Returns a stateful value, and a function to update it.
- During initial render, returned state (
state) is the same as the value passed as first argument (
setStatefunction is used to update state
- Accepts a new state value
- Enqueues a re-render of the component
If the new state is computed using the previous state, you can pass a function to
The function will receive the previous value, and return an updated value. This counter component uses both forms of
- "+" and "-" use the functional form, because the updated value is based on the previous value.
- "Reset" uses the normal form, because it always sets the count back to the initial value.
initialState argument is the state used during the initial render.
- It is disregarded in subsequent renders
- Can be used if the initial state is the result of an expensive computation.
If you update a State Hook to the same value as the current state, React will bail out without rendering the children or firing effects. React may still need to render that specific component again before bailing out. If you're doing expensive calculations while rendering, you can optimize them with
Accepts a function that contains imperative, possibly effectful code.
Side effects not allowed inside the main body of a function component (React's render phase):
The function passed to
useEffect will run after the render is committed to the screen. By default, effects run after every completed render, but you can choose to fire them only when certain values have changed.
Often, effects create resources that need to be cleaned up before the component leaves the screen, such as a subscription or timer ID. To do this, the function passed to
useEffect may return a clean-up function. For example, to create a subscription:
The clean-up function runs before the component is removed from the UI to prevent memory leaks. If a component renders multiple times (as they typically do), the previous effect is cleaned up before executing the next effect, meaning a new subscription is created on every update.
componentDidUpdate, the function passed to
useEffect fires after layout and paint, during a deferred event. However, not all effects can be deferred. For these types of effects, React provides
It has the same signature as
useEffect, and only differs in when it is fired. Although
useEffect is deferred until after the browser has painted, it's guaranteed to fire before any new renders. React will always flush a previous render's effects before starting a new update.
Effects fire after every completed render to ensure they are always recreated if its dependencies changes. But in some cases, like the subscription example, we only need a new subscription if the
source prop has changed.
To implement this, pass a second argument to
useEffect that is the array of values that the effect depends on.
Now the subscription will only be recreated when
Make sure the array includes all values from the component scope (such as props and state) that change over time and that are used by the effect. Otherwise, your code will reference stale values from previous renders.
If you want to run an effect and clean it up only once (on mount and unmount), you can pass an empty array (
) as a second argument.
- This tells React that your effect doesn't depend on any values from props or state, so it never needs to re-run.
- This isn't handled as a special case -- it follows directly from how the dependencies array always works.
If you pass an empty array (
), the props and state inside the effect will always have their initial values.
- While passing
as the second argument is closer to the familiar
componentWillUnmountmental model, there are usually better solutions to avoid re-running effects too often.
- React defers running
useEffectuntil after the browser has painted, so doing extra work is less of a problem.
The array of dependencies is not passed as arguments to the effect function.
- Conceptually, though, that's what they represent
- Every value referenced inside the effect function should also appear in the dependencies array