反应条件渲染模式

Zha*_*hao 20 javascript reactjs

我已经实现了一个模态组件,在屏幕上显示模式对话框.通常,模态将有条件地显示.我可以通过两种方式在render函数中执行此操作:

render(){
    ...
    <Modal show={this.state.showModal}>
        // something in modal
    </Modal>
}
Run Code Online (Sandbox Code Playgroud)

在Modal组件中,我使用this.props.show为自己添加一个不同的类.如果为false,则会添加display:none来隐藏模态.

另一种方式是这样的:

render(){
    ...
    { this.state.showModal &&
        (<Modal>
            // something in modal
        </Modal>)
    }
}
Run Code Online (Sandbox Code Playgroud)

这用于showModal决定是否在渲染中添加模态.

我想弄清楚的是:

  1. 这两种方式有什么不同?
  2. 其中一个比另一个好吗?
  3. 还有另一种方法吗?

编辑:似乎不同的人有不同的偏好.对我来说,我更喜欢@ErikTheDeveloper所说的.显示/隐藏模态的功能应该保留在模态中,当我们不需要显示模态时,我们可以在模态中返回null.

我想也许没有一个答案,哪种方式更好.也许这只是个人选择?

Dyl*_*lan 7

您的第一个示例始终呈现模式,但使用CSS隐藏/显示它.

您的第二个示例仅在显示时将模式插入到DOM中,否则它根本不会显示在DOM中.

我不想渲染它,除非它是可见的(第二个例子),但我认为无论如何都不重要.第二个例子现在也有更少的道具,因此Modal组件更简单.


cod*_*erC 5

我也更喜欢第二种方法。尽管 React 最大限度地减少了 DOM 中附加元素的负面影响,但不渲染不应该渲染的元素始终是一个好习惯。我将扩展这种想法,并提取在单独的函数中显示/隐藏模态的逻辑,并在渲染中调用它。

render: function(){
   ...
   {this.renderModal()}
},
renderModal: function(){
    ...
    {this.state.showModal && (<Modal />)}
}
Run Code Online (Sandbox Code Playgroud)

这使您可以灵活地在单个位置添加附加条件,并使渲染函数保持较小且易于理解。


Eri*_*bar 2

我不久前回答了一个类似的问题,涉及打开/关闭模式的最佳方式

从那时起,我花了很多时间使用 React,并在此过程中吸取了一些教训。

我发现这种通用方法可以很好地处理模态:使用完全受控的“哑”组件,需要 3 个 props。

  • show: Boolean - 模式是否可见?
  • close:函数 - 模式需要回调才能关闭自身
  • Children: 节点 - 模态框的内容

有关受控组件的信息,请参阅 React 文档


要回答关于两者之间差异的问题,IMO 选项 1 提供了更清晰、更灵活的 API 来使用,而选项 2 则更加简约。

使用选项 1,您可以通过使用CSS从. 我建议返回,因为模态内容根本不会被渲染,而不是渲染它们并通过 CSS“隐藏”它们。null<Modal>null

选项 2 强制使用更详细的“JSX 方式”进行条件渲染,我认为这在很多情况下都是合适的。<Modal>然而,我觉得模态的概念值得隐藏/显示作为组件 API(道具/方法/等...)的一部分


为什么要传递closeprop/callback?

考虑到大多数模态都有 UX,例如关闭事件,例如:按 [ESC]、单击“x”、单击模态外部等...需要通过传递 prop 来告知模态如何“关闭自身close” /callback 在我下面的例子中。


代码示例

// The simple, fully controlled Modal component
const Modal = React.createClass({
  render() {
    const {
      show,     // Boolean - Is the modal visible?
      close,    // Function - The modal needs a function to "close itself"
      children, // node - The contents of the modal 
    } = this.props;
    return !show ? null : (
      <div className="some-class-for-styling">
        <a onClick={close}>x</a>
        {children}
      </div>
    );
  }
});

const UsesModal = React.createClass({
  setEditing(editing) {
    this.setState({editing});
  },

  render() {
    // `editing` could come from anywhere. 
    // Could be derived from props, 
    // or managed locally as state, anywhere really....
    const {editing} = this.state;
    return (
      <div>
        <h1>Some Great Component</h1>
        <a onClick={() => this.setEditing(true)}>Show Modal!</a>
        <Modal show={editing} close={() => this.setEditing(false)}>
          Some great modal content... show based on UsesModal.state.editing
        </Modal>
      </div>
    );
  }
});
Run Code Online (Sandbox Code Playgroud)

如果你想让模态管理它自己的状态,你可以用一个稍微聪明的组件包装“哑”模态,并使用 refs 和“公共组件方法”(尽管我发现坚持使用简化的方法)通常会减少头痛和遗憾;))

const SmarterModal = React.createClass({
  close() {
    this.setState({show: false});
  },

  open() {
    this.setState({show: true});
  },

  render() {
    const {children} = this.props;
    const {show} = this.state;
    return (
      <Modal show={show} close={this.close}>
        {children}
      </Modal>
    );
  }
});

const UsesSmarterModal = React.createClass({
  render() {
    return (
      <div>
        <h1>Some Great Component</h1>
        <a onClick={() => this.refs.my_smarter_modal.open()}>Show Modal!</a>
        <SmarterModal ref="my_smarter_modal">
          Some great modal content... show based on SmarterModals own internal state
        </SmarterModal>
      </div>
    );
  }
});
Run Code Online (Sandbox Code Playgroud)

您可以通过多种方式来概括简单的内容<Modal>,但我觉得它可以作为坚实的基础,并且数据流可以很好地运行,以允许从最有意义的任何地方进行计算/导出“模态是否开放”。这是我发现效果很好的方法。