如何在 Facebook React 的 JSX 中使用条件元素并保持 DRY?

IT技术 javascript reactjs react-jsx
2021-01-28 04:53:01

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

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

除了那个答案旁边的垃圾,我想不出任何别的东西......好像我偶然发现了众神
2021-03-28 04:53:01
是否null工作得一样好undefined规范的那一部分是否也以这种方式工作,因此将来不太可能打破?
2021-04-02 04:53:01

那这个呢。让我们定义一个简单的帮助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>
谢谢。我建议阅读此github.com/facebook/react/issues/690此链接已发布在此问题下方的评论中,我在发布解决方案后注意到了它。如果你检查它,有些人也提到了这个解决方案,但不推荐它。我个人认为这没问题,至少在 OP 的情况下,但确实这种方式并不完美(例如,没有很好的方法来定义 else 分支)。总之,值得一读。
2021-03-18 04:53:01
只需用另一个元素包裹它,<span>或者<div>.
2021-03-18 04:53:01
当我尝试使用它来渲染 <td> 或 <table> 中的空时出现问题,因为 <noscript> 作为 <tr> 的子级是不可接受的。否则它对我来说很好用。
2021-03-18 04:53:01
如果你打算这样做,有一个非常好的转译方法:npmjs.com/package/jsx-control-statements
2021-04-11 04:53:01
不确定这是否仍然有效,因为最新版本似乎要求返回值是 ReactElement
2021-04-12 04:53:01

就个人而言,我真的认为(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>
@moby 我认为流行的答案更具动态性,并导致渲染功能更清晰。使用这种方法,如果您有多个条件会发生什么?您现在会疯狂地使用这种奇怪的格式进行嵌套,如果两个单独的区域需要根据条件进行相同的更改,您现在必须再次重写条件。虽然只是我的意见!:)
2021-03-20 04:53:01
一个相关的页面也非常有用:facebook.github.io/react/docs/...
2021-03-20 04:53:01
@Chiedo 为什么你更喜欢流行的答案?这似乎很好用。
2021-03-29 04:53:01
注意:括号与组件返回相同,因此您的内容需要用 <div></div> 包围。
2021-04-14 04:53:01

你也可以这样写

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

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

If样式组件是危险的,因为该代码块总是执行不管条件的。例如,如果banner,这将导致空异常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>
  );
}

react问题的另一个选择

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>
  );
}
在迄今为止的所有解决方案中,内联函数似乎是最优雅和直接的。有什么需要注意的吗?
2021-04-09 04:53:01