簡體   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