[英]Reactjs button in Parent component which submits Redux Form in Child Component
我有4个嵌套组件, <CompD>
嵌套在<CompC>
其被嵌套在<CompB>
其被嵌套在<CompA>
<CompD>
包含带有onSubmit={onSubmit}
的Redux表单和一堆输入,以及一个带有type="submit"
的保存按钮
当前带有按钮的<CompD>
片段:
const propTypes = {
firstName: PropTypes.string,
secondName: PropTypes.string
};
const defaultTypes = {
firstName = " ",
secondName = " "
};
const PollForm = ({
firstName,
secondName
}) => (
<Form onSubmit={onSubmit}>
.
.
<button type="submit">
'Save'
</button>
</Form>
);
PollForm.propTypes = propTypes;
PollForm.defaultProps = defaultProps;
export default PollForm;
我想将此按钮移到<CompA>
,所以<CompA>
的按钮的行为与<CompA>
中的按钮<CompD>
并提交表单。
<CompA>
代码片段,其中添加了一个新按钮:
const propTypes = {
onSubmit: PropTypes.func, ...
};
const defaultTypes = {
onSubmit: () = {}, ...
};
class Config extends Component {
constructor(props) {
super(props);
this.handleSubmit = this.handleSubmit.bind(this); ...
}
handleSubmit(data) {
this.props.onSubmit(data);
}
render() {
const {
} = this.props;
return (
.
.
<button onClick={onSubmit}>
'Save'
</button>
)
}
}
如何通过<CompA
的handleSubmit(data)
函数传递来自表单的数据任何想法如何做到这一点?
React Components使用道具相互通信。 Parent -> Child
通过props
, Child -> Parent
通过callback props
。 另一种方法是使用新的Context API
。 如果您有一个非常深的嵌套结构,那会更好。
波纹管我展示了如何通过道具来完成。
class CompB extends React.Component { state = { name: "John Doe", email: "john@doe.com" } handleChange = e => { const {name, value} = e.target; this.setState({[name]: value}) } handleSubmit = e => { e.preventDefault(); this.submit(this.state) } submit = (data) => { console.log("submitted", data, +new Date()); this.props.onSubmit(data); } componentDidUpdate (oldProps) { if (!oldProps.shouldSubmit && this.props.shouldSubmit){ this.submit(this.state); } } render () { const { name, email } = this.state; return ( <form onChange={this.handleChange} onSubmit={this.handleSubmit}> <div> <label> Name <input name="name" type="text" value={name} /> </label> </div> <div> <label> Email <input name="email" type="email" value={email} /> </label> </div> </form> ) } } class CompA extends React.Component { state = { shouldSubmit: false, } submit = () => { this.setState({shouldSubmit: true}) } handleSubmit = () => { this.setState({shouldSubmit: false}) } render () { const {shouldSubmit} = this.state; return ( <div> <CompB shouldSubmit={shouldSubmit} onSubmit={this.handleSubmit} /> <button type="button" onClick={this.submit} > Submit </button> </div> ) } } ReactDOM.render(<CompA />, document.querySelector("#root"))
<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="root"></div>
您可以将表单提交状态和逻辑从<CompD>
提升到<CompA>
,并且可以使用React Context提供深入到<CompD>
的表单状态和处理程序,例如:
import React from 'react'; import ReactDOM from 'react-dom'; const FormContext = React.createContext(); function CompB({ children }) { return <div id="B">{children}</div>; } function CompC({ children }) { return <div id="C">{children}</div>; } function CompD() { return ( <FormContext.Consumer> {({ onSubmit, onChange, name }) => { return ( <form onSubmit={onSubmit}> <label> Name: <input type="text" value={name} onChange={onChange} /> </label> <input type="submit" value="submit-input" /> </form> ); }} </FormContext.Consumer> ); } class CompA extends React.Component { onChange = ({ target: { value } }) => { this.setState({ name: value }); }; onSubmit = event => { event.preventDefault(); console.log('Submitting name: ', this.state.name); }; state = { name: 'defaultName', onSubmit: this.onSubmit, onChange: this.onChange, }; render() { return ( <FormContext.Provider value={this.state}> <CompB> <CompC> <CompD /> </CompC> </CompB> <button name="submit" onClick={this.onSubmit}>submit-btn<button/> </FormContext.Provider> ); } } ReactDOM.render( <CompA />, document.getElementById('root'), );
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>React App</title> </head> <body> <div id="root"></div> </body> </html>
但是将表单与提交按钮分开确实显得很冗长。 不知道为什么会有这样的需求,但是通常最好将它们组合在一个组件中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.