Tương đương với ng-if trong react.js là gì?


81

Tôi sắp phản ứng từ việc sử dụng angle và tôi đang cố gắng tìm ra một giải pháp thay thế phản ứng tốt cho chỉ thị ng-if của angle trong đó tôi kết xuất hoặc không kết xuất một phần tử dựa trên một điều kiện. Lấy mã này làm ví dụ. Tôi đang sử dụng typecript (tsx) btw nhưng điều đó không quan trọng lắm.

"use strict";

import * as React from 'react';

interface MyProps {showMe: Boolean}
interface MyState {}

class Button extends React.Component <MyProps, MyState>{
  constructor(props){
    super(props);
    this.state = {};
  }

  render(){
    let button;
    if (this.props.showMe === true){
       button = (
        <button type="submit" className="btn nav-btn-red">SIGN UP</button>
      )
    } else {
      button = null;
    }
    return button;

}
}
export default Button;

Giải pháp này hoạt động, nhưng có cách nào khác thường được sử dụng để đạt được hiệu quả này không? Tôi chỉ đoán mò thôi



1
Phương pháp bạn đã sử dụng là phương pháp chính xác trong phản ứng. Sử dụng toán tử bậc ba sẽ giảm mã của bạn xuống một dòng nhưng logic sẽ vẫn như cũ. Bạn có thể sử dụng chuỗi rỗng hoặc chuỗi trống (chỉ dấu ngoặc kép) ''khi bạn không muốn các phần tử được hiển thị.
Kishore Barik

Tài liệu chính thức gần đây nhất đã đăng một số cách đơn giản để thực hiện việc này. facebook.github.io/react/docs/…
Downhillski

Câu trả lời:


88

Làm thế nào về toán tử bậc ba ?

render() {
  return (
    this.props.showMe ? <button type="submit" className="btn nav-btn-red">SIGN UP</button> : null
  );
}

Bạn cũng có thể sử dụng &&:

render() {
  return (
    this.props.showMe && <button type="submit" className="btn nav-btn-red">SIGN UP</button>
  );
}

Khối lớn như trong nhận xét có thể dễ dàng được xử lý bằng cách gói JSX trong ()s:

render() {
  return this.props.showMe && (
    <div className="container">
      <button type="submit" className="btn nav-btn-red">
        SIGN UP
      </button>
    </div>
  );
}

Cũng nội tuyến:

render() {
  return (
    <div className="container">
      {this.props.showMe && <button type="submit" className="btn nav-btn-red">SIGN UP</button>}
    </div>
  );
}

6
và làm thế nào để sử dụng cho các khối mã lớn hơn? chỉ nội tuyến?
Asqan

18
Tôi cũng nghĩ rằng nó khá ổn nhưng nó vẫn khiến tôi nhớ đến hỗn hợp PHP & HTML xấu xí
không giới

