Reputation: 880
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
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
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
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
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