In situations where you initialize useState
with some value and later on you want to update the state,
because the parent changed, you would need to currently listen on the parent change in an useeffect
and then set the state to update it, or more precisely, update the local version.
For this a hook I use quite often for forms or temporarily updated values is the useLocal
hook.
const RangeDatepicker = ({ value: { from, to }, onChange }) => {
const [from, setFrom] = useLocal(from)
const [to, setTo] = useLocal(to)
const update = () => {
if (from && to) {
onChange({ from, to });
}
}
useEffect(update, [from, to])
return <MyCalendarRangePicker from={from} to={to} onChangeFrom={setFrom} onChangeTo={setTo} />
}
- the controlling component sets from and to
- the RangeDatepicker copies the initial values
- On every change of the RangeDatepicker, locally values are updated, but not propagated back
- When both values (from and to) are set correctly, the onChange will be triggered
- the parent then updates the local values using the inner logic of useLocal
- the parent can always decide to override local values in a controlled manner
Note that the parent would always override the local version if it would be for example an object that is genreated on each render. So make sure, when you are creating computed values in an object, that the computed value must be memoized, when you are using this hook