You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript项目用Formik 2.2.9修改select值后不重新渲染怎么解决

问题核心原因

你手动给Field组件绑定了this.props.criterion.xxx.toString(),相当于覆盖了Formik内置的双向绑定逻辑:Formik内部状态更新后,你绑定的value始终是props传入的初始值,自然不会触发视图刷新。而如果不绑定value,你的initialValues是数值/布尔类型,和select option的字符串value类型不匹配,初始渲染时找不到对应选项,所以显示为空。

解决方案

按以下步骤修改即可,不需要自定义onChange事件:

  1. 初始化表单时提前做类型适配:把所有对应select的字段统一转成字符串类型,和option的value类型保持一致
  2. 移除所有Field组件上手动绑定的value属性,让Formik全权处理值的双向绑定
  3. 提交前把表单的字符串值转换回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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 07:36:01