【发布时间】:2017-12-07 15:39:21
【问题描述】:
所以我有一个组件 A(扩展 React.component),它被一个更高阶的组件 B 包裹。
在组件 B 的方法中,我需要为 A 设置状态,或者在 A 中调用一个函数(以便它可以执行 setState) - 这通常是如何完成的?
我可以在此处粘贴实际代码,但我认为如果有处理这种情况的标准方法可能会使事情复杂化。
编辑:这里的代码 - isOpen 需要改变模态关闭,它需要改变 handleSubmit....
import React from 'react';
import Modal from 'react-modal';
import { withFormik, Form, Field } from 'formik';
import Yup from 'yup';
// first part of Formik integration
const formikEnhancer = withFormik({
mapPropsToValues(props) {
return {
personName: props.email || '',
personSurname: props.surname || '',
personCongregation: props.congregation || ''
}
},
validationSchema: Yup.object().shape({
personName: Yup.string().required().min(1),
personSurname: Yup.string().required().min(2),
personCongregation: Yup.string().required().min(8)
}),
handleSubmit(values, {props, resetForm, setErrors, setSubmitting}) {
submitNewPerson(values, {resetForm, setErrors, setSubmitting});
props.testCall;
}
});
function submitNewPerson(v, {resetForm, setErrors, setSubmitting}) {
//e.preventDefault();
congregations = [];
congregations.push(v.personCongregation);
const peep = {
name: v.personName,
surname: v.personSurname,
congregations: congregations//,
//startDate: Number(e.target.componentStartDate.value),
//endDate: Number(e.target.componentEndDate.value)
};
// do the db insert here and check for errors
setSubmitting(false);
});
};
class AddPerson extends React.Component {
constructor(props) {
super(props);
this.state = {
error: undefined,
isOpen: false
}
}
componentWillMount() {
Modal.setAppElement('body');
}
renderCong() {
// this just maps out a list of select options
}
render() {
return (
<div>
<button className="button" onClick={()=> this.setState({isOpen:true, error:undefined})}>+ Add Person</button>
<Modal isOpen={this.state.isOpen} contentLabel="Add Person"
className = "boxed-view__box" overlayClassName="boxed-view boxed-view--modal">
<Form className="boxed-view__form">
<div>
<Field type="text" name="personName" placeholder="Name" />
</div>
<div>
<Field type="text" name="personSurname" placeholder="Surname" />
</div>
<div>
<Field component="select" name="personCongregation" value={this.state.cong}>
<option key="0" value="">- Select Option -</option>
{this.renderCong()}
</Field>
</div>
<button disabled={this.props.isSubmitting} className="button">Add Person</button>
<button disabled={this.props.isSubmitting} type="button" className="button button--secondary" onClick={
()=> {
this.props.resetForm();
this.setState({isOpen:false});
}}>Cancel</button>
</Form>
</Modal>
</div>
)
};
};
【问题讨论】:
-
在高阶组件中,您永远不需要在包装的组件上使用设置状态。与您的包装组件通信的唯一方法是使用
props您能否再描述一下您的功能用例? -
B 不应该知道 A 的状态,A 应该提供一个 B 可以使用的待更新接口,这可以通过暴露 B 可以更新的 props 来完成,您可以添加
componentWillReceiveProps方法A 根据收到的道具相应地更新状态。 -
谢谢 - 有帮助的开始。所以 HOC (B) 是 Formik,它处理表单的验证和提交。在我的组件 (A) 中,我通过更改状态来打开模型以显示表单。然后Formik(B)有一个handleSubmit方法,当(A)提交时触发。如果提交成功,我需要通过更改状态来关闭模式 - 如果它是错误的,我需要通过更改状态来显示错误。
-
为此,您应该让表单的父组件处理提交,它可以 (a) 触发来自表单组件的 onSubmit 回调,并且 (b) 保持成功/失败状态并传递后退作为要显示的道具。
-
那么我认为状态应该在 B 内部处理,因为它是处理表单提交结果的一个,你可以在你的 B 状态中有一个
modalOpen和hasError属性,你可以在那里更新然后作为道具发送给 A 以便它可以更新自己的状态并隐藏/显示模式以及错误。
标签: javascript reactjs