title: Managing focus within a compound component
body: <p>I have a compound component and I'd like to be able to use the up and down keys to navigate focus between the child components of a wrapper.</p>
  <p>I can do this by standard DOM manipulation - but it feels as though there ought to be a better way to do this with React. I'm guessing this would normally involve refs - but I can't see how such a solution would work. The code below shows a working way of solving this problem using DOM manipulation:</p>
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="true">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>const A = () =&gt; (
    &lt;button data-hook="a" style={{ display: "block", width: "100%" }}&gt;
      A
    &lt;/button&gt;
  );
  const B = () =&gt; (
    &lt;button data-hook="b" style={{ display: "block", width: "100%" }}&gt;
      B
    &lt;/button&gt;
  );
  
  const WrapperWithOnPress = (props) =&gt; {
    const handleKeyDown = (event) =&gt; {
      let index = null;
  
      const topLevel = event.target.closest('[data-hook="top-level"]');
  
      const allAChildren = Array.from(
        topLevel.querySelectorAll('[data-hook="a"]')
      );
  
      allAChildren.forEach((child, i) =&gt; {
        if (child === event.target) {
          index = i;
        }
      });
  
      console.log(index);
  
      let nextIndex = index;
  
      // up
      if (event.keyCode === 38) {
        nextIndex = Math.max(0, index - 1);
      }
  
      // down
      if (event.keyCode === 40) {
        nextIndex = Math.min(allAChildren.length - 1, index + 1);
      }
  
      allAChildren[nextIndex].focus();
    };
  
    return (
      &lt;div onKeyDown={handleKeyDown} data-hook="top-level"&gt;
        {props.children}
      &lt;/div&gt;
    );
  };
  
  function App() {
    return (
      &lt;div className="App"&gt;
        &lt;WrapperWithOnPress&gt;
          &lt;A /&gt;
          &lt;B /&gt;
          &lt;A /&gt;
          &lt;A /&gt;
        &lt;/WrapperWithOnPress&gt;
      &lt;/div&gt;
    );
  }
  
  
  ReactDOM.render(&lt;App /&gt;, document.getElementById('app'));</code></pre>
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"&gt;&lt;/script&gt;
  &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"&gt;&lt;/script&gt;
  
  &lt;div id="app"&gt;&lt;/div&gt;</code></pre>
  </div>
  </div>
  </p>
  <p>The main problem is that the wrapper of the compound component in question needs to be able to only move between certain types of component in the children - in my actual use case, this means moving between only header components when the up or down keys are pressed.</p>
  <p>Is there a way to do this sort of thing without manually reaching out to the DOM?</p>
  <p>I have heard that it is possible to do <code>child.type</code> where <code>child</code> is a react component. I've never previously used this, and it doesn't seem to work for this example for me.</p>
  <p><a href="https://codesandbox.io/s/dreamy-resonance-12rpc?file=/src/App.js:0-1233" rel="nofollow noreferrer">Here is the example if it helps.</a></p>