I'm following an Advanced React Patterns with Hooks online course and there's this early example in which they create an Expandable component (say the classic accordion or collapsible panels) with the following API:
<Expandable>
    <Expandable.Header>This is the header</Expandable.Header>
    <Expandable.Body>This is the content</Expandable.Body>
</Expandable>
And they're using Context to pass the state expanded to Expandable's children. So far so good:
import React, { createContext, useState } from 'react'
const ExpandableContext = createContext()
const { Provider } = ExpandableContext
const Expandable = ({children}) => {
  const [expanded, setExpanded] = useState(false)
  const toggle = setExpanded(prevExpanded => !prevExpanded)
  return <Provider>{children}</Provider>
}
export default Expandable
But then they say:
toggleacts as a callback function and it’ll eventually be invoked byExpandable.Header. Let’s prevent any future performance issues by memoizing the callback
const toggle = useCallback(
    () => setExpanded(prevExpanded => !prevExpanded),
    []
)
This confuses me because according to the docs useCallback will return a memoized version of the callback that only changes if one of the dependencies has changed. But toggle doesn't have any dependencies, and still it produces a different result (setting expanded state to true or false alternatively) every time.
So, what's the point of this? What am I missing?
When the state in Expandable component will be updated, Expandable component will re-render. This will cause the toggle function to be re-created.
To prevent this, it is wrapped in useCallback hook so that toggle function is not recreated unnecessarily across re-renders.
useCallback hook is used to memoize callbacks that are passed as props to child components. This can help avoid unnecessary execution of useEffect hook or any other code that depends on referential identity of the callback function passed as a prop from the parent component.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With