Here is an example of a mutable ref storing the current callback from the Overreacted blog:
function useInterval(callback, delay) {
const savedCallback = useRef();
// update ref before 2nd effect
useEffect(() => {
savedCallback.current = callback; // save the callback in a mutable ref
});
useEffect(() => {
function tick() {
// can always access the most recent callback value without callback dep
savedCallback.current();
}
let id = setInterval(tick, delay);
return () => clearInterval(id);
}, [delay]);
}
However the React Hook FAQ states that the pattern is not recommended:
Also note that this pattern might cause problems in the concurrent mode. [...]
In either case, we don’t recommend this pattern and only show it here for completeness.
I found this pattern to be very useful in particular for callbacks and don't understand why it gets a red flag in the FAQ. For example, a client component can use useInterval
without needing to wrap useCallback
around the callback (simpler API).
Also there shouldn't be a problem in concurrent mode, as we update the ref inside useEffect
. From my point of view, the FAQ entry might have a wrong point here (or I have misunderstood it).
So, in summary:
- Does anything fundamentally speak against storing callbacks inside mutable refs?
- Is it safe in concurrent mode when done like it is in the above code, and if not, why not?
from Store a callback in useRef()
No comments:
Post a Comment