title: Is there any practical way to call `React.createContext()` within a component?
body: <p>Let's say I want to create a UI component for an "accordion" (a set of collapsible panels). The parent component controls the state of which panels are open, while the child panels should be able to read the context to determine whether or not they're open.</p>
  
  <pre><code>const Accordion = ({ children }) =&gt; {
    const [openSections, setOpenSections] = useState({})
  
    const isOpen = sectionId =&gt; Boolean(openSections[sectionId])
  
    const onToggle = sectionId =&gt; () =&gt;
      setOpenSections({ ...openSections, [sectionId]: !openSections[sectionId] })
  
    const context = useMemo(() =&gt; createContext(), [])
      // Can't tell children to use *this* context
  
    return (
      &lt;context.Provider value={useMemo(() =&gt; ({ isOpen, onToggle }), [isOpen, onToggle])}&gt;
        {children}
      &lt;/context.Provider&gt;
    )
  }
  
  const AccordionSection = ({ sectionId, title, children }) =&gt; {
    const { isOpen, onToggle } = useContext(context)
      // No way to infer the right context
  
    return (
      &lt;&gt;
        &lt;button onClick={onToggle(sectionId)}&gt;{isOpen(sectionId) ? 'Close' : 'Open'}&lt;/button&gt;
        {isOpen &amp;&amp; children}
      &lt;/&gt;
    )
  }
  </code></pre>
  
  <p>The only way I could think of accomplishing this would be to have <code>Accordion</code> run an effect whenever <code>children</code> changes, then traverse <code>children</code> deeply and find <code>AccordionSection</code> components, while not recursing any nested <code>Accordion</code> components -- then <code>cloneElement()</code> and inject <code>context</code> as a prop to each <code>AccordionSection</code>.</p>
  
  <p>This seems not only inefficient, but I'm not even entirely sure it will work. It depends on <code>children</code> being fully hydrated when the effect runs, which I'm not sure if that happens, and it also requires that <code>Accordion</code>'s renderer gets called whenever deep children change, which I'm not sure of either.</p>
  
  <p>My current method is to create a custom hook for the developer implementing the Accordion. The hook returns a function which returns the <code>isOpen</code> and <code>onToggle</code> functions which have to manually be passed to each rendered <code>AccordionSection</code>. It works and is possibly more elegant than the children solution, but requires more overhead as the developer needs to use a hook just to maintain what would otherwise be state encapsulated in <code>Accordion</code>.</p>