--- id: hooks-reference title: Hooks API Reference permalink: docs/hooks-reference.html prev: hooks-custom.html next: hooks-faq.html --- *Hooks* are a new addition in React 16.8. They let you use state and other React features without writing a class. This page describes the APIs for the built-in Hooks in React. If you're new to Hooks, you might want to check out [the overview](/docs/hooks-overview.html) first. You may also find useful information in the [frequently asked questions](/docs/hooks-faq.html) section. - [Basic Hooks](#basic-hooks) - [`useState`](#usestate) - [`useEffect`](#useeffect) - [`useContext`](#usecontext) - [Additional Hooks](#additional-hooks) - [`useReducer`](#usereducer) - [`useCallback`](#usecallback) - [`useMemo`](#usememo) - [`useRef`](#useref) - [`useImperativeHandle`](#useimperativehandle) - [`useLayoutEffect`](#uselayouteffect) - [`useDebugValue`](#usedebugvalue) - [`useDeferredValue`](#usedeferredvalue) - [`useTransition`](#usetransition) - [`useId`](#useid) - [Library Hooks](#library-hooks) - [`useSyncExternalStore`](#usesyncexternalstore) - [`useInsertionEffect`](#useinsertioneffect) ## Basic Hooks {#basic-hooks} ### `useState` {#usestate} ```js const [state, setState] = useState(initialState); ``` Returns a stateful value, and a function to update it. During the initial render, the returned state (`state`) is the same as the value passed as the first argument (`initialState`). The `setState` function is used to update the state. It accepts a new state value and enqueues a re-render of the component. ```js setState(newState); ``` During subsequent re-renders, the first value returned by `useState` will always be the most recent state after applying updates. >Note > >React guarantees that `setState` function identity is stable and won't change on re-renders. This is why it's safe to omit from the `useEffect` or `useCallback` dependency list. #### Functional updates {#functional-updates} If the new state is computed using the previous state, you can pass a function to `setState`. The function will receive the previous value, and return an updated value. Here's an example of a counter component that uses both forms of `setState`: ```js function Counter({initialCount}) { const [count, setCount] = useState(initialCount); return ( <> Count: {count} ); } ``` The "+" and "-" buttons use the functional form, because the updated value is based on the previous value. But the "Reset" button uses the normal form, because it always sets the count back to the initial value. If your update function returns the exact same value as the current state, the subsequent rerender will be skipped completely. > Note > > Unlike the `setState` method found in class components, `useState` does not automatically merge update objects. You can replicate this behavior by combining the function updater form with object spread syntax: > > ```js > const [state, setState] = useState({}); > setState(prevState => { > // Object.assign would also work > return {...prevState, ...updatedValues}; > }); > ``` > > Another option is `useReducer`, which is more suited for managing state objects that contain multiple sub-values. #### Lazy initial state {#lazy-initial-state} The `initialState` argument is the state used during the initial render. In subsequent renders, it is disregarded. If the initial state is the result of an expensive computation, you may provide a function instead, which will be executed only on the initial render: ```js const [state, setState] = useState(() => { const initialState = someExpensiveComputation(props); return initialState; }); ``` #### Bailing out of a state update {#bailing-out-of-a-state-update} 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 uses the [`Object.is` comparison algorithm](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is#Description).) Note that React may still need to render that specific component again before bailing out. That shouldn't be a concern because React won't unnecessarily go "deeper" into the tree. If you're doing expensive calculations while rendering, you can optimize them with `useMemo`. #### Batching of state updates {#batching-of-state-updates} React may group several state updates into a single re-render to improve performance. Normally, this improves performance and shouldn't affect your application's behavior. Before React 18, only updates inside React event handlers were batched. Starting with React 18, [batching is enabled for all updates by default](/blog/2022/03/08/react-18-upgrade-guide.html#automatic-batching). Note that React makes sure that updates from several *different* user-initiated events -- for example, clicking a button twice -- are always processed separately and do not get batched. This prevents logical mistakes. In the rare case that you need to force the DOM update to be applied synchronously, you may wrap it in [`flushSync`](/docs/react-dom.html#flushsync). However, this can hurt performance so do this only where needed. ### `useEffect` {#useeffect} ```js useEffect(didUpdate); ``` Accepts a function that contains imperative, possibly effectful code. Mutations, subscriptions, timers, logging, and other side effects are not allowed inside the main body of a function component (referred to as React's _render phase_). Doing so will lead to confusing bugs and inconsistencies in the UI. Instead, use `useEffect`. The function passed to `useEffect` will run after the render is committed to the screen. Think of effects as an escape hatch from React's purely functional world into the imperative world. By default, effects run after every completed render, but you can choose to fire them [only when certain values have changed](#conditionally-firing-an-effect). #### Cleaning up an effect {#cleaning-up-an-effect} 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: ```js useEffect(() => { const subscription = props.source.subscribe(); return () => { // Clean up the subscription subscription.unsubscribe(); }; }); ``` The clean-up function runs before the component is removed from the UI to prevent memory leaks. Additionally, if a component renders multiple times (as they typically do), the **previous effect is cleaned up before executing the next effect**. In our example, this means a new subscription is created on every update. To avoid firing an effect on every update, refer to the next section. #### Timing of effects {#timing-of-effects} Unlike `componentDidMount` and `componentDidUpdate`, the function passed to `useEffect` fires **after** layout and paint, during a deferred event. This makes it suitable for the many common side effects, like setting up subscriptions and event handlers, because most types of work shouldn't block the browser from updating the screen. However, not all effects can be deferred. For example, a DOM mutation that is visible to the user must fire synchronously before the next paint so that the user does not perceive a visual inconsistency. (The distinction is conceptually similar to passive versus active event listeners.) For these types of effects, React provides one additional Hook called [`useLayoutEffect`](#uselayouteffect). It has the same signature as `useEffect`, and only differs in when it is fired. Additionally, starting in React 18, the function passed to `useEffect` will fire synchronously **before** layout and paint when it's the result of a discrete user input such as a click, or when it's the result of an update wrapped in [`flushSync`](/docs/react-dom.html#flushsync). This behavior allows the result of the effect to be observed by the event system, or by the caller of [`flushSync`](/docs/react-dom.html#flushsync). > Note > > This only affects the timing of when the function passed to `useEffect` is called - updates scheduled inside these effects are still deferred. This is different than [`useLayoutEffect`](#uselayouteffect), which fires the function and processes the updates inside of it immediately. Even in cases where `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. #### Conditionally firing an effect {#conditionally-firing-an-effect} The default behavior for effects is to fire the effect after every completed render. That way an effect is always recreated if one of its dependencies changes. However, this may be overkill in some cases, like the subscription example from the previous section. We don't need to create a new subscription on every update, only 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. Our updated example now looks like this: ```js useEffect( () => { const subscription = props.source.subscribe(); return () => { subscription.unsubscribe(); }; }, [props.source], ); ``` Now the subscription will only be recreated when `props.source` changes. >Note > >If you use this optimization, 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. Learn more about [how to deal with functions](/docs/hooks-faq.html#is-it-safe-to-omit-functions-from-the-list-of-dependencies) and what to do when the [array values change too often](/docs/hooks-faq.html#what-can-i-do-if-my-effect-dependencies-change-too-often). > >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 `componentDidMount` and `componentWillUnmount` mental model, there are usually [better](/docs/hooks-faq.html#is-it-safe-to-omit-functions-from-the-list-of-dependencies) [solutions](/docs/hooks-faq.html#what-can-i-do-if-my-effect-dependencies-change-too-often) to avoid re-running effects too often. Also, don't forget that React defers running `useEffect` until after the browser has painted, so doing extra work is less of a problem. > > >We recommend using the [`exhaustive-deps`](https://github.com/facebook/react/issues/14920) rule as part of our [`eslint-plugin-react-hooks`](https://www.npmjs.com/package/eslint-plugin-react-hooks#installation) package. It warns when dependencies are specified incorrectly and suggests a fix. 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. In the future, a sufficiently advanced compiler could create this array automatically. ### `useContext` {#usecontext} ```js const value = useContext(MyContext); ``` Accepts a context object (the value returned from `React.createContext`) and returns the current context value for that context. The current context value is determined by the `value` prop of the nearest `` above the calling component in the tree. When the nearest `` above the component updates, this Hook will trigger a rerender with the latest context `value` passed to that `MyContext` provider. Even if an ancestor uses [`React.memo`](/docs/react-api.html#reactmemo) or [`shouldComponentUpdate`](/docs/react-component.html#shouldcomponentupdate), a rerender will still happen starting at the component itself using `useContext`. Don't forget that the argument to `useContext` must be the *context object itself*: * **Correct:** `useContext(MyContext)` * **Incorrect:** `useContext(MyContext.Consumer)` * **Incorrect:** `useContext(MyContext.Provider)` A component calling `useContext` will always re-render when the context value changes. If re-rendering the component is expensive, you can [optimize it by using memoization](https://github.com/facebook/react/issues/15156#issuecomment-474590693). >Tip > >If you're familiar with the context API before Hooks, `useContext(MyContext)` is equivalent to `static contextType = MyContext` in a class, or to ``. > >`useContext(MyContext)` only lets you *read* the context and subscribe to its changes. You still need a `` above in the tree to *provide* the value for this context. **Putting it together with Context.Provider** ```js{31-36} const themes = { light: { foreground: "#000000", background: "#eeeeee" }, dark: { foreground: "#ffffff", background: "#222222" } }; const ThemeContext = React.createContext(themes.light); function App() { return ( ); } function Toolbar(props) { return (
); } function ThemedButton() { const theme = useContext(ThemeContext); return ( ); } ``` This example is modified for hooks from a previous example in the [Context Advanced Guide](/docs/context.html), where you can find more information about when and how to use Context. ## Additional Hooks {#additional-hooks} The following Hooks are either variants of the basic ones from the previous section, or only needed for specific edge cases. Don't stress about learning them up front. ### `useReducer` {#usereducer} ```js const [state, dispatch] = useReducer(reducer, initialArg, init); ``` An alternative to [`useState`](#usestate). Accepts a reducer of type `(state, action) => newState`, and returns the current state paired with a `dispatch` method. (If you're familiar with Redux, you already know how this works.) `useReducer` is usually preferable to `useState` when you have complex state logic that involves multiple sub-values or when the next state depends on the previous one. `useReducer` also lets you optimize performance for components that trigger deep updates because [you can pass `dispatch` down instead of callbacks](/docs/hooks-faq.html#how-to-avoid-passing-callbacks-down). Here's the counter example from the [`useState`](#usestate) section, rewritten to use a reducer: ```js const initialState = {count: 0}; function reducer(state, action) { switch (action.type) { case 'increment': return {count: state.count + 1}; case 'decrement': return {count: state.count - 1}; default: throw new Error(); } } function Counter() { const [state, dispatch] = useReducer(reducer, initialState); return ( <> Count: {state.count} ); } ``` >Note > >React guarantees that `dispatch` function identity is stable and won't change on re-renders. This is why it's safe to omit from the `useEffect` or `useCallback` dependency list. #### Specifying the initial state {#specifying-the-initial-state} There are two different ways to initialize `useReducer` state. You may choose either one depending on the use case. The simplest way is to pass the initial state as a second argument: ```js{3} const [state, dispatch] = useReducer( reducer, {count: initialCount} ); ``` >Note > >React doesn’t use the `state = initialState` argument convention popularized by Redux. The initial value sometimes needs to depend on props and so is specified from the Hook call instead. If you feel strongly about this, you can call `useReducer(reducer, undefined, reducer)` to emulate the Redux behavior, but it's not encouraged. #### Lazy initialization {#lazy-initialization} You can also create the initial state lazily. To do this, you can pass an `init` function as the third argument. The initial state will be set to `init(initialArg)`. It lets you extract the logic for calculating the initial state outside the reducer. This is also handy for resetting the state later in response to an action: ```js{1-3,11-12,19,24} function init(initialCount) { return {count: initialCount}; } function reducer(state, action) { switch (action.type) { case 'increment': return {count: state.count + 1}; case 'decrement': return {count: state.count - 1}; case 'reset': return init(action.payload); default: throw new Error(); } } function Counter({initialCount}) { const [state, dispatch] = useReducer(reducer, initialCount, init); return ( <> Count: {state.count} ); } ``` #### Bailing out of a dispatch {#bailing-out-of-a-dispatch} If you return the same value from a Reducer Hook as the current state, React will bail out without rendering the children or firing effects. (React uses the [`Object.is` comparison algorithm](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is#Description).) Note that React may still need to render that specific component again before bailing out. That shouldn't be a concern because React won't unnecessarily go "deeper" into the tree. If you're doing expensive calculations while rendering, you can optimize them with `useMemo`. ### `useCallback` {#usecallback} ```js const memoizedCallback = useCallback( () => { doSomething(a, b); }, [a, b], ); ``` Returns a [memoized](https://en.wikipedia.org/wiki/Memoization) callback. Pass an inline callback and an array of dependencies. `useCallback` will return a memoized version of the callback that only changes if one of the dependencies has changed. This is useful when passing callbacks to optimized child components that rely on reference equality to prevent unnecessary renders (e.g. `shouldComponentUpdate`). `useCallback(fn, deps)` is equivalent to `useMemo(() => fn, deps)`. > Note > > The array of dependencies is not passed as arguments to the callback. Conceptually, though, that's what they represent: every value referenced inside the callback should also appear in the dependencies array. In the future, a sufficiently advanced compiler could create this array automatically. > > We recommend using the [`exhaustive-deps`](https://github.com/facebook/react/issues/14920) rule as part of our [`eslint-plugin-react-hooks`](https://www.npmjs.com/package/eslint-plugin-react-hooks#installation) package. It warns when dependencies are specified incorrectly and suggests a fix. ### `useMemo` {#usememo} ```js const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]); ``` Returns a [memoized](https://en.wikipedia.org/wiki/Memoization) value. Pass a "create" function and an array of dependencies. `useMemo` will only recompute the memoized value when one of the dependencies has changed. This optimization helps to avoid expensive calculations on every render. Remember that the function passed to `useMemo` runs during rendering. Don't do anything there that you wouldn't normally do while rendering. For example, side effects belong in `useEffect`, not `useMemo`. If no array is provided, a new value will be computed on every render. **You may rely on `useMemo` as a performance optimization, not as a semantic guarantee.** In the future, React may choose to "forget" some previously memoized values and recalculate them on next render, e.g. to free memory for offscreen components. Write your code so that it still works without `useMemo` — and then add it to optimize performance. > Note > > The array of dependencies is not passed as arguments to the function. Conceptually, though, that's what they represent: every value referenced inside the function should also appear in the dependencies array. In the future, a sufficiently advanced compiler could create this array automatically. > > We recommend using the [`exhaustive-deps`](https://github.com/facebook/react/issues/14920) rule as part of our [`eslint-plugin-react-hooks`](https://www.npmjs.com/package/eslint-plugin-react-hooks#installation) package. It warns when dependencies are specified incorrectly and suggests a fix. ### `useRef` {#useref} ```js const refContainer = useRef(initialValue); ``` `useRef` returns a mutable ref object whose `.current` property is initialized to the passed argument (`initialValue`). The returned object will persist for the full lifetime of the component. A common use case is to access a child imperatively: ```js function TextInputWithFocusButton() { const inputEl = useRef(null); const onButtonClick = () => { // `current` points to the mounted text input element inputEl.current.focus(); }; return ( <> ); } ``` Essentially, `useRef` is like a "box" that can hold a mutable value in its `.current` property. You might be familiar with refs primarily as a way to [access the DOM](/docs/refs-and-the-dom.html). If you pass a ref object to React with `
`, React will set its `.current` property to the corresponding DOM node whenever that node changes. However, `useRef()` is useful for more than the `ref` attribute. It's [handy for keeping any mutable value around](/docs/hooks-faq.html#is-there-something-like-instance-variables) similar to how you'd use instance fields in classes. This works because `useRef()` creates a plain JavaScript object. The only difference between `useRef()` and creating a `{current: ...}` object yourself is that `useRef` will give you the same ref object on every render. Keep in mind that `useRef` *doesn't* notify you when its content changes. Mutating the `.current` property doesn't cause a re-render. If you want to run some code when React attaches or detaches a ref to a DOM node, you may want to use a [callback ref](/docs/hooks-faq.html#how-can-i-measure-a-dom-node) instead. ### `useImperativeHandle` {#useimperativehandle} ```js useImperativeHandle(ref, createHandle, [deps]) ``` `useImperativeHandle` customizes the instance value that is exposed to parent components when using `ref`. As always, imperative code using refs should be avoided in most cases. `useImperativeHandle` should be used with [`forwardRef`](/docs/react-api.html#reactforwardref): ```js function FancyInput(props, ref) { const inputRef = useRef(); useImperativeHandle(ref, () => ({ focus: () => { inputRef.current.focus(); } })); return ; } FancyInput = forwardRef(FancyInput); ``` In this example, a parent component that renders `` would be able to call `inputRef.current.focus()`. ### `useLayoutEffect` {#uselayouteffect} The signature is identical to `useEffect`, but it fires synchronously after all DOM mutations. Use this to read layout from the DOM and synchronously re-render. Updates scheduled inside `useLayoutEffect` will be flushed synchronously, before the browser has a chance to paint. Prefer the standard `useEffect` when possible to avoid blocking visual updates. > Tip > > If you're migrating code from a class component, note `useLayoutEffect` fires in the same phase as `componentDidMount` and `componentDidUpdate`. However, **we recommend starting with `useEffect` first** and only trying `useLayoutEffect` if that causes a problem. > >If you use server rendering, keep in mind that *neither* `useLayoutEffect` nor `useEffect` can run until the JavaScript is downloaded. This is why React warns when a server-rendered component contains `useLayoutEffect`. To fix this, either move that logic to `useEffect` (if it isn't necessary for the first render), or delay showing that component until after the client renders (if the HTML looks broken until `useLayoutEffect` runs). > >To exclude a component that needs layout effects from the server-rendered HTML, render it conditionally with `showChild && ` and defer showing it with `useEffect(() => { setShowChild(true); }, [])`. This way, the UI doesn't appear broken before hydration. ### `useDebugValue` {#usedebugvalue} ```js useDebugValue(value) ``` `useDebugValue` can be used to display a label for custom hooks in React DevTools. For example, consider the `useFriendStatus` custom Hook described in ["Building Your Own Hooks"](/docs/hooks-custom.html): ```js{6-8} function useFriendStatus(friendID) { const [isOnline, setIsOnline] = useState(null); // ... // Show a label in DevTools next to this Hook // e.g. "FriendStatus: Online" useDebugValue(isOnline ? 'Online' : 'Offline'); return isOnline; } ``` > Tip > > We don't recommend adding debug values to every custom Hook. It's most valuable for custom Hooks that are part of shared libraries. #### Defer formatting debug values {#defer-formatting-debug-values} In some cases formatting a value for display might be an expensive operation. It's also unnecessary unless a Hook is actually inspected. For this reason `useDebugValue` accepts a formatting function as an optional second parameter. This function is only called if the Hooks are inspected. It receives the debug value as a parameter and should return a formatted display value. For example a custom Hook that returned a `Date` value could avoid calling the `toDateString` function unnecessarily by passing the following formatter: ```js useDebugValue(date, date => date.toDateString()); ``` ### `useDeferredValue` {#usedeferredvalue} ```js const deferredValue = useDeferredValue(value); ``` `useDeferredValue` accepts a value and returns a new copy of the value that will defer to more urgent updates. If the current render is the result of an urgent update, like user input, React will return the previous value and then render the new value after the urgent render has completed. This hook is similar to user-space hooks which use debouncing or throttling to defer updates. The benefits to using `useDeferredValue` is that React will work on the update as soon as other work finishes (instead of waiting for an arbitrary amount of time), and like [`startTransition`](/docs/react-api.html#starttransition), deferred values can suspend without triggering an unexpected fallback for existing content. #### Memoizing deferred children {#memoizing-deferred-children} `useDeferredValue` only defers the value that you pass to it. If you want to prevent a child component from re-rendering during an urgent update, you must also memoize that component with [`React.memo`](/docs/react-api.html#reactmemo) or [`React.useMemo`](/docs/hooks-reference.html#usememo): ```js function Typeahead() { const query = useSearchQuery(''); const deferredQuery = useDeferredValue(query); // Memoizing tells React to only re-render when deferredQuery changes, // not when query changes. const suggestions = useMemo(() => , [deferredQuery] ); return ( <> {suggestions} ); } ``` Memoizing the children tells React that it only needs to re-render them when `deferredQuery` changes and not when `query` changes. This caveat is not unique to `useDeferredValue`, and it's the same pattern you would use with similar hooks that use debouncing or throttling. ### `useTransition` {#usetransition} ```js const [isPending, startTransition] = useTransition(); ``` Returns a stateful value for the pending state of the transition, and a function to start it. `startTransition` lets you mark updates in the provided callback as transitions: ```js startTransition(() => { setCount(count + 1); }); ``` `isPending` indicates when a transition is active to show a pending state: ```js function App() { const [isPending, startTransition] = useTransition(); const [count, setCount] = useState(0); function handleClick() { startTransition(() => { setCount(c => c + 1); }); } return (
{isPending && }
); } ``` > Note: > > Updates in a transition yield to more urgent updates such as clicks. > > Updates in a transition will not show a fallback for re-suspended content. This allows the user to continue interacting with the current content while rendering the update. ### `useId` {#useid} ```js const id = useId(); ``` `useId` is a hook for generating unique IDs that are stable across the server and client, while avoiding hydration mismatches. > Note > > `useId` is **not** for generating [keys in a list](/docs/lists-and-keys.html#keys). Keys should be generated from your data. For a basic example, pass the `id` directly to the elements that need it: ```js function Checkbox() { const id = useId(); return ( <> ); }; ``` For multiple IDs in the same component, append a suffix using the same `id`: ```js function NameFields() { const id = useId(); return (
); } ``` > Note: > > `useId` generates a string that includes the `:` token. This helps ensure that the token is unique, but is not supported in CSS selectors or APIs like `querySelectorAll`. > > `useId` supports an `identifierPrefix` to prevent collisions in multi-root apps. To configure, see the options for [`hydrateRoot`](/docs/react-dom-client.html#hydrateroot) and [`ReactDOMServer`](/docs/react-dom-server.html). ## Library Hooks {#library-hooks} The following Hooks are provided for library authors to integrate libraries deeply into the React model, and are not typically used in application code. ### `useSyncExternalStore` {#usesyncexternalstore} ```js const state = useSyncExternalStore(subscribe, getSnapshot[, getServerSnapshot]); ``` `useSyncExternalStore` is a hook recommended for reading and subscribing from external data sources in a way that's compatible with concurrent rendering features like selective hydration and time slicing. This method returns the value of the store and accepts three arguments: - `subscribe`: function to register a callback that is called whenever the store changes. - `getSnapshot`: function that returns the current value of the store. - `getServerSnapshot`: function that returns the snapshot used during server rendering. The most basic example simply subscribes to the entire store: ```js const state = useSyncExternalStore(store.subscribe, store.getSnapshot); ``` However, you can also subscribe to a specific field: ```js const selectedField = useSyncExternalStore( store.subscribe, () => store.getSnapshot().selectedField, ); ``` When server rendering, you must serialize the store value used on the server, and provide it to `useSyncExternalStore`. React will use this snapshot during hydration to prevent server mismatches: ```js const selectedField = useSyncExternalStore( store.subscribe, () => store.getSnapshot().selectedField, () => INITIAL_SERVER_SNAPSHOT.selectedField, ); ``` > Note: > > `getSnapshot` must return a cached value. If getSnapshot is called multiple times in a row, it must return the same exact value unless there was a store update in between. > > A shim is provided for supporting multiple React versions published as `use-sync-external-store/shim`. This shim will prefer `useSyncExternalStore` when available, and fallback to a user-space implementation when it's not. > > As a convenience, we also provide a version of the API with automatic support for memoizing the result of getSnapshot published as `use-sync-external-store/with-selector`. ### `useInsertionEffect` {#useinsertioneffect} ```js useInsertionEffect(didUpdate); ``` The signature is identical to `useEffect`, but it fires synchronously _before_ all DOM mutations. Use this to inject styles into the DOM before reading layout in [`useLayoutEffect`](#uselayouteffect). Since this hook is limited in scope, this hook does not have access to refs and cannot schedule updates. > Note: > > `useInsertionEffect` should be limited to css-in-js library authors. Prefer [`useEffect`](#useeffect) or [`useLayoutEffect`](#uselayouteffect) instead.