useLocal: the useState hook for a properly-synced state
Lukas Klinzing
Posted on July 11, 2021
As you might know, the React hook useState
takes one argument, which will initialize its internal state to that given value. When React 16 with Hooks got released, I found it a little bit confusing, but it perfectly makes sense.
No matter what, there are still situations, where you need to update the state based on the incoming props. Usually that is done using a useEffect
hook, where you listen on the incoming prop to change, and then update your local state.
This is a great way of handling it, because you, as the owner of the component can perfectly control, if the parent prop change is actually what you want. It could even break your component if the parent decides to update a prop during a critical state of your component.
But there are also situations, where not much can happen. There are simple scenarios where you basically want to hold a local version and not propagate it up the tree until a certain condition happen. During that time, you still want to allow the parent controlling component to update the local value, if that is what it wants.
Here is an example how to allow the parent controlling component set (and update, if necessary) the from and to values. It can happen that for example for whatever reason, there is another component, that can set a date range, for that, we would want that from and to can be updated.
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 easiest implementation of such a hook (in Typscript) looks like this
One further improvement would be, to pass in some conditional function that checks, if it is allowed to update the local state.
You can visit the gist here
https://gist.github.com/theluk/13b7a17455b599699b7d34775cbf8273
Posted on July 11, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.