> useState with an array with more than 1 component setting the state...
It sounds like you might be setting state by modifying the array and then calling the setter. This won't work:
array.push(thing)
setArray(array)
Instead, you have to update the array immutably, like setArray([...array, thing]).
> useCallback for event listeners
useEffect is usually the right place to set up event listeners (and has a built-in way of cleaning them up, by returning a cleanup function).
> Sometimes I want to return null before a hook.
Hooks pretty much have to be at the very top of the component, and eslint-ignore'ing those errors will probably cause weird issues later. Better to think about another way to solve the problem that doesn't involve returning early.
An issue I ran into recently: I had a modal Edit dialog with some form state that was initialized with the current values of the thing I wanted to edit. If that modal was always mounted and merely shown/hidden (), the state would be initialized once and wouldn't update when I changed the item-to-be-edited. The fix was to unmount the dialog, and only mount it when there was an item to edit, {itemToEdit && }