TypeScript项目用Formik 2.2.9修改select值后不重新渲染怎么解决
问题核心原因
你手动给Field组件绑定了this.props.criterion.xxx.toString(),相当于覆盖了Formik内置的双向绑定逻辑:Formik内部状态更新后,你绑定的value始终是props传入的初始值,自然不会触发视图刷新。而如果不绑定value,你的initialValues是数值/布尔类型,和select option的字符串value类型不匹配,初始渲染时找不到对应选项,所以显示为空。
解决方案
按以下步骤修改即可,不需要自定义onChange事件:
- 初始化表单时提前做类型适配:把所有对应select的字段统一转成字符串类型,和option的value类型保持一致
- 移除所有Field组件上手动绑定的value属性,让Formik全权处理值的双向绑定
- 提交前把表单的字符串值转换回
CriterionEdit接口要求的类型
修改后核心代码示例
public render() { return ( <React.Fragment> <h1>Edit</h1> <Formik enableReinitialize // 初始化时做类型转换 initialValues={{ ...this.props.criterion, interval: this.props.criterion.interval.toString(), isDeleted: this.props.criterion.isDeleted.toString(), groupId: this.props.criterion.groupId.toString() }} onSubmit={(values) => { // 提交前转换回目标类型 const submitValues: CriterionEdit = { ...values, interval: parseInt(values.interval, 10), groupId: parseInt(values.groupId, 10), isDeleted: values.isDeleted === "true" } const requestOptions = { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(submitValues), }; fetch("/criterion/update/", requestOptions).then( () => (window.location.href = "/criteria/my") ); }} > <Form translate="yes"> <Field name="id" type="hidden" /> <div className="form-group"> <label htmlFor="name">Criterion title</label> <Field name="name" className="form-control" type="text" /> </div> <div className="form-group"> <label htmlFor="interval">Interval</label> <Field name="interval" as="select" className="form-control" title="interval" > <option value="0">week</option> <option value="1">month</option> <option value="2">quarter</option> <option value="3">half-year</option> <option value="4">year</option> </Field> </div> <div className="form-group"> <label htmlFor="isDeleted">IsDeleted</label> <Field name="isDeleted" as="select" className="form-control" title="isDeleted" > <option value="false">no</option> <option value="true">yes</option> </Field> </div> <div className="form-group"> <label htmlFor="groupId">Group</label> <Field name="groupId" as="select" className="form-control" title="group" > {this.props.groups.map((option) => ( <option key={option.id} value={option.id.toString()}> {option.title} </option> ))} </Field> </div> <div className="form-group"> <label htmlFor="description">Description</label> <Field name="description" as="textarea" className="form-control" /> </div> <button type="submit" className="btn btn-primary"> Submit </button> </Form> </Formik> </React.Fragment> ); }
内容的提问来源于stack exchange,提问作者A K
相关产品推荐
相关产品推荐

