What is the right way of using the useCallback and useState hooks in conjunction?
Sometimes we will want to wrap the useState hook with a useCallback hook.
The simple reason for that is to prevent a render cycle when passing the function as props (when the component receiving that prop is wrapped with
We must remember is that the
setState function must not be passed to the
useCallback dependency array. The React team suggests this:
"React guarantees that setState function identity is stable and won’t change on re-renders. This is why it’s safe to omit from the useEffect or useCallback dependency list."
const [isOpen, setIsOpen] = useState(false); const toggle = useCallback(() => setIsOpen(!isOpen), [isOpen]); // We don't have to pass the setState function.
But the example above is but practice. Why? Even though we are not passing the setState function, we must pass the
isOpen variable, as it is being used inside the
useCallback hook. This will cause the toggle function to be recreated every time the state changes.
You already know the solution, right?
We can use the callback function that receives the previous value and manipulate it. This way, we are not using variables from outside the useCallback function, and we can keep the dependency array nice and clean.
const [isOpen, setIsOpen] = useState(false); const toggle = useCallback(() => setIsOpen(prevState =>!prevState), );