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

2022-08-30 00:47:06

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

答案 1

只需将横幅保留为未定义,并且不会包含它。


答案 2

那这个呢。让我们定义一个简单的帮助组件。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>