Reputation: 51
I'm often in a situation, where I like to have a reference (with useRef
) in sync with a state (with useState
). This is particularly useful inside stable callbacks to avoid unnecessary rerenders.
Currently I'm using this approach:
const [value, setValue] = useState(...)
const valueRef = useRef(value)
valueRef.current = value
I've seen code where the last line is wrapped in a useEffect
like
useEffect(() => {
valueRef.current = value
}, [value])
which looks more expensive as simply overwriting the previous value with the new one.
Is there a best practice for something like that? Or is the complete concept wrong?
Thanks in advance
Upvotes: 4
Views: 4638
Reputation: 13234
This has been called the "latest ref pattern". I've used it to keep a ref in sync with a prop, not state, but it's the same idea.
I believe the purpose of the useLayoutEffect (or useEffect) is because assigning to ref.current
doesn't play nicely with server-side rendering or the upcoming suspense mode. React assumes that component bodies do not have side effects, and assigning a ref's value is a side effect that React isn't guaranteed to preserve.
Upvotes: 5
Reputation: 13588
This is what I do by creating a custom function
const [ value, _setValue ] = useState(...)
const valueRef = useRef()
valueRef.current = value
const setValue = (arg) => {
valueRef.current = arg
_setValue(arg)
}
Upvotes: 2