I have a react form with a list of "subform" as react component. I want to update the "global" form value from those child component.
One of my child component looks like that :
function ForecastForADay(props: any) {
const { formValue, setFormValue } = useContext(FormContext)
return (
<>
...
<input
type="number"
placeholder="0"
className="form-control w-10"
onChange={(x) =>
setFormValue((oldVal: Forecasts) => {
var nVal = oldVal
;(nVal[props.objField as keyof Forecasts] as SingleForecast).temperatureMin = parseInt(x.target.value)
return nVal
})
}
></input>
...
</>
)
}
As you can see I use a context for the whole form value (cause there’s multiple layers of component). My issue is that in the onChange
function, it modify all the fields of the nVal object instead of only modifying porps.objField
.
props.objField
as the correct value which corespond to a field’s name.
Do you have any idea why this behaviour occurs?
>Solution :
The issue you are experiencing is related to object mutability in JavaScript. When you write var nVal = oldVal
, you are creating a reference to the same object that is stored in oldVal
. Therefore, any changes made to nVal will also affect oldVal
. In other words, both oldVal
and nVal
are pointing to the same object in memory.
To avoid this issue, you should create a copy of the object before modifying it. One way to achieve this is by using the spread operator (…) to create a shallow copy of the object.
Change setFormValue
as:
setFormValue((oldVal: Forecasts) => {
const nVal = { ...oldVal }; // Create a shallow copy of the object
nVal[props.objField as keyof Forecasts] = {
...nVal[props.objField as keyof Forecasts], // Create a shallow copy of the nested object
temperatureMin: parseInt(x.target.value)
};
return nVal;
});