最近我不得不在React中写一些东西,这要求我在一个模态中渲染不同的组件。因为我不想在同一个父组件中用不同的模态重复我的自我,所以我决定重复使用它,但不确定如何正确地执行它#34;正确"。这就是我所做的:
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>
}
我知道它有点难以阅读,因为代码片段中的缩进略微搞砸了。但正如你所看到的,根据&#34; currentModalAction&#34;我只有返回相关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>
是的,我已经实现了可重用性&#34;这种模式,并没有重复我的自我,但在我看来,这可能弊大于利......不可读,不太清楚。
对此问题有一些共同的方法吗?请注意,我没有使用react-modal或类似的东西。它只是反应堆。
答案 0 :(得分:3)
我制作了一些代表你案件的代码。
你可以使用像renderBodyComponent
这样的函数道具来渲染你的模态体。
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'));
&#13;
.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;
}
&#13;
<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>
&#13;