在react.js中相当于ng-if是什么?


81

我开始对使用angular做出反应,并且试图找出我可以根据条件渲染或不渲染元素的Ang- ng-if指令的替代方法。以下面的代码为例。我正在使用打字稿(tsx)btw,但这没什么大不了的。

"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;

该解决方案有效,但是通常还有另一种方法可以达到这种效果吗?我只是在猜测



1
您使用的方法是正确的反应方法。使用三元运算符会将您的代码减少到一行,但逻辑仍然相同。''当您不希望呈现元素时,可以使用null或空白字符串(仅包含引号)。
Kishore Barik '16

最新的官方文档发布了一些简洁的方法来实现此目的。facebook.github.io/react/docs/...
Downhillski

Answers:


88

如何三元运算符

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

您也可以使用&&

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

通过将JSX包装在()s中,可以轻松地处理注释中的大块:

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

还内联:

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

6
以及如何用于较大的代码块?只是内联?
Asqan

18
我也认为这还可以,但是它仍然让我想起了丑陋的PHP和HTML混合
不限

88
我想念Angular :(
Uday Hiwarale '17

2
对我来说,它比无尽的黑客程序要干净得多,并且最好何时使用它。而且我喜欢能够亲自留在javascript-ish空间中。
萨曼莎·阿特金斯

1
@PatrickCyiza您能详细说明您的问题吗?听起来像是比较浅的问题。
Yuya

25

我出于历史目的将其保留在此处,请在反应开发了一段时间 后创建一个NgIf组件(这是本机反应,但可能对反应有效)后,请在下面查看我的修改,以寻求更好的解决方案

码:

import React, {Component} from "react";

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

export default NgIf;

用法:

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

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

我对此并不陌生,因此可能会有所改进,但可以帮助我从Angular过渡

编辑

一旦我有更多的经验,请参阅下面的编辑以获得更好的解释

感谢下面的Jay评论,一个好主意也是:

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

要么

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

与其他一些答案类似,但是它们是内联的,而不是使用整个渲染块/函数,不需要特殊的组件,并且您可以将else语句与三元运算符一起使用。如果父项不存在,则if语句中包含的项不会引发错误。即,如果props.value不存在,则props.value.value2不会引发错误。

看到这个答案https://stackoverflow.com/a/26152067

编辑2:

根据上面的链接(https://stackoverflow.com/a/26152067),经过大量的开发React应用程序的经验,上述方法并不是最好的方法。

实际上,有条件运算符的反应很容易使您着迷。有两种处理方法:

//Show if someItem
{someItem && displayThis}

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

您可能要注意的一个警告是,如果“ someItem”不是布尔表达式。如果说0,则react将打印0或react native将给您有关需要在文本元素中包装“ 0”的错误。对于虚假测试,这通常不是问题,但对于真实测试,将提出问题。例如:

{!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

我经常使用的把戏?双重底片。

{!!someItem && displayThis}

注意,这不适用于三元运算符(myVar?true:false),因为它会将结果隐式转换为布尔表达式。


1
我最喜欢这个。使用组件和属性描述视图逻辑。
杰伊·威克

更新:查看了这些答案后,看来这是不理想的。
杰伊·威克

1
我同意,对自己来说这是新手,这似乎是一个不错的选择。我发现的方法的一个缺点是,如果NgIf对象中包含的项引用了不存在的内容,它将仍然会出错。谢谢指点出来
瑞恩丧钟

1
我非常感谢您能及时更新。它提供了上下文,谢谢!
asiegf

感谢您的编辑2。我的首选解决方案
TrueKojo

21

如果您还有其他元素,则可以像这样包装条件:

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

1
不像其他建议那么干净,但是非常适合一个班轮!
乔尔·戴维

11

更好一点:

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

嗨,我正在尝试执行此操作,但是我在一个组件中有多个元素,并且它无法正常工作
user3653796

10

我只是想补充一点,*ngIf在angular中不会实例化它所连接的组件。在React中,如果您在语句中使用if语句,return则即使未显示该组件,它仍将实例化该组件。为了*ngIf在React中实现真正的类型行为,您必须创建一个变量,该变量将条件组件保存在return语句之外:

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
}

谢谢,这对我有所帮助!
斯蒂芬

4

我可以想到至少三种不同的方法来在React中模拟ng-if功能

  • 如果
  • 开关
  • IIFE(立即调用的函数表达式)

您可以在此处阅读该帖子:React组件中Angular的ng-if等效项

基本上,您想执行以下操作:

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;
  }
});

谢谢,这让我完全畅通无阻,节省了一天!非常感谢!
斯蒂芬

4

falsenullundefined,和true有效的儿童。他们只是不渲染。这些JSX表达式将全部呈现为同一事物:

所以你可以试试看

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

这对于有条件地渲染React元素很有用。此JSX仅呈现if条件为true,并且仅在someArray.length> 0时呈现


4

我不喜欢代码中有很多三元运算符。这就是为什么我制作了一个包含几个有用组件的库的原因。“ 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>

您可以从npm安装它

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


3

我是Tersus-jsx.macro的创建者,我认为此模块提供了此问题的确切条件。

除了将JSX表达式和ES6混合以实现ng-if或ng-repeat之外,此宏还允许执行与AngularJS for React JSX中相同的方式,例如用于ng-if:

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

相当于

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

鉴于开箱即用的最新版本的create-react-app支持Babel-Macro,您需要做的就是npm安装此模块,用“ tersus”包装渲染返回并开始分配这些道具。

您可以从以下网址进行安装:https//www.npmjs.com/package/tersus-jsx.macro


大包装!
secavfr

2

我也来自有角度的背景,并且正在寻找一种简单的衬纸来显示变量是否包含任何元素的标签。这为我工作:

<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

我只是创建了一个将expresting和另外两个参数作为模板的方法,以防表达式true和另一个是一个选项else模板

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

我这样用

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

我个人喜欢使用吸气剂,它很干净,可以确保反应性:

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

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

0

我正在努力工作并做出反应。我认为angular可以通过不同的指令很好地管理逻辑条件。

reactjs这种方法的工作方式不同。

您可以使用if else条件作为returnrender functionternary operator

如果还有

  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;
    }

与三元运算符

{ 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 } 
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.