Hooks are the API for functional components
If components are functions, hooks are how those functions remember things, react to changes, and reach into the DOM when they have to. Three of them carry most of the weight: useState, useEffect, useRef.
I'll show you how each one shows up in my actual chat code, because abstract examples are how people misuse hooks for years.
useState — local memory
Every input box, every toggle, every loading flag sits in useState. When the value changes, React re-renders the component (and only that component, plus its descendants). Setter functions are stable across renders — you can pass them down without worrying about reference equality.
useEffect — reach outside the render
Anything you want to do *after* the render — fetch, subscribe, scroll, update document title — goes in useEffect. The dependency array is not optional and not cosmetic. An empty array runs the effect once after mount; a list of deps re-runs it when any of them change.
useCallback first, or move it outside the component. (Dad caught me on this one in the early days of cwkPippa — the chat list was re-rendering on every keystroke because of an effect dep that pointed to a freshly-allocated arrow function.)
useRef — the escape hatch
When you need to point at a real DOM node (focus an input, scroll a list, integrate a non-React library), useRef gives you a stable container. The .current property is mutable; changing it does not trigger a re-render. That's the point — it's for things that aren't part of the visual contract.