繁体   English   中英

在React组件中使用不同的子元素重用模式

[英]Reusing a modal, in a React component, with different children

最近,我不得不在React中写一些东西,这需要我在模式中渲染不同的组件。 由于我不想在同一个父组件中使用不同的模态来重复我的自我,所以我决定重用它,但是不确定如何“正确”地进行操作。 这是我所做的:

  renderModalTitle = () => {
return this.state.currentModalAction === 'delete' ? `Are you sure you want to delete book "${this.state.currentBook.title}"?`
  : this.state.currentBook ? `Edit book "${this.state.currentBook.title}"`
    : 'Create new book'
}

renderModalBody = () => {
  return this.state.currentModalAction === 'edit' || 
   this.state.currentModalAction === 'new' ?
    <BookForm book={this.state.currentBook} onSave={this.onBookSave}> 
    </BookForm>
      : <ConfirmDelete onBookDeleteCancel={this.toggle} onBookDelete={()=> 
      {this.onBookDelete(this.state.currentBook.id)}} data= 
    {this.state.currentBook}></ConfirmDelete>

 }

我知道很难读,因为代码片段中的缩进有些混乱。 但是正如您所看到的,根据“ currentModalAction”,我只是具有返回相关jsx的函数。 然后在模态中:

 <Modal isOpen={this.state.modal} toggle={this.toggle} className={this.props.className}>
        <ModalHeader className="color_main" toggle={this.toggle}>{this.renderModalTitle()}</ModalHeader>
        <ModalBody>
          {this.renderModalBody()}
        </ModalBody>
        <ModalFooter>

          <Button className="square" color="default" onClick={this.toggle}>Cancel</Button>
        </ModalFooter>
      </Modal>

因此,是的,我已经实现了模式的“可重用性”,并且没有重复自己的工作,但是在我看来,这可能弊大于利……不可读,也不十分清楚。

是否有一些解决此问题的通用方法? 注意,我没有使用react-modal或类似的东西。 这只是反应。

我编写了一些代表您的案例的代码。

您可以使用诸如renderBodyComponent类的函数prop来渲染您的模态主体。

 class FlexibleModal extends React.Component { render() { if (!this.props.isOpen) { return null; } return ( <div className="flexible-modal"> <div className="flexible-modal-header"> {this.props.headerTitle} </div> <div className="flexible-modal-body"> {this.props.renderBodyComponent()} </div> </div> ); } }; const BodyCase1 = () => ( <div> Modal Body Case 1 </div> ); const BodyCase2 = () => ( <div> Modal Body Case 2 </div> ); class App extends React.Component { state = { showModal: false, case: 1, } toggleModal = () => { this.setState({ showModal: !this.state.showModal }); } toggleCase = () => { const nextCase = this.state.case === 1 ? 2 : 1; this.setState({ case: nextCase }); } render() { return ( <div> <button onClick={() => this.toggleModal()} > Toggle modal </button> <button onClick={() => this.toggleCase()} > Toggle next case </button> <FlexibleModal isOpen={this.state.showModal} headerTitle="Customizable Modal Header Title" renderBodyComponent={ this.state.case === 1 ? () => (<BodyCase1 />) : () => (<BodyCase2 />) } /> </div> ); } } ReactDOM.render(<App />, document.getElementById('react')); 
 .flexible-modal { margin: 15px; border: 1px solid #ddd; background: #fff; } .flexible-modal-header { border-bottom: 1px solid #ddd; padding: 10px; background: #e7e7e7; } .flexible-modal-body { padding: 10px; } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> <div id="react"></div> 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM