But here's the weirdness. useState knows whether it's already been called for a given component; this is how it tracks state. The first call returns the state (the initial value) and a setter. Subsequent calls -- occurring after the first render -- do not return these objects anew, but instead reach into a per-functional-component store and return the values that already exist there. Calling the setter doesn't set the state in the body; rather, it updates the value in the store, then triggers a re-render.
If you're wondering just how react knows how to match up calls to useState between renders, it doesn't really. It simply matches them up based on the order they're called in. For that reason, you have to always call exactly the same useState calls on each render -- no putting some in an if statement or a variable length for loop, otherwise they'll be out of sync.
There are a bunch of other "hooks" for use in functional components, but they all work basically the same way: place some data in the functional component's store, then set up re-render (which, again, just means calling the component's function again) to occur when certain data changes.