reactjsformik

Formik: set value based on previous value


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

Solution

  • 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.