Start here. This is the direct spoken answer to practice first.
Why this question matters
Moving code into a function does not automatically create a good hook. A useful hook gives one piece of stateful behavior a clear contract while preserving React's ownership and lifecycle rules.
A custom hook can combine state, effects, memoized callbacks, and other hooks behind a focused interface. Each call gets its own state; the hook shares behavior, not one global instance. I would extract a hook when several components need the same lifecycle logic or when one component becomes hard to read because a coherent behavior is mixed with rendering. The returned values and commands should describe the feature, such as data, status, retry, and cancel, rather than expose every internal setter.