I've noticed a common and exceptionally useful pattern in React - a composition between a component and a purpose specific associated hook.
The state management for any select element is nearly always the same. We can abstract it into a nice hook called useOptions. The hook will be used in the component that renders the select element and exposes the currently selected value along with a change handler function.
We could end there and be content... but why stop. In the example above, the props, value and onChange, are effectively fixed and we have a component that is like a curried function that has been partially applied with those props. That partial application can be formalized into a ManagedSelect component:
Better! But now we have lost access to the selected value in the MyForm component. This works perfectly though for traditional forms that submit a POST request with a FormData object to a server (or a Remix/React Router 7 action function), but it won't work for forms that are highly dynamic with lots of client side interactions and perform the form submission via a client side function; the selected value needs to be exposed to the MyForm component for any number of tasks. Some common examples are:
Its as if we want the ManagedSelect component to have 2 return values, the JSX and the result of the useOptions hook the component invokes internally...