当redux store中的值发生变化时,如何更新formik中的特定表单字段?
Posted
技术标签:
【中文标题】当redux store中的值发生变化时,如何更新formik中的特定表单字段?【英文标题】:How to update specific form field in formik when value changes in redux store? 【发布时间】:2020-06-08 02:15:38 【问题描述】:我在我的反应应用程序中使用 formik。我已经从一个状态初始化了所有表单值。但是如果 redux 商店中的道具发生变化,我想更新一个特定的表单字段。下面是我的formik表单:
<Formik
initialValues=this.state.branchData
enableReinitialize=true
onSubmit=this.formSubmit >
( values, setFieldValue ) => (
<Form >
<Row>
<Col lg="12">
<FormGroup className="col-6">
<Input type="select" value=values.StateId name="StateId" onChange=this.handleChange(setFieldValue)>
<option value='' >Select State</option>
this.props.stateList && this.props.stateList.map((item, i) => (
<option key=i value=item.StateId>
item.StateName
</option>
))
</Input>
this.validator.message('state', values.StateId, 'required')
<Label className="impo_label">Select State</Label>
</FormGroup>
<FormGroup className="col-6">
<Field className="form-control" name="GstNo" type="text" maxLength="15" />
<Label className="impo_label">GST No</Label>
this.validator.message('gst no', values.GstNo, 'required|min:15|max:15')
</FormGroup>
</Col>
</Row>
</Form>
)
现在,当我从下拉列表中更改状态时,将调用一个 API,该 API 将通过状态 ID 返回 gst no。我想用从道具中的 api 收到的值更新 gst no 字段。如果收到的 gst no 为空,那么我希望用户输入 gst no,但如果从 api 收到 gst no,我想用 props 中收到的值更新表单中的 gst no 字段并禁用表单输入。我无法更新 this.state.branchData 中的 gstno,因为这将使用 this.state.branchData 中的值重置表单值。
有人知道如何在 formik 中实现这一点吗?
【问题讨论】:
【参考方案1】:当数据来自api
。您可以像这样轻松更改字段的值:
setFieldValue('GstNo', valueFromApi)
【讨论】:
setFieldValue() 在 formik 表单之外无法访问。你有什么方法可以让我在 componenetWillRecieveProps() 的某个地方访问 formik 表单之外的 setFieldValue() 吗? 你可以调用formik
里面的函数并调用它。示例:``` formik
: `` const setGsNo = (value, setFieldValue) => setFieldValue('GstNo', valueFromApi) ```
至少有codesandbox
对不起,我没有得到你的解决方案,你的代码框也没有工作。【参考方案2】:
我定义了一个用于维护 gstNo 的状态变量,它将根据从下拉列表中选择的状态 ID 从 API 中获取。像这样:
this.state =
gstNo: null,
;
因此,当调用 API 并收到响应时,gstNo 属性将在 redux 存储中更新。
this.state.gstNo
将在 UNSAFE_componentWillReceiveProps() 中更新,当this.props.gstNo
更改时。如下:
if (this.props.gstNo !== nextprops.gstNo)
let gstNo;
if (nextprops.gstNo)
gstNo = nextprops.gstNo;
else
gstNo = null;
this.setState(
gstNo: gstNo,
);
为了给formik赋值this.state.gstNo
,我简单地写了这个:
<FormGroup className="col-6">
<Field
className="form-control"
name="GstNo"
disabled=this.state.gstNo
type="text"
maxLength="15"
value=
(values.GstNo = this
.state.gstNo
? this.state.gstNo
: values.GstNo)
/>
<Label className="impo_label">
GST No
</Label>
</FormGroup>
因此,一旦this.state.gstNo
具有某些价值,它就会反映在 formik 表单的文本字段中,并且文本框将被禁用。
【讨论】:
【参考方案3】:您可以启用 Formik 的 enableReinitialize 属性来更新字段。
<Formik
enableReinitialize=true
initialValues=...
>
....
【讨论】:
感谢您的解决方案,@Msilucifer。这真的节省了我的时间! :)【参考方案4】:最好使用setFieldValue,当API获取一些值或者任何props/dependency值发生变化时,可以使用useEffect来处理,
例如:
我从父组件中获得了 setFieldValue
函数作为道具。
useEffect(() =>
if (
values.parentCategoryId &&
!categories?.data?.find(category => category.id === values.categoryId)
?.hasFurnishingStatus
)
setFieldValue('furnishingStatus', '');
, [values?.categoryId]);
这里的furnishingStatus
是我要为其设置值的字段的名称。
<Field name="furnishingStatus" component=RadioGroup row>...</Field>
【讨论】:
以上是关于当redux store中的值发生变化时,如何更新formik中的特定表单字段?的主要内容,如果未能解决你的问题,请参考以下文章
当 React JS 中的一项值使用地图函数中的状态发生变化时,如何动态更新购物车中的值?
当 uitableviewcell 中 uipickerview 的值发生变化时,我需要更新 viewcontroller 中的标签