Formik: set value based on previous value

52 Views Asked by At

Is there a possibility to set a formik value based on the previous value?

Here a simple example:

  const onButtonClick = () =>{
    Array.from(Array(5).keys())
     .forEach((num) => formik.setFieldValue("testvalue", formik.values.testvalue + num));
    };
  }

The problem is, that if some functions run async parallel, we end up with a result, where only one num was added, instead of a sum of all.

In react's useState "Dispatch" we have the possibility to use a function as value, which has the previous item as parameter:

const [testValue, setTestvalue] = React.useState(false);
setTestvalue((prev) => prev + num)

So I would expect something like this with formik:

const onButtonClick = () =>{
    Array.from(Array(5).keys())
     .forEach((num) => formik.setFieldValue("testvalue", (prev) => prev + num));
    };
  }
1

There are 1 best solutions below

0
heiwil On BEST ANSWER

I ended up with a workaround, using a React state variable and React.useState's setter function.

If someone has a similar problem, here my simplified solution:

const [myValueList, setMyValueList] = React.useState<Array<MyType> | undefined>(undefined);

With following useEffect hook I synchronize the react value with the formik value, whenever the myValueList changes.

React.useEffect(() => {
  formik.setFieldValue("myFormikValueList", myValueList);    
 }, [myValueList]); // observe myValueList

And in my business logic somewhere I can set the react variable, which automatically will be synced by the useEffect hook above.

const myBusinessLogic (updateObject: MyType) => {
  // my logic
  setMyValueList(prev => prev ? [... prev, updateObject] : [updateObject])
}

I also created a Formik Feature Request, maybe it will be implemented.

This is just a simple example. In my case I am uploading images asynchronously. and want to update the uploading process of each element in my list. It ended up overwriting each other.