title: Filtered list: how best to keep keyboard nav in sync with the list as rendered?
body: <p>I'm building out keyboard navigation for a composable React combobox component. As it stands, it works <em>except</em> when the visible list of options is filtered down to match text field input. I'm using <code>React.Children</code> in the callback below to build an array corresponding to my options list; this works well on initialization, but after filtering (and re-rendering the options that match the filter) the result when I call it still includes all items, rendered or not, with the props they initially had. (I had the &quot;bright idea&quot; of giving unrendered children a tabindex of -2 and filtering that way, but this only works if the values are updated...)</p>
  <ul>
  <li>Is there a better way than <code>React.Children</code> to populate my array of IDs and values/labels for my options, and to update it based on what was most recently rendered?</li>
  <li>If so, where could I learn about it?</li>
  <li>If not:
  <ul>
  <li>how can I access the current state, rather than a stale one?</li>
  <li>what's the best way of pointing to the specific children in question? The method I'm using looks brittle.</li>
  </ul>
  </li>
  </ul>
  <pre><code>const updateOptions = useCallback(
      () =&gt;
        // set the optionStateMap from children
        React.Children.forEach(children, child =&gt; {
          if (!React.isValidElement(child)) return;
          if (!child.props.children) return;
          const optionsArray: Array&lt;optionStateProps&gt; = [];
          child.props.children[0].forEach( // will break if my list is not the first child with children; d'oh
            (option: { props: { id: string; label: string, tabIndex: number} }) =&gt; {
              if (option.props.tabIndex &lt; -1) return;
              optionsArray.push({
                id: option.props.id,
                label: option.props.label
              });
            }
          );
          setOptionStateMap(optionsArray);
        }),
      [children]
    );
  </code></pre>
  <p>Thanks for looking!</p>