Javascript 如何使用Facebook React'拥有条件元素并保持干燥;是JSX吗?

Javascript 如何使用Facebook React'拥有条件元素并保持干燥;是JSX吗?,javascript,reactjs,react-jsx,Javascript,Reactjs,React Jsx,如何选择在JSX中包含元素?下面是一个使用横幅的示例,如果该横幅已传入,则该横幅应位于组件中。我想要避免的是在if语句中重复HTML标记 render: function () { var banner; if (this.state.banner) { banner = <div id="banner">{this.state.banner}</div>; } else { banner = ????? }

如何选择在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>
    );
}
render:function(){
瓦尔旗;
如果(本州横幅){
banner={this.state.banner};
}否则{
横幅=?????
}
返回(
{banner}
废话废话。。。
);
}

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

这怎么办。让我们定义一个简单的帮助
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>
    );
}
你使用它时必须小心。我建议阅读其他答案,寻找替代(更安全的)方法

更新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>
    );
}
<h3>{this.state.banner.title || 'Default banner title'}</h3>

当“if”分支中有多个元素时,此组件工作:

var Display=React.createClass({
渲染:函数(){
如果(!this.props.when){
返回false;
}
返回React.DOM.div(null,this.props.children);
},
});
用法:

render:function(){
返回(
正在加载某些内容。。。
Elem1
Elem2
加载
Elem3
Elem4
);
}

另外,有人认为这些组件不利于代码读取。但在我看来,使用javascript的Html更糟糕

如果样式组件是危险的,因为代码块总是在不考虑条件的情况下执行。例如,如果
banner
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(){
返回(
{函数(){
如果(本州横幅){
返回{this.state.banner}
}
}.叫(这个)}
废话废话。。。
);
}
react的另一个选项:

render:function(){
返回(
{this.state.banner&&
{this.state.banner}
}
废话废话。。。
);
}

我做了一些简化,基本上,它允许您将
条件定义为标记,然后将它们编译成三元ifs,这样
中的代码只有在条件为真时才能执行。

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

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: ->
  <div className="container">
    {
      if something
        <h2>Coffeescript is magic!</h2>
      else
        <h2>Coffeescript sucks!</h2>
    }
  </div>  
render:->
{
如果有什么
咖啡脚本很神奇!
其他的
咖啡糟透了!
}

我个人认为()中显示的三元表达式是符合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>

{这个州的旗帜(
{this.state.banner}
) : 
空}
废话废话。。。
&&+代码样式+小组件 这个简单的测试语法+代码样式约定+小型的重点组件对我来说是最可读的选项。您只需特别注意错误值,如
false
0

render:function(){
var person=。。。;
var计数器=。。。;
返回(
{个人&&(
)}
{(计数器类型!=“未定义”)&&(
)}
);
}
做记号 ES7 stage-0 do表示法语法也非常好,当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}/>
}
constusers=({Users})=>(
{users.map(user=>
)}
)  
const UserList=({users})=>do{
如果(!用户)正在加载
如果(!users.length)为空,则为else
其他的
}


这里有更多详细信息:

实验性ES7
do
语法使这变得容易。如果您使用的是Babel,请启用
es7.doExpressions
功能,然后:

render() {
  return (
    <div id="banner">
      {do {
        if (this.state.banner) {
          this.state.banner;
        } else {
          "Something else";
        }
      }}
    </div>
  );
}
render(){
返回(
{do{
如果(本州横幅){
这个州的旗帜;
}否则{
“其他东西”;
}
}}
);
}

请参见

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

即:

render:function(){
返回(
{this.props.product.title | |“无标题”}
);
}

还有另一种解决方案:

var节点=require('react-if-comp');
...
render:function(){
返回(
废话废话。。。
);
}
我最近做了一个改进,仅当谓词通过时才安全地呈现元素

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

const ifUniverseIsWorking=renderIf(1+1==2);
//...
{如果你正在工作(
你好
)}

你也可以这样写

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

如果您的
state.banner
null
未定义
,则跳过条件的右侧。

大多数示例都带有一行有条件呈现的“html”。这对我来说似乎是可读的
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}/>
}
render() {
  return (
    <div id="banner">
      {do {
        if (this.state.banner) {
          this.state.banner;
        } else {
          "Something else";
        }
      }}
    </div>
  );
}
render: function() {
            return (
                <div className="title">
                    { this.props.product.title || "No Title" }
                </div>
            );
        }
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>
    );
}
{renderIf(1 + 1 === 2)(
  <span>Hello!</span>
)}
const ifUniverseIsWorking = renderIf(1 + 1 === 2);

//...

{ifUniverseIsWorking(
  <span>Hello!</span>
)}
{ this.state.banner && <div>{...}</div> }
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>
}
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>
    );
}
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 />
    }
  }
}
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>
  );
}
{(() => {
  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})}/>
  }
})()}
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>
  );
}
function() {

}()
(function() {

}())
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'));
{opened && <SomeElement />}
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
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>
        )}
      />
    )
  }
}
const If = ({children, show}) => show ? children : null
<If show={true}> Will show </If>
<If show={false}> WON'T show </div> </If>
{ 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>
    );
}
export default function ReactIf(props: {condition: boolean, children: React.ReactNode }) {
    return props.condition ? <React.Fragment>{props.children}</React.Fragment> : <React.Fragment/>;
}