88
Tôi nhớ Angular :(
Uday Hiwarale

2
Đối với tôi, nó sạch hơn rất nhiều so với vô số bản hack và khi nào thì tốt nhất nên sử dụng. Và tôi thích phần lớn được ở trong không gian javascript-ish cá nhân.
Samantha Atkins

1
@PatrickCyiza Bạn có thể giải thích thêm về vấn đề của mình không? Nghe giống như vấn đề so sánh nông cạn.
Yuya

25

Tôi để điều này ở đây cho mục đích lịch sử, vui lòng xem các chỉnh sửa của tôi bên dưới để có giải pháp tốt hơn nhiều sau khi đã phát triển trong phản ứng một thời gian, tôi đã tạo thành phần NgIf (đây là thành phần phản ứng gốc nhưng có thể hoạt động cho phản ứng)

Mã:

import React, {Component} from "react";

class NgIf extends Component {
  render() {
    if (this.props.show) {
      return (
        this.props.children
      );
    } else {
      return null
    }
  }
}

export default NgIf;

Sử dụng:

...
import NgIf from "./path/to/component"
...

class MyClass {
   render(){
      <NgIf show={this.props.show}><Text>This Gets Displayed</Text></NgIf>
   }
}

Tôi mới làm quen với điều này nên có thể sẽ được cải thiện, nhưng giúp tôi trong quá trình chuyển đổi từ Angular

BIÊN TẬP

Xem các chỉnh sửa bên dưới để được giải thích rõ hơn sau khi tôi có thêm kinh nghiệm

Cảm ơn Bình luận của Jay bên dưới, một ý tưởng tuyệt vời cũng là:

render() {
   <View>{this.props.value ? <Text>Yes</Text> : <Text>No</Text>}</View>
}

HOẶC LÀ

render() {
   <View>{this.props.value && <Text>Yes</Text>}</View>
}

Tương tự như một số câu trả lời khác nhưng hoạt động nội tuyến, thay vì sử dụng toàn bộ khối / chức năng kết xuất, không yêu cầu một thành phần đặc biệt và bạn có thể sử dụng một câu lệnh khác với toán tử bậc ba. Các mục cộng có trong câu lệnh if không gây ra lỗi nếu đối tượng mẹ của chúng không tồn tại. Tức là nếu nếu props.valuekhông tồn tại, thì props.value.value2sẽ không tạo ra lỗi.

Xem câu trả lời này https://stackoverflow.com/a/26152067

CHỈNH SỬA 2:

Theo liên kết ở trên ( https://stackoverflow.com/a/26152067 ) và sau khi có thêm nhiều kinh nghiệm phát triển ứng dụng phản ứng, cách trên không phải là cách tốt nhất để thực hiện mọi việc.

Các toán tử điều kiện trong phản ứng thực sự rất dễ khiến bạn phải lo lắng. Có hai cách để thực hiện:

//Show if someItem
{someItem && displayThis}

//Show if else
{someItem ? displayThisIfTrue : displayThisIfFalse}

Một cảnh báo bạn có thể gặp phải là nếu "someItem" không phải là một biểu thức boolean. Nếu nói 0 thì phản ứng sẽ in ra 0 hoặc phản ứng gốc sẽ cho bạn lỗi về việc cần phải bọc "0" trong phần tử văn bản. Đây thường không phải là vấn đề đối với các bài kiểm tra giả mạo, nhưng sẽ là vấn đề đối với các bài kiểm tra trung thực. Ví dụ:

{!someItem && displayThis} //Will work just fine if item is 0 or null or "" etc
{someItem && displayThis} //Will print the value of someItem if its not falsy

Thủ thuật thường sử dụng của tôi? phủ định kép.

{!!someItem && displayThis}

Lưu ý rằng điều này không áp dụng cho các toán tử bậc ba (myVar? True: false) vì nó chuyển đổi ngầm kết quả thành một biểu thức boolean.


1
Tôi thích điều này nhất. Sử dụng các thành phần và thuộc tính để mô tả logic chế độ xem.
Jay Wick

Cập nhật: sau khi xem xét những câu trả lời này , có vẻ như đây là một thử thách.
Jay Wick

1
Bản thân tôi mới làm quen với điều này, tôi đồng ý, đó có vẻ là một cách tốt để đi. Một nhược điểm với phương pháp của tôi mà tôi đã phát hiện ra là nó sẽ vẫn gặp lỗi nếu một mục chứa trong đối tượng NgIf tham chiếu đến một thứ không tồn tại. Cảm ơn vì đã chỉ nó ra
Ryan Knell

1
Tôi thực sự đánh giá cao rằng bạn đã cập nhật nó với thời gian. Nó cung cấp ngữ cảnh, cảm ơn bạn!
asiegf

Cảm ơn bạn đã EDIT 2. Giải pháp ưa thích của tôi
TrueKojo

21

Nếu bạn cũng có các phần tử khác, bạn có thể chỉ bọc điều kiện như sau:

render() {
  return (
    <div>Stuff</div>
    {this.props.showMe && (
      <button type="submit" className="btn nav-btn-red">SIGN UP</button>
    )}
    <div>More stuff</div>
  );
}

1
Không sạch như một số gợi ý khác, nhưng tuyệt vời cho một lớp lót!
Joel Davey

11

Đẹp hơn một chút:

render() {
  return (
    this.props.showMe && <button type="submit" className="btn nav-btn-red">SIGN UP</button>
  );
}

hi tôi đang cố gắng để làm điều này nhưng tôi có một số yếu tố trong một thành phần và nó không làm việc
user3653796

10

Tôi chỉ muốn thêm rằng *ngIftrong góc không khởi tạo thành phần mà nó được gắn vào. Trong React nếu bạn sử dụng câu lệnh if bên trong returncâu lệnh thì nó sẽ vẫn khởi tạo thành phần mặc dù nó không được hiển thị. Để đạt được *ngIfhành vi kiểu true trong React, bạn phải tạo một biến chứa thành phần điều kiện bên ngoài returncâu lệnh:

render() {

  const show = false

  return show
     ? <AwesomeComponent />   //still instantiated
     : null
}

render() {

  let c = null
  const show = false

  if (show) {
    c = <AwesomeComponent />   //not instantiated
  }
  return c
}

Cảm ơn điều này đã giúp tôi!
Stephen

4

Tôi có thể nghĩ ra ít nhất ba cách khác nhau để mô phỏng chức năng ng-if trong React

  • nếu
  • công tắc điện
  • IIFE (biểu thức hàm được gọi ngay lập tức)

Bạn có thể đọc bài đăng ở đây: Angular's ng-if Tương đương trong một thành phần React

Về cơ bản, bạn muốn làm điều gì đó như sau:

var IfDemoComponent = React.createClass({
  render: function() {
    var el = null;
    if (this.props.showMe) {
      el = (
        <div>
          I am only included in the DOM if this.props.showMe evaluates to true.
        </div>
      );
    }
   return el;
  }
});

Cảm ơn điều này hoàn toàn bỏ chặn tôi, đã lưu trong ngày! Cảm ơn bạn rất nhiều!
Stephen

4

false, null, undefined, Và truelà con cái hợp lệ. Chúng chỉ đơn giản là không kết xuất. Tất cả các biểu thức JSX này sẽ hiển thị cùng một thứ:

Vì vậy, bạn có thể thử điều này

const conditional=({condition,someArray})=>{
     return(
        <div>
          {condition && <Header /> // condition being boolean} 
          {someArray.length>0 && <Content />}
        </div>
      )
}

điều này có thể hữu ích để hiển thị có điều kiện các phần tử React. JSX này chỉ hiển thị điều kiện if là đúng và sẽ chỉ hiển thị nếu someArray.length> 0


4

Tôi không thích có nhiều toán tử bậc ba trong mã. Đó là lý do tại sao tôi tạo một thư viện với một vài thành phần hữu ích. "RcIf"

  <RcIf if={condition} >
    <h1>I no longer miss ngif</h1>
  </RcIf>
  <RcIf if={othercondition} >
    <h1>I no longer miss v-if</h1>
    <RcElse>
      <h1>I love react</h1>
    </RcElse>
  </RcIf>

Bạn có thể cài đặt nó từ npm

https://www.npmjs.com/package/rc-if


3

Tôi là người tạo ra Tersus-jsx.macro và tôi nghĩ rằng mô-đun này cung cấp chính xác những gì cần thiết cho câu hỏi này.

Thay vì trộn các biểu thức JSX và ES6 để đạt được ng-if hoặc ng-repeat, macro này cho phép thực hiện mọi thứ giống như trong AngularJS dành cho React JSX, ví dụ như đối với ng-if:

<div>
  <button
    tj-if={a === 0}
    id="gotoA"
    className="link"
    onClick={clicking}
  />
</div>

tương đương với

<div>
  {(a === 0) && (
    <button
      id="gotoA"
      className="link"
      onClick={clicking}
    />
  )}
</div>

Do phiên bản mới nhất của tạo-phản ứng-ứng dụng hỗ trợ Babel-Macro, tất cả những gì bạn cần làm là npm cài đặt mô-đun này, bao bọc trả về kết xuất bằng "tersus" và bắt đầu gán các đạo cụ đó.

Bạn có thể cài đặt cái này từ: https://www.npmjs.com/package/tersus-jsx.macro


Gói tuyệt vời!
secavfr

2

Tôi cũng đến từ một nền góc cạnh và đang tìm kiếm một lớp lót đơn giản để hiển thị thẻ nếu biến có bất kỳ phần tử nào. Điều này đã làm việc cho tôi:

<div className="comic_creators">
    {c.creators.available > 0 ? <h4>Creators</h4> : null }
    {c.creators.items.map((creator,key) =>
        <Creator creator={creator} key={key}></Creator>
    )}
</div>

0

Tôi chỉ tạo một phương thức để lấy exprestion và hai đối số khác làm mẫu trong trường hợp biểu thức true và đối số kia là một tùy chọn khác mẫu

export function rif(exp, template, elseTemplate = null) {
    if (exp) {
        return template;
    } else {
        return elseTemplate;
    }
}

và tôi sử dụng nó như thế này

import { rif } from '../utilities';

...
render() {
        return (
            <main role="main" className="container">

                {rif(
                    this.movies.length > 0,
                    <p>Showing {this.movies.length} movies. </p>,
                    <p>There are no movies..</p>
                )}
            </main>
        );
    }

0

Cá nhân tôi thích sử dụng getters, nó rõ ràng và đảm bảo khả năng phản ứng:

get toBeDisplayed(){
  const { someLogicState } = this.state;
  if(someLogicState)
    return (
      <div>
        Hi, world !
      </div>
    );
  else
    return null;
}

render(){
  return (<div>{this.toBeDisplayed}</div>);
}

0

Tôi đang làm việc cả góc cạnh và phản ứng. Tôi nghĩ angularquản lý điều kiện hợp lý độc đáo thông qua các chỉ thị khác nhau.

Trong reactjscách tiếp cận này hoạt động theo cách khác.

Bạn có thể sử dụng if elseđiều kiện như returncủa render functionhay ternary operator.

Với nếu khác

  render(){
    
    const auth = true;
    
    if(!auth)
      return(
      <div className="ps-checkout__login">
        <div className="d-flex flex-row">
            <div className="p-2"><img src="../../../static/img/return-customer.png"></img> 
             Returning Customer?</div>
            <div className="p-2"> 
                <Link href="/account/login">
                    <a>                            
                        Click here to login
                    </a>
                </Link>
            </div>
        </div>
    </div>
    )
  else return null;
    }

Với toán tử bậc ba

{ auth?
    (<div className="ps-checkout__login">
        <div className="d-flex flex-row">
            <div className="p-2"><img src="../../../static/img/return-customer.png"></img> 
            Returning Customer?</div>
            <div className="p-2"> 
                <Link href="/account/login">
                    <a>                            
                        Click here to login
                    </a>
                </Link>
            </div>
        </div>
    </div>):null } 
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.