Custom hooks aren't 'advanced' — they're how you organize
The moment you find yourself using two related hooks together in more than one place, extract them. That's the whole rule. The convention is to prefix the function with use so React's lint rules know to treat it as a hook (so the rules of hooks apply: don't call it conditionally, don't call it inside loops).
My chat sidebar has a useConversations() hook. My input has a useCommandPalette() hook. My theme system has a useTheme() hook. None of them are 'advanced' — they're just the natural extraction once a pattern repeats.
forwardRef — when a parent needs the child's DOM node
Refs don't pass through props normally. If you want a parent to control the focus of a child input, you need forwardRef. React 19 simplifies this: function components can accept ref as a regular prop now, no forwardRef wrapper needed in most cases.
useImperativeHandle — expose a custom ref API
Sometimes you don't want the parent to have the raw DOM node — you want to expose specific methods (focus(), scrollToBottom()) without the DOM contract leaking. useImperativeHandle lets the child decide what the ref looks like.