我在我的页面上打开并关闭了表单的以下代码段:
<div>
{this.state.editFormOpen?
<div>
<Link
to=''
onClick={()=>{this.setState({editFormOpen:false})}}>
Close
</Link>
<PostForm
onSubmit={(post)=>this.createPost(post)}
/>
</div>:
<Link
to=''
onClick={()=>{this.setState({editFormOpen:true})}}>
Add post
</Link>}
</div>
现在为了避免重复自己,我想将该代码重构为一个单独的<FormHandler/>
组件,这样它就适用于任意形式,而不仅仅是
<PostForm/>
。即,我需要能够将任何表单组件传递给<FormHandler/>
。
如何在React中执行此操作?
答案 0 :(得分:1)
为了实现这一目标,您已经拥有了所需的一切。也许只需更改您呈现3.6
的行并接受来自新组件的PostForm
。有了它,您将能够在其中呈现您想要的任何形式。
请记住,您在props.children
之外保留的业务逻辑越少越好。每个表单都应该知道在每个字段更改或提交时应该做什么。
例如,FormHandler
不应成为this.createPost
的一部分,以防您想在整个代码中重复使用它。
FormHandler
class FormHandler extends React.Component {
constructor(props) {
super(props)
this.state = {
formOpen: false,
}
this.toggleFormOpen = this.toggleFormOpen.bind(this)
}
toggleFormOpen() {
this.setState({
formOpen: !this.state.formOpen,
})
}
render() {
return (
<div>
<button onClick={this.toggleFormOpen}>
{this.state.formOpen ? 'Close' : 'Open'}
</button>
{this.state.formOpen && React.cloneElement(
this.props.children,
{
onClose: this.toggleFormOpen
}
)}
</div>
)
}
}
const PostForm = ({ onClose, onSubmit }) =>
<form>
<input type="text" placeholder="Post Name" />
<input type="text" placeholder="Post Title" />
<input type="text" placeholder="Date" />
<button onClick={event => {
event.preventDefault()
onSubmit({ postName: '', postTitle: '', date: ''})
onClose()
}}>
Submit
</button>
</form>
const UserForm = ({ onClose, onSubmit }) =>
<form>
<input type="text" placeholder="First Name" />
<input type="text" placeholder="Last Name" />
<button onClick={event => {
event.preventDefault()
onSubmit({ firstName: '', lastName: '' })
onClose()
}}>
Submit
</button>
</form>
const App = () =>
<div>
<FormHandler>
<PostForm
onSubmit={formData => console.log('PostForm', formData)}
/>
</FormHandler>
<br />
<FormHandler>
<UserForm
onSubmit={formData => console.log('UserForm', formData)}
/>
</FormHandler>
</div>
ReactDOM.render(
<App />,
document.getElementById('root')
)
答案 1 :(得分:1)
我将通过创建一个返回React Component的工厂来实现它,而不是将子项渲染为props
const FormHandlerFactory = ({Form = PostForm}) => {
return class FormHandler extends React.Component {
render() {
return (
<div>
{this.state.editFormOpen?
<div>
<Link
to=''
onClick={()=>{this.setState({editFormOpen:false})}}>
Close
</Link>
<Form
onSubmit={(post)=>this.createPost(post)}
/>
</div>:
<Link
to=''
onClick={()=>{this.setState({editFormOpen:true})}}>
Add post
</Link>}
</div>
)
}
}
}
您可以将此工厂用作
const FormHandler = FormHandlerFactory({Form: YourCustomFormComponent});
const App = (props) => (
<Form {...props}
)
答案 2 :(得分:1)
您可以创建一个无状态组件,该组件可以呈现您在该组件中传递的任何子项,您还需要将状态放在父组件中
const ToggleForm = ({ editFormOpen, editFormHandler, children }) => (
<div>
{editFormOpen?
<div>
<Link
to=''
onClick={() => editFormHandler(false)}>
Close
</Link>
{children}
</div>:
<Link
to=''
onClick={() => editFormHandler(true)}>
Add post
</Link>}
</div>
);
class ParentCmp extends React.Component {
constructor(props) {
super(props);
this.state = {
editFormOpen: false,
}
this.editFormHandler = this.editFormHandler.bind(this);
this.createPost = this.createPost.bind(this);
}
editFormHandler(boolValue) {
this.setState({
editFormOpen: boolValue
});
}
render() {
return (
<div>
<ToggleForm
editFormOpen={this.state.editFormOpen}
editFormHandler={this.state.editFormHandler}
>
<PostForm
onSubmit={(post)=>this.createPost(post)}
/>
</ToggleForm>
</div>
)
}
}