我如何选择在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>
    );
}

当前回答

我使用一个更显式的快捷方式:立即调用函数表达式(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})}/>
  }
})()}

其他回答

当你在"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>
  );
}

附注:有些人认为这些组件不适合代码阅读。但在我看来,Html和javascript更糟糕

我想这一点没有被提及。这就像你自己的答案,但我认为它更简单。您总是可以从表达式中返回字符串,并且可以在表达式中嵌套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>

这个呢?让我们定义一个简单的帮助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 />组件中的代码总是被执行。因此,如果横幅为空,下面的例子将失败(注意第二行上的属性访问):

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

它更短,更优雅,更安全。我一直在用它。唯一的缺点是,如果分支那么容易,你就不能做其他事情,但这通常不常见。

无论如何,这是可能的,这要感谢JavaScript中的逻辑运算符的工作方式。逻辑运算符甚至允许这样的小技巧:

<h3>{this.state.banner.title || 'Default banner title'}</h3>

在ES6中,你可以用简单的一行程序来实现

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

"show"是一个布尔值,你可以通过

<If show={true}> Will show </If>
<If show={false}> WON'T show </div> </If>

下面是我使用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 />}

仅当opened为true时才会呈现SomeElement。它的工作原理在于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,我发现它是有条件渲染某些元素的好方法。