使用状态更新其中一个 Formik 初始值会重置所有其他值

Updating one of the Formik initial values with state resets all other values

我目前有一个正在使用 formik 构建的表单。我能够按预期更新每个字段(姓名、电子邮件、phone)。我 运行 遇到的问题是当我提供一个带有状态值的 formik 初始值并更新该状态时。更新状态的行为导致表单完全重置输入字段有没有办法在不重置整个表单的情况下更新测试状态?我的代码如下:

import { useState } from "react";
import { Formik, FieldArray } from "formik";
import "./styles.css";

export default function App() {
  const [test, setTest] = useState(null);
  return (
    <Formik
      enableReinitialize
      initialValues={{
        test: test,
        name: "",
        email: "",
        phone: ""
      }}
    >
      {({
        values,
        touched,
        errors,
        handleChange,
        handleBlur,
        handleSubmit
      }) => (
        <>
          <button onClick={() => setTest("something")}>Update State</button>
          <br />
          <input
            placeholder="name"
            type="text"
            name="name"
            value={values.name}
            onChange={handleChange}
          />
          <br />
          <input
            placeholder="email"
            type="text"
            name="email"
            value={values.email}
            onChange={handleChange}
          />
          <br />
          <input
            placeholder="phone"
            type="text"
            name="phone"
            value={values.phone}
            onChange={handleChange}
          />
          <>
            <pre style={{ textAlign: "left" }}>
              <strong>Values</strong>
              <br />
              {JSON.stringify(values, null, 2)}
            </pre>
            <pre style={{ textAlign: "left" }}>
              <strong>Errors</strong>
              <br />
              {JSON.stringify(errors, null, 2)}
            </pre>
          </>
        </>
      )}
    </Formik>
  );
}


为了复制我在 codesandbox 中谈论的内容,首先更新姓名、电子邮件和 phone 号码。然后点击更新状态按钮,一切都会被重置

codesandbox https://codesandbox.io/s/wispy-sun-mzeuy?file=/src/App.js:0-1567

这是因为您正在初始化 Formik 组件,其中 enableReinitialize 设置为 true:

enableReinitialize?: boolean

Default is false. Control whether Formik should reset the form if initialValues changes (using deep equality).

更新状态变量 test 时,formik 值将重新初始化为 initialValues 中设置的值。


如果你想让它工作,我已经 forked your sandbox 并将其修改为使用 formik 钩子(没有 enableReinitialize)结合 useEffect 来手动更新值来自州:

  const [test, setTest] = useState(null);
  const { values, errors, handleChange, setFieldValue } = useFormik({
    initialValues: {
      test: test,
      name: "",
      email: "",
      phone: ""
    }
  });

  useEffect(() => {
    setFieldValue("test", test);
  }, [test]);