最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Updating one of the Formik initial values with state resets all other values - Stack Overflow

programmeradmin3浏览0评论

I currently have a form I am building using formik. I am able to update each of the fields(name, email, phone) as expected. The issue I am running into is when I provide one of the formik intial values with a state value and update that state. The act of updating the state causes the form to pletely reset the input fields Is there a way to update the test state without resetting the entire form?? My code is as follows:

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>
  );
}


In order to replicate what I am talking about in the codesandbox first update the name, email, and phone number. Then hit the udate state button and everything will be reset

codesandbox =/src/App.js:0-1567

I currently have a form I am building using formik. I am able to update each of the fields(name, email, phone) as expected. The issue I am running into is when I provide one of the formik intial values with a state value and update that state. The act of updating the state causes the form to pletely reset the input fields Is there a way to update the test state without resetting the entire form?? My code is as follows:

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>
  );
}


In order to replicate what I am talking about in the codesandbox first update the name, email, and phone number. Then hit the udate state button and everything will be reset

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

Share Improve this question asked Feb 25, 2021 at 16:05 Rob TerrellRob Terrell 2,5624 gold badges21 silver badges47 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 10

This is because you are initializing the Formik ponent with enableReinitialize set to true:

enableReinitialize?: boolean

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

When the state variable test is updated, the formik-values are reinitialized to the values set in initialValues.


If you want this to work, I've forked your sandbox and modified it to use the formik hook (without enableReinitialize) in bination with a useEffect to manually update the value from state:

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

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

My solution for this problem was to use the Formik values as state and set it directly with setFieldValue, so enableInitialize would not be triggered.

export default function App() {
  //const [test, setTest] = useState(null); // This removed
  return (
    <Formik
      enableReinitialize
      initialValues={{
        test: "",
        name: "",
        email: "",
        phone: ""
      }}
    >

...

 <button onClick={() => setFieldValue("test", "something")}>Update State</button>

Mostly the reason you would want to use states outside of Formik is to use it outside of Formik (ok clear), but this way you still can trigger a function from outside of Formik which you pass the values and the setFieldValue- Function to do whatever when triggered e.g. at onChange of a Formik field:

  const handlerDefinedOutside = (values: any, setFieldValue: (field: string, value: any, shouldValidate?: boolean) => void): void => { /* do stuff */ };

  <TextField
     onChange={(e) => {
       handleChange(e);
       handlerDefinedOutside(values, setFieldValue);
     }}
  />
发布评论

评论列表(0)

  1. 暂无评论