父组件中的 Reactjs 按钮,在子组件中提交 Redux 表单
Posted
技术标签:
【中文标题】父组件中的 Reactjs 按钮,在子组件中提交 Redux 表单【英文标题】:Reactjs button in Parent component which submits Redux Form in Child Component 【发布时间】:2019-03-07 18:37:59 【问题描述】:我有 4 个嵌套组件,<CompD>
嵌套在 <CompC>
中,<CompB>
嵌套在 <CompB>
中,<CompA>
中嵌套。
<CompD>
包含一个带有 onSubmit=onSubmit
的 Redux 表单,带有一堆输入和一个带有 type="submit"
的保存按钮
<CompD>
的 sn-p 当前带有按钮:
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>
中的按钮的行为方式与<CompD>
中的按钮完全相同并提交表单。
<CompA>
的 sn-p 添加了一个新按钮:
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)
函数中的表单数据
有什么想法可以做到这一点吗?
【问题讨论】:
您想获取 CompA 中的按钮并将表单保留在 CompD 中吗? 您的意思是点击<CompA>
中的按钮,然后以某种方式触发<CompD>
中的Form 的onSubmit
事件,对吧?
@NguyễnThanhTú 是的,这是正确的
@IvanBurnaev 是的
【参考方案1】:
React 组件使用 props 相互通信。 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>
【讨论】:
谢谢你的详细回答,我已经编辑了我的帖子以包含代码sn-ps,你能看看 你想把数据保存在<CompD />
吗?
我不确定,但我想将Form
保留在那里,这是否意味着数据也应该保留在那里?
谢谢会检查,如果它有区别,我正在使用 Redux 表单并将状态映射到道具【参考方案2】:
您可以将表单提交状态和逻辑从 <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>
但是将表单与提交按钮分开看起来确实很冗长。不知道为什么你有这样的需求,但通常最好将它们放在一个组件中。
【讨论】:
谢谢你的详细回答,我已经编辑了我的帖子以包含代码sn-ps,你能看看 您好,我已阅读您更新的 sn-ps。如果在onSubmit
、onChange
等从 以上是关于父组件中的 Reactjs 按钮,在子组件中提交 Redux 表单的主要内容,如果未能解决你的问题,请参考以下文章