237

我如何选择在 JSX 中包含一个元素?这是一个使用横幅的示例,如果它已被传入,则该横幅应在组件中。我要避免的是必须在 if 语句中复制 HTML 标记。

render: function () {
    var banner;
    if (this.state.banner) {
        banner = <div id="banner">{this.state.banner}</div>;
    } else {
        banner = ?????
    }
    return (
        <div id="page">
            {banner}
            <div id="other-content">
                blah blah blah...
            </div>
        </div>
    );
}
4

28 回答 28

151

只需将横幅保留为未定义,它就不会被包含在内。

于 2014-03-20T16:21:47.693 回答
133

那这个呢。让我们定义一个简单的帮助If组件。

var If = React.createClass({
    render: function() {
        if (this.props.test) {
            return this.props.children;
        }
        else {
            return false;
        }
    }
});

并以这种方式使用它:

render: function () {
    return (
        <div id="page">
            <If test={this.state.banner}>
                <div id="banner">{this.state.banner}</div>
            </If>
            <div id="other-content">
                blah blah blah...
            </div>
        </div>
    );
}

更新:随着我的回答越来越受欢迎,我有义务警告您与此解决方案相关的最大危险。正如另一个答案中所指出的,<If />无论条件是真还是假,组件内的代码都会始终执行。因此,如果是,以下示例将失败(请注意第二行的属性访问):bannernull

<If test={this.state.banner}>
    <div id="banner">{this.state.banner.url}</div>
</If>

使用时必须小心。我建议阅读其他答案以了解替代(更安全)的方法。

更新 2:回过头来看,这种方法不仅危险,而且非常麻烦。这是一个典型的例子,当开发人员(我)试图将他知道的模式和方法从一个领域转移到另一个领域,但它并没有真正起作用(在这种情况下是其他模板语言)。

如果您需要条件元素,请这样做:

render: function () {
    return (
        <div id="page">
            {this.state.banner &&
                <div id="banner">{this.state.banner}</div>}
            <div id="other-content">
                blah blah blah...
            </div>
        </div>
    );
}

如果您还需要 else 分支,只需使用三元运算符:

{this.state.banner ?
   <div id="banner">{this.state.banner}</div> :
   <div>There is no banner!</div>
}

它更短、更优雅、更安全。我用它所有的时间。唯一的缺点是你不能那么else if容易地进行分支,但这通常并不常见。

无论如何,这要归功于JavaScript 中逻辑运算符的工作方式。逻辑运算符甚至允许像这样的小技巧:

<h3>{this.state.banner.title || 'Default banner title'}</h3>
于 2014-10-01T23:03:09.753 回答
82

就个人而言,我真的认为(JSX In Depth)中展示的三元表达式是符合 ReactJs 标准的最自然的方式。

请参阅以下示例。乍一看有点乱,但效果很好。

<div id="page">
  {this.state.banner ? (
    <div id="banner">
     <div class="another-div">
       {this.state.banner}
     </div>
    </div>
  ) : 
  null} 
  <div id="other-content">
    blah blah blah...
  </div>
</div>
于 2015-04-15T14:13:51.817 回答
47

你也可以这样写

{ this.state.banner && <div>{...}</div> }

如果您的state.bannerisnullundefined,则跳过条件的右侧。

于 2016-02-22T14:57:01.810 回答
41

样式组件是危险的,因为无论条件如何,If代码块总是被执行。例如,如果banneris ,这将导致 null 异常null

//dangerous
render: function () {
  return (
    <div id="page">
      <If test={this.state.banner}>
        <img src={this.state.banner.src} />
      </If>
      <div id="other-content">
         blah blah blah...
      </div>
    </div>
  );
}

另一种选择是使用内联函数(对 else 语句特别有用):

render: function () {
  return (
    <div id="page">
      {function(){
        if (this.state.banner) {
          return <div id="banner">{this.state.banner}</div>
        }
      }.call(this)}
      <div id="other-content">
         blah blah blah...
      </div>
    </div>
  );
}

反应问题的另一个选择:

render: function () {
  return (
    <div id="page">
      { this.state.banner &&
        <div id="banner">{this.state.banner}</div>
      }
      <div id="other-content">
         blah blah blah...
      </div>
    </div>
  );
}
于 2015-02-24T22:16:01.323 回答
23

很简单,创建一个函数。

renderBanner: function() {
  if (!this.state.banner) return;
  return (
    <div id="banner">{this.state.banner}</div>
  );
},

render: function () {
  return (
    <div id="page">
      {this.renderBanner()}
      <div id="other-content">
        blah blah blah...
      </div>
    </div>
  );
}

