I've set a MUI Table with its last row containing a few TextFields as such (content stripped for readability) :
[Generated rows...]
<TableRow>
<TableCell component="th" scope="row">
<TextField/>
</TableCell> ...
<TableCell>
<Button variant="outlined" onClick={() => addFond()}>
<Add />
</Button>
</TableCell>
</TableRow>
Above rows are to be generated from an Array coming from a persistent storage state.
One row is to be added using the addFond()
button and function:
const addFond = () => {
userDefaults.assuranceVie ??= {}
userDefaults.assuranceVie.tableFondsVI ??= []
userDefaults.assuranceVie.tableFondsVI.push({ ...formik.values, id: uuidv4() })
setDefaults(userDefaults)
}
I'm using a Formik form for the new row, and would like to create a new formik row for all the iterated rows above the last one.
When clicking the addFond()
button, I expected the state to change and to rerender the whole component.
I have a console.log
printing the state at top-level of the component, but nothing prints when clicking.
Note that this Table component is embedded into an higher order tag.
After resolution edit :
I couldn't modify the state object and expect the change detection to work after using the setter since the state didn't actually change.
State change doesn't trigger rerender
There's no any state change, actually. The re-render is not triggered because the previous value of state is exactly the same as the new one, since you are mutating it.
userDefaults.assuranceVie ??= {}
-> state mutation.
You should base on the callback function of setState
to be sure you refer to the current state and you should return a new object to avoid mutation.
const addFond = () => {
setDefaults((prev) => ({
...prev,
assuranceVie: {
...(prev.assuranceVie || {}), // in case if not exists
tableFondsVI: [
...(prev.assuranceVie?.tableFondsVI || []),
{ ...formikValues, id: uuidv4() }
],
}
});
}