使用React和React-bootstrap应用程序进行不必要的模态渲染

时间:2017-10-13 06:43:01

标签: javascript reactjs react-bootstrap

我正在学习React,正在开发一个简单的小应用程序。该应用程序包含一行,其中包含选项卡和下拉菜单。从该下拉列表中,您可以打开用于添加/删除/编辑所述选项卡的模式。

我注意到所有模态都会在应用程序启动时调用它们的render方法,每次单击任何选项卡,甚至是当前选定的选项卡。我是React的新手,所以如果这应该发生,我会很困惑。该应用程序似乎按预期工作。

以下是代码的超简化版本,只包含必要的部分:

app.js

class App extends React.Component {
  // ...
  // state is { modals: { addTab: false, editTab: false, removeTab: false } }

  closeModal = (modalState) => {
    const obj = this.state.modals;
    obj[modalState] = false;
    this.setState(obj);
  }

  render() {
    <div className="App container-fluid">
      // ...
      <AddTabModal showModal={this.state.modals.addTab} closeModal={this.closeModal} ... />
      // ...
    </div>
  }
}

AddTabModal.js

class AddTabModal extends React.Component {
  // ...
  render() {
    // This gets triggered every time I click any tab or the dropdown menu.
    // Even if the modal is not visible.
    console.log('Render add tab modal');
    return (
      <Modal show={this.props.showModal} ... >
        // ...
        <Modal.Footer>
          <Button onClick={() => { this.props.closeModal('addTab'); }}>Close</Button>
        </Modal.Footer>
      </Modal>
    );
  }
}

我还读到在JSX中使用箭头函数是一个糟糕的模式,但如果我将按钮更改为:

<Button onClick={this.props.closeModal('addTab')}>Close</Button>

当我点击按钮时它仍然应该运行,对吗?但应用程序从一开始就完全锁定,我得到“超出最大更新深度”错误。我相信这与上述问题有关,因为我在应用程序中没有任何componentWillUpdate / componentDidUpdate方法。

1 个答案:

答案 0 :(得分:2)

您可以采取一些措施进行优化:

  • 确保传递给模态的所有道具都是不可变的
  • 将close函数解压缩为类方法
  • 除非道具改变
  • ,否则使用PureComponent来阻止渲染
class AddTabModal extends PureComponent {
  // ...
  onCloseModal = () => {
    this.props.closeModal('addTab');
  }

  render() {
    // This gets triggered every time I click any tab or the dropdown menu.
    // Even if the modal is not visible.
    console.log('Render add tab modal');
    return (
      <Modal show={this.props.showModal} ... >
        // ...
        <Modal.Footer>
          <Button onClick={this.onCloseModal}>Close</Button>
        </Modal.Footer>
      </Modal>
    );
  }
}
  

我还读到在JSX中使用箭头函数是一个糟糕的模式,但如果我将按钮更改为:

<Button onClick={this.props.closeModal('addTab')}>Close</Button>

这是因为() => this.props.closeModal('addTab')创建了一个新函数,调用时会关闭模态。但是,如果您只有this.props.closeModal('addTab'),则立即调用close模态函数。

避免额外匿名函数的方法是将其提取为类似上面代码中的类方法。