这是我个人一直遵循的模式。使代码真正干净且易于理解。Banner更重要的是,如果它变得太大(或在其他地方重用),它允许您重构为自己的组件。

于 2016-07-06T19:03:41.703 回答
22

&& + 代码风格 + 小组件

这种简单的测试语法 + 代码风格的约定 + 专注的小组件对我来说是最易读的选项。您只需要特别注意虚假值,例如false,0""

render: function() {
    var person= ...; 
    var counter= ...; 
    return (
       <div className="component">
          {person && (
            <Person person={person}/>
          )}
          {(typeof counter !== 'undefined') && (
            <Counter value={counter}/>
          )}
       </div>
    );
}

做符号

ES7 stage-0 do notation 语法也非常好,当我的 IDE 正确支持它时,我肯定会使用它:

const Users = ({users}) => (
  <div>
    {users.map(user =>
      <User key={user.id} user={user}/>
    )}
  </div>
)  

const UserList = ({users}) => do {
  if (!users) <div>Loading</div>
  else if (!users.length) <div>Empty</div>
  else <Users users={users}/>
}

更多细节在这里:ReactJs - 创建一个“If”组件......一个好主意?

于 2015-05-07T07:44:01.763 回答
13

实验性的 ES7do语法使这很容易。如果您使用 Babel,请启用该es7.doExpressions功能:

render() {
  return (
    <div id="banner">
      {do {
        if (this.state.banner) {
          this.state.banner;
        } else {
          "Something else";
        }
      }}
    </div>
  );
}

http://wiki.ecmascript.org/doku.php?id=strawman:do_expressions

于 2015-07-11T02:51:52.827 回答
11

正如答案中已经提到的,JSX 为您提供了两个选项

  • 三元运算符

    { this.state.price ? <div>{this.state.price}</div> : null }

  • 逻辑合取

    { this.state.price && <div>{this.state.price}</div> }


但是,那些不适用于 price == 0.

JSX 将在第一种情况下呈现假分支,如果是逻辑连接,则不会呈现任何内容。如果属性可能为 0,只需在 JSX 之外使用 if 语句。

于 2016-09-12T15:08:45.753 回答
9

当您在“if”分支中有多个元素时,此组件将起作用:

var Display = React.createClass({
  render: function () {
    if (!this.props.when) {
      return false;
    }
    return React.DOM.div(null, this.props.children);
  },
});

用法:

render: function() {
  return (
    <div>
      <Display when={this.state.loading}>
        Loading something...
        <div>Elem1</div>
        <div>Elem2</div>
      </Display>
      <Display when={!this.state.loading}>
        Loaded
        <div>Elem3</div>
        <div>Elem4</div>
      </Display>
    </div>
  );
}

ps有人认为这些组件不利于代码阅读。但在我看来,带有 javascript 的 Html 更糟糕

于 2015-01-16T14:29:59.247 回答
3

大多数示例都是有条件呈现的一行“html”。当我有多行需要有条件地呈现时,这对我来说似乎是可读的。

render: function() {
  // This will be renered only if showContent prop is true
  var content = 
    <div>
      <p>something here</p>
      <p>more here</p>
      <p>and more here</p>
    </div>;

  return (
    <div>
      <h1>Some title</h1>

      {this.props.showContent ? content : null}
    </div>
  );
}

第一个例子很好,因为null我们可以有条件地渲染一些其他内容,比如{this.props.showContent ? content : otherContent}

但是,如果您只需要显示/隐藏内容,这会更好,因为忽略了布尔值、空值和未定义值

render: function() {
  return (
    <div>
      <h1>Some title</h1>

      // This will be renered only if showContent prop is true
      {this.props.showContent &&
        <div>
          <p>something here</p>
          <p>more here</p>
          <p>and more here</p>
        </div>
      }
    </div>
  );
}
于 2016-03-11T14:52:16.207 回答
2

我使用更明确的快捷方式:立即调用函数表达式 (IIFE):

{(() => {
  if (isEmpty(routine.queries)) {
    return <Grid devices={devices} routine={routine} configure={() => this.setState({configured: true})}/>
  } else if (this.state.configured) {
    return <DeviceList devices={devices} routine={routine} configure={() => this.setState({configured: false})}/>
  } else {
    return <Grid devices={devices} routine={routine} configure={() => this.setState({configured: true})}/>
  }
})()}
于 2016-12-12T16:54:43.167 回答
2

还有另一种解决方案,如果 React 的组件

var Node = require('react-if-comp');
...
render: function() {
    return (
        <div id="page">
            <Node if={this.state.banner}
                  then={<div id="banner">{this.state.banner}</div>} />
            <div id="other-content">
                blah blah blah...
            </div>
        </div>
    );
}
于 2016-01-08T23:09:20.440 回答
2

也许它可以帮助遇到这个问题的人: React 中的所有条件渲染这是一篇关于 React 中条件渲染的所有不同选项的文章。

何时使用条件渲染的关键要点:

** 如果别的

  • 是最基本的条件渲染
  • 初学者友好
  • 使用 if 通过返回 null 来提前退出渲染方法

** 三元运算符

  • 在 if-else 语句上使用它
  • 比 if-else 更简洁

** 逻辑 && 运算符

  • 当三元运算的一侧返回 null 时使用它

** 开关盒

  • 冗长的
  • 只能内联自调用函数
  • 避免它,改用枚举

** 枚举

  • 完美映射不同的状态
  • 完美映射多个条件

** 多级/嵌套条件渲染

  • 为了可读性而避免使用它们
  • 使用自己的简单条件渲染将组件拆分为更轻量级的组件
  • 使用 HOC

** HOC

  • 使用它们来屏蔽条件渲染
  • 组件可以专注于它们的主要用途

** 外部模板组件

  • 避免它们并熟悉 JSX 和 JavaScript
于 2017-02-21T21:48:49.860 回答
1

我制作了https://www.npmjs.com/package/jsx-control-statements以使其更容易一些,基本上它允许您将<If>条件定义为标签,然后将它们编译成三元 if 以便里面的代码<If>唯一得到如果条件为真则执行。

于 2015-02-26T23:04:53.327 回答
1

我最近制作了https://github.com/ajwhite/render-if以仅在谓词通过时安全地渲染元素。

{renderIf(1 + 1 === 2)(
  <span>Hello!</span>
)}

或者

const ifUniverseIsWorking = renderIf(1 + 1 === 2);

//...

{ifUniverseIsWorking(
  <span>Hello!</span>
)}
于 2016-02-05T05:00:28.740 回答
1

您可以使用函数并返回组件并保持渲染函数的精简

class App extends React.Component {
  constructor (props) {
    super(props);
    this._renderAppBar = this._renderAppBar.bind(this);
  }

  render () {
    return <div>
      {_renderAppBar()}

      <div>Content</div>

    </div>
  }

  _renderAppBar () {
    if (this.state.renderAppBar) {
      return <AppBar />
    }
  }
}
于 2016-06-11T19:42:17.053 回答
1

使用 ES6,你可以用一个简单的单行来做到这一点

const If = ({children, show}) => show ? children : null

"show" 是一个布尔值,你使用这个类

<If show={true}> Will show </If>
<If show={false}> WON'T show </div> </If>
于 2018-01-20T00:36:18.793 回答
1

这是我使用 ES6 的方法。

import React, { Component } from 'react';
// you should use ReactDOM.render instad of React.renderComponent
import ReactDOM from 'react-dom';

class ToggleBox extends Component {
  constructor(props) {
    super(props);
    this.state = {
      // toggle box is closed initially
      opened: false,
    };
    // http://egorsmirnov.me/2015/08/16/react-and-es6-part3.html
    this.toggleBox = this.toggleBox.bind(this);
  }

  toggleBox() {
    // check if box is currently opened
    const { opened } = this.state;
    this.setState({
      // toggle value of `opened`
      opened: !opened,
    });
  }

  render() {
    const { title, children } = this.props;
    const { opened } = this.state;
    return (
      <div className="box">
        <div className="boxTitle" onClick={this.toggleBox}>
          {title}
        </div>
        {opened && children && (
          <div class="boxContent">
            {children}
          </div>
        )}
      </div>
    );
  }
}

ReactDOM.render((
  <ToggleBox title="Click me">
    <div>Some content</div>
  </ToggleBox>
), document.getElementById('app'));

演示:http: //jsfiddle.net/kb3gN/16688/

我正在使用如下代码:

{opened && <SomeElement />}

SomeElement仅当opened为真时才会呈现。它之所以起作用,是因为 JavaScript 解析逻辑条件的方式:

true && true && 2; // will output 2
true && false && 2; // will output false
true && 'some string'; // will output 'some string'
opened && <SomeElement />; // will output SomeElement if `opened` is true, will output false otherwise

正如React将忽略的那样false,我发现有条件地渲染某些元素是非常好的方法。

于 2017-02-13T14:17:41.150 回答
1

还有一个非常干净的一行版本... { this.props.product.title || “无题” }

IE:

render: function() {
            return (
                <div className="title">
                    { this.props.product.title || "No Title" }
                </div>
            );
        }
于 2015-11-09T22:26:14.737 回答
1

您可以使用三元运算符有条件地包含元素,如下所示:

render: function(){

         return <div id="page">

                  //conditional statement
                  {this.state.banner ? <div id="banner">{this.state.banner}</div> : null}

                  <div id="other-content">
                      blah blah blah...
                  </div>

               </div>
}
于 2016-03-12T13:14:08.187 回答
0

当必须仅在满足传递的条件时才渲染某些内容时,您可以使用语法:

{ condition && what_to_render }

这种方式的代码如下所示:

render() {
    const { banner } = this.state;
    return (
        <div id="page">
            { banner && <div id="banner">{banner}</div> }
            <div id="other-content">
                blah blah blah...
            </div>
        </div>
    );
}

当然,还有其他有效的方法可以做到这一点,这完全取决于偏好和场合。如果您有兴趣,可以在本文中了解更多关于如何在 React 中进行条件渲染的方法!

于 2018-02-22T10:38:22.797 回答
0

我喜欢立即调用函数表达式 ( IIFE) 和if-elseover render callbacksand的明确性ternary operators

render() {
  return (
    <div id="page">
      {(() => (
        const { banner } = this.state;
        if (banner) {
          return (
            <div id="banner">{banner}</div>
          );
        }
        // Default
        return (
          <div>???</div>
        );
      ))()}
      <div id="other-content">
        blah blah blah...
      </div>
    </div>
  );
}

您只需要熟悉IIFE语法,{expression}是通常的 React 语法,在其中只需考虑您正在编写一个调用自身的函数。

function() {

}()

需要包裹在括号内

(function() {

}())
于 2016-12-19T09:32:08.697 回答
0

我不认为这已经被提及。这就像您自己的答案,但我认为它更简单。您始终可以从表达式返回字符串,并且可以将 jsx 嵌套在表达式中,因此这允许易于阅读的内联表达式。

render: function () {
    return (
        <div id="page">
            {this.state.banner ? <div id="banner">{this.state.banner}</div> : ''}
            <div id="other-content">
                blah blah blah...
            </div>
        </div>
    );
}

<script src="http://dragon.ak.fbcdn.net/hphotos-ak-xpf1/t39.3284-6/10574688_1565081647062540_1607884640_n.js"></script>
<script src="http://dragon.ak.fbcdn.net/hphotos-ak-xpa1/t39.3284-6/10541015_309770302547476_509859315_n.js"></script>
<script type="text/jsx;harmony=true">void function() { "use strict";

var Hello = React.createClass({
  render: function() {
    return (
      <div id="page">
        {this.props.banner ? <div id="banner">{this.props.banner}</div> : ''}
        <div id="other-content">
          blah blah blah...
        </div>
      </div>
    );   
  }
});

var element = <div><Hello /><Hello banner="banner"/></div>;
React.render(element, document.body);

}()</script>

于 2016-04-28T12:51:51.330 回答
0

我只是在 React with TypeScript 中使用以下代码段

export default function ReactIf(props: {condition: boolean, children: React.ReactNode }) {
    return props.condition ? <React.Fragment>{props.children}</React.Fragment> : <React.Fragment/>;
}

于 2021-06-14T16:54:50.023 回答
0

还有一种技术使用渲染道具来条件渲染组件。这样做的好处是在满足条件之前渲染不会进行评估,从而无需担心nullundefined值。

const Conditional = ({ condition, render }) => {
  if (condition) {
    return render();
  }
  return null;
};

class App extends React.Component {
  constructor() {
    super();
    this.state = { items: null }
  }

  componentWillMount() {
    setTimeout(() => { this.setState({ items: [1,2] }) }, 2000);
  }

  render() {
    return (
      <Conditional
        condition={!!this.state.items}
        render={() => (
          <div>
            {this.state.items.map(value => <p>{value}</p>)}
          </div>
        )}
      />
    )
  }
}
于 2017-12-04T21:21:31.547 回答
-1

只是添加另一个选项 - 如果你喜欢/容忍咖啡脚本,你可以使用咖啡反应来编写你的 JSX,在这种情况下 if/else 语句是可用的,因为它们是咖啡脚本中的表达式而不是语句:

render: ->
  <div className="container">
    {
      if something
        <h2>Coffeescript is magic!</h2>
      else
        <h2>Coffeescript sucks!</h2>
    }
  </div>  
于 2015-03-27T01:55:53.810 回答
-1

只是通过对文档的引用来扩展@Jack Allan 的答案。

null在这种情况下,建议使用 React 基本(快速入门)文档。但是,布尔值、空值和未定义也被忽略,在高级指南中提到。

于 2017-05-08T15:11:53.330 回答