Omama Zainab
Omama Zainab

Reputation: 880

How to set all formik values at once?

I have a formik form for editing data which comes from an API endpoint,currently I am re-initializing the values in a useEffect hook like this

React.useEffect(() => {
    initialValues.first_name = address?.first_name;
    initialValues.last_name = address?.last_name;
    initialValues.middle_name = address?.middle_name;
    initialValues.label = address?.label;
    initialValues.description = address?.description;
  }, [address, initialValues]);

since the form has many values the useEffect hook gets lengthy and does not look clean either, I am trying to find a way to do it in a single line so it does not get a giant piece of code.

Upvotes: 5

Views: 20014

Answers (4)

omzer
omzer

Reputation: 1598

If you want to set few values at the top level, then setValues is sufficient:

setValues({ age: 12, name: "omar"})

However, things get complicated if your key is something like this array.0.nested.object, on such situation formik's setIn comes in handy:

let newValues = { ...values }; / Clone the previous values to prevent mutation

newValues = setIn(newValues, 'array.0.nested.object', "new value");
newValues = setIn(newValues, 'array.0.other.object', "other value");

setValues(newValues);

This will do all the changes to the state, while only doing one re-render to the components

Upvotes: 0

Keval Goyani
Keval Goyani

Reputation: 21

You can do this by adding setValues prop by passing object as argument.

Solution:

useEffect(() => {
     formik.setValues({
        first_name: address?.first_name,
        last_name: address?.last_name,
        middle_name: address?.middle_name,
        label: address?.label,
        description: address?.description
      });
  }, ["ADD YOUR DEPENDENCY"]);

Upvotes: 2

Omama Zainab
Omama Zainab

Reputation: 880

so it worked when I used formik.setValues, since it returns a promise so I put it in an asynchronous function. formik.setValues

  React.useEffect(() => {
    async function setInitialValues() {
      if (address) await formik.setValues(address, false);
    }
    setInitialValues();

    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [address]);

Upvotes: 3

screw spike
screw spike

Reputation: 411

It‘s my idea of this question ,you can use the pick from ramda,and when the fromfield add new column you just need to push the label to the formDataLabels, I hope it may work for you.

import {pick} from 'ramda';

// ... 

React.useEffect(() => {
    const formDataLabels = ['first_name', 'last_name', 'middle_name', 'label', 'description'];
    const updateData = pick(formDataLabels, address);
    initialValues = {
        ...initialValues,
        ...updateData,
    };
}, [address, initialValues]);

Upvotes: 1

Related Questions