Hacker News new | ask | show | jobs
by cheald 781 days ago
AFAIK, the "use" convention is just a convention used to indicate that you're dealing with something that is plugged into React's state management system, and is going to deal with some kind of state change that can cause component re-renders.

It's helpful to remember that functional components are, well, just functions, which on their own don't have any way to preserve their own state without resorting to some kind of global state store. Unlike object instances, which can have members which keep their state across invocations to instance.render(), functional components are just functions which receive props and return something (usually a React.createElement invocation, often disguised with JSX). Since they don't inherently have any way to preserve state, React provides functions to manage state and to trigger re-renders of components. This is what hooks are - they're global functions which manage updating a global state dict behind the scenes, and triggering re-renders when state changes.

* useState declares a stateful variable which is preserved across renders, and a mutator function which is used to update that variable (in the global state dict) and cause React to perform a re-render of any components which depend on that variable.

* useEffect would probably be better named "useSideEffect", since its purpose is to run a callback as a side effect of one of its declared dependencies changing. It is a little overloaded, in that it can run its callback as an effect of: 1. The component initially mounting, 2. the component unmounting, or 3. one of the declared dependencies changing value.

* useMemo is kind of a combination of useState and useEffect, which declares a stateful variable that is preserved across component renders (the memoized value) and uses a generator function to regenerate and save a new version of that variable when a declared dependency changes.

* useCallback can be thought of as a specialized case of useMemo which returns a memoized function.

Essentially all hooks are built on these four (and really, just useState and useEffect, since useMemo and useCallback are trivial derivations from those two).

It's helpful to think about react state as eventual and to treat it as immutable, and to think of components as truly functional constructs, which should just receive external input and return an output. It may be helpful to think of useState values as nothing more than additional values passed to the function by React when it invokes them. When you update state (or run an effect) you aren't changing things in this invocation of the component, you're changing things for the next invocation for the component (and queueing a reinvocation).

Imagine that you have a declared hook `[someState, setSomeState] = useState();`

Calling `setSomeState(val)` doesn't change the value of `someState`, which you should treat as an immutable variable. Instead, it updates the value of `globalStateDict[currentComponentIdentifier]["someState"] = val` and tells React to queue a re-render of this component. React dutifully re-invokes the function, and the second time it's run, the local `someState` variable receives its value from the React-managed global state, which is now `val`.

1 comments

useEffect is best thought of as a synchronization mechanism between external state and react state and the function it returns may actually be better thought of as a side effect. UseEffect makes sense in this case because you aren’t on the side!