new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

React · API reference · all subjects

react/hooks

241 notes in this subject, read out of this brain and free to use. This is page 1 of 5.

useEffect with function created inside Effect

Avoid using a function created during rendering as a dependency. Instead, declare it inside the Effect. This prevents the Effect from re-running on every commit due to function identity changes.

Displaying different content on client vs server in Effects

In server-rendered apps, use an Effect with useState to display different content on client. For example, initialize didMount state to false, then in the Effect set it to true. This triggers a re-render with client-only content since Effects don't run on the server. Use sparingly as users on slow connections see the initial content for extended time.

useEffect with async/await and cleanup

When using async/await in an Effect, wrap it in a helper function because the Effect cannot be async itself. Still provide a cleanup function that sets an ignore flag to prevent updates after unmounting: ```js useEffect(() => { async function startFetching() { setBio(null); const result = await fetchBio(person); if (!ignore) { setBio(result); } } let ignore = false; startFetching(); return () => { ignore = true; } }, [person]); ```

Suppressing eslint-plugin-react-hooks/exhaustive-deps is risky

When dependencies don't match the code, there is a high risk of introducing bugs. Suppressing the linter with eslint-ignore-next-line lies to React about the values the Effect depends on. Instead, prove the dependencies are unnecessary by refactoring the code.

useEffectEvent for reading latest props without reacting

Use useEffectEvent Hook to create an Effect Event for code that reads the latest props and state without reacting to changes. Declare the Effect Event inside the component, move non-reactive code into it, then call it from your Effect. Effect Events must always be omitted from Effect dependencies.

useEffect return value

useEffect returns undefined.

useEffect dependencies array rules

The dependencies list must have a constant number of items and be written inline like [dep1, dep2, dep3]. React compares each dependency with its previous value using Object.is comparison. If you omit the dependencies argument, the Effect re-runs after every commit. If you pass an empty array [], the Effect runs only once after the component mounts. If you pass a dependency array with values, the Effect runs after the initial mount and after each commit where dependencies changed.

useEffect example: connecting to external system

Example connecting a ChatRoom component to a chat service: ```js import { useState, useEffect } from 'react'; import { createConnection } from './chat.js'; function ChatRoom({ roomId }) { const [serverUrl, setServerUrl] = useState('https://localhost:1234'); useEffect(() => { const connection = createConnection(serverUrl, roomId); connection.connect(); return () => { connection.disconnect(); }; }, [serverUrl, roomId]); // ... } ``` This shows a setup function that creates and connects to a chat room, and a cleanup function that disconnects, with both serverUrl and roomId as dependencies.

Object and function dependencies cause unnecessary reruns

If some dependencies are objects or functions defined inside the component, there is a risk that they will cause the Effect to re-run more often than needed. To fix this, remove unnecessary object and function dependencies. You can move them inside the Effect, use state updaters instead of state values, or declare Effect Events with useEffectEvent.

useEffect hook signature

useEffect(setup, dependencies?) is the React Hook that lets you synchronize a component with an external system. The setup parameter is a function containing the Effect's logic that may optionally return a cleanup function. The dependencies parameter is optional and is a list of all reactive values referenced inside the setup code.

useEffect for data fetching with race condition prevention

When fetching data in an Effect, create an ignore flag initialized to false and set it to true in the cleanup function. Check the flag before updating state with the response to prevent race conditions where network responses arrive out of order: ```js let ignore = false; fetchBio(person).then(result => { if (!ignore) { setBio(result); } }); return () => { ignore = true; }; ```

useEffect vs useLayoutEffect

If an Effect is not caused by an interaction, React generally lets the browser paint the updated screen first before running the Effect. If the Effect is doing something visual and the delay is noticeable, replace useEffect with useLayoutEffect. If the Effect is caused by an interaction like a click, React may run the Effect before the browser paints the updated screen to ensure the result can be observed by the event system.

Reactive values in components

Reactive values include props, state, and all variables and functions declared directly inside your component body. These must be specified as dependencies if referenced inside the setup code. If your linter is configured for React, it will verify that every reactive value is correctly specified as a dependency.

useEffect setup function timing

When a component commits, React runs the setup function. After every commit with changed dependencies, React first runs the cleanup function with old values, then runs the setup function with new values. After the component is removed from the DOM, React runs the cleanup function one final time.

useEffect with state updater function

When updating state based on previous state inside an Effect, pass a state updater function instead of the current value. For example, use setCount(c => c + 1) instead of setCount(count + 1). This removes the need to include the state variable as a dependency, preventing unnecessary Effect reruns.

useId requires identical server and client tree

With server rendering, useId requires an identical component tree on the server and the client. If the trees you render on the server and the client don't match exactly, the generated IDs won't match.

useId should not be used for list keys

useId should not be used to generate keys in a list. Keys should be generated from your data.

useId not available in async Server Components

useId currently cannot be used in async Server Components.

useId hook signature and return value

useId is a React Hook that generates unique IDs for accessibility attributes. It takes no parameters and returns a unique ID string associated with that particular useId call in that particular component.

useId must be called at top level

useId is a Hook and can only be called at the top level of your component or your own Hooks. It cannot be called inside loops or conditions. If you need conditional IDs, extract a new component and move the state into it.

useId prefix for multiple related elements

You can call useId once to generate a shared prefix for multiple related elements. For example: const id = useId(); then use id + '-firstName' and id + '-lastName' for different elements. This avoids calling useId for every single element that needs a unique ID.

useId works with server rendering via parent path

useId is better than an incrementing counter for server rendering because React generates the ID from the 'parent path' of the calling component. This ensures that if the client and server component trees are identical, the parent paths will match regardless of rendering order, making hydration work correctly and output match between server and client.

useId for accessibility attributes example

Example showing useId for accessibility: import { useId } from 'react'; function PasswordField() { const passwordHintId = useId(); return ( <> <label> Password: <input type="password" aria-describedby={passwordHintId} /> </label> <p id={passwordHintId}> The password should contain at least 18 characters </p> </> ); } This ensures unique IDs even when PasswordField is rendered multiple times.

useId should not be used for cache keys

useId should not be used to generate cache keys for use(). The ID is stable when a component is mounted but may change during rendering. Cache keys should be generated from your data.

useImperativeHandle pitfall - overuse of refs

Do not overuse refs. You should only use refs for imperative behaviors that cannot be expressed as props, such as scrolling to a node, focusing a node, triggering an animation, or selecting text. If something can be expressed as a prop, you should not use a ref. For example, instead of exposing an imperative handle like { open, close } from a Modal component, take isOpen as a prop like <Modal isOpen={isOpen} />.

useImperativeHandle dependencies list

The dependencies array is optional but must have a constant number of items and be written inline like [dep1, dep2, dep3]. If omitted, createHandle will re-execute on every render. React compares each dependency with its previous value using Object.is.

React 19 ref as prop

Starting with React 19, ref is available as a prop to components. In React 18 and earlier, it was necessary to get the ref from forwardRef.

useImperativeHandle call location

useImperativeHandle must be called at the top level of your component to customize the ref handle it exposes.

useImperativeHandle custom composite methods example

This example shows a Post component exposing a custom scrollAndFocusAddComment method that combines multiple operations: function Post({ ref }) { const commentsRef = useRef(null); const addCommentRef = useRef(null); useImperativeHandle(ref, () => { return { scrollAndFocusAddComment() { commentsRef.current.scrollToBottom(); addCommentRef.current.focus(); } }; }, []); return ( <> <article> <p>Welcome to my blog!</p> </article> <CommentList ref={commentsRef} /> <AddComment ref={addCommentRef} /> </> ); }

useImperativeHandle hook signature

useImperativeHandle(ref, createHandle, dependencies?) is a React Hook that lets you customize the handle exposed as a ref. It takes a ref prop, a createHandle function that returns the ref handle to expose, and an optional dependencies array. It returns undefined.

useImperativeHandle selective method exposure example

This example shows exposing only focus and scrollIntoView methods from an input component: import { useRef, useImperativeHandle } from 'react'; function MyInput({ ref }) { const inputRef = useRef(null); useImperativeHandle(ref, () => { return { focus() { inputRef.current.focus(); }, scrollIntoView() { inputRef.current.scrollIntoView(); }, }; }, []); return <input ref={inputRef} />; }

useImperativeHandle return value

useImperativeHandle returns undefined.

useImperativeHandle parameters

useImperativeHandle accepts three parameters: ref (the ref received as a prop to the component), createHandle (a function that takes no arguments and returns the ref handle, typically an object with exposed methods), and dependencies (optional - a list of all reactive values referenced inside createHandle code, compared using Object.is, that determines when createHandle re-executes).

useInsertionEffect hook signature

useInsertionEffect takes two parameters: setup function and optional dependencies array. Signature is useInsertionEffect(setup, dependencies?).

useInsertionEffect better than rendering injection

useInsertionEffect is better than injecting styles during rendering because if React is processing a non-blocking update, injecting during rendering causes the browser to recalculate styles every single frame while rendering a component tree, which is extremely slow.

useInsertionEffect server-side CSS collection

To collect CSS rules used on the server when useInsertionEffect does not run, you can do it during rendering by checking if window is undefined: let collectedRulesSet = new Set(); function useCSS(rule) { if (typeof window === 'undefined') { collectedRulesSet.add(rule); } useInsertionEffect(() => { // ... }); return rule; }

useInsertionEffect CSS injection example

Example of using useInsertionEffect to inject dynamic styles from a CSS-in-JS library: import { useInsertionEffect } from 'react'; let isInserted = new Set(); function useCSS(rule) { useInsertionEffect(() => { if (!isInserted.has(rule)) { isInserted.add(rule); document.head.appendChild(getStyleForRule(rule)); } }); return rule; } function Button() { const className = useCSS('...'); return <div className={className} />; }

useInsertionEffect cleanup and setup interleaving

Unlike other types of Effects which fire cleanup for every Effect and then setup for every Effect, useInsertionEffect fires both cleanup and setup one component at a time, resulting in an interleaving of the cleanup and setup functions.

useInsertionEffect DOM timing unpredictable

useInsertionEffect may run either before or after the DOM has been updated. You should not rely on the DOM being updated at any particular time.

useInsertionEffect refs not attached yet

By the time useInsertionEffect runs, refs are not attached yet.

useInsertionEffect cannot update state

You cannot update state from inside useInsertionEffect.

useInsertionEffect is for CSS-in-JS library authors

useInsertionEffect is intended for CSS-in-JS library authors who need to inject styles. Unless you are working on a CSS-in-JS library and need a place to inject styles, you should use useEffect or useLayoutEffect instead.

useInsertionEffect only runs on client

Effects only run on the client. They do not run during server rendering.

useInsertionEffect return value

useInsertionEffect returns undefined.

useInsertionEffect dependencies parameter

The dependencies parameter is optional and must be a constant-length array written inline like [dep1, dep2, dep3]. React compares each dependency using Object.is comparison. Reactive values include props, state, and variables/functions declared directly in component body. If dependencies are not specified, the Effect re-runs after every component re-render.

useInsertionEffect better than useLayoutEffect for styles

useInsertionEffect is better than injecting styles during useLayoutEffect or useEffect because it ensures that by the time other Effects run in components, the style tags have already been inserted. Otherwise, layout calculations in regular Effects would be wrong due to outdated styles.

useInsertionEffect setup function behavior

The setup function runs before any layout Effects fire. It may optionally return a cleanup function. When a component is added to the DOM, React runs the setup function before layout Effects. After every re-render with changed dependencies, React runs the cleanup function first with old values, then runs setup with new values. When a component is removed, React runs the cleanup function.

useLayoutEffect Strict Mode behavior

When Strict Mode is on, React runs one extra development-only setup+cleanup cycle before the first real setup. This stress-tests that cleanup logic mirrors setup logic and stops or undoes what setup is doing.

useLayoutEffect dependencies array semantics

React compares each dependency with its previous value using Object.is comparison. Reactive values include props, state, and all variables and functions declared directly inside the component body. A linter configured for React will verify that every reactive value is correctly specified as a dependency. The list must have a constant number of items and be written inline like [dep1, dep2, dep3].

useLayoutEffect cleanup function behavior

The cleanup function returned by the setup function runs after every commit with changed dependencies (React runs the cleanup function with old values first, then the setup function with new values). Before the component is removed from the DOM, React also runs the cleanup function.

useLayoutEffect timing relative to browser repaint

useLayoutEffect is a version of useEffect that fires before the browser repaints the screen. React runs the setup function after the component commits to the DOM and before the browser repaints the screen.

useLayoutEffect return value

useLayoutEffect returns undefined.

useLayoutEffect signature and parameters

useLayoutEffect takes two parameters: setup (required) and dependencies (optional). The setup parameter is a function containing the effect logic that may optionally return a cleanup function. The dependencies parameter is a list of reactive values. If omitted, the effect runs after every commit.

useLayoutEffect and state updates trigger remaining Effects

If you trigger a state update inside useLayoutEffect, React will execute all remaining Effects immediately, including useEffect.

useLayoutEffect only runs on the client

Effects only run on the client. They do not run during server rendering.

useLayoutEffect blocks browser repaint

The code inside useLayoutEffect and all state updates scheduled from it block the browser from repainting the screen. When used excessively, this makes the app slow.

useLayoutEffect performance pitfall

useLayoutEffect can hurt performance. Prefer useEffect when possible.

useLayoutEffect can only be called at top level of component

useLayoutEffect is a Hook and can only be called at the top level of your component or your own Hooks. You cannot call it inside loops or conditions. If you need that, extract a component and move the Effect there.

useLayoutEffect for measuring layout before repaint

useLayoutEffect is used to perform layout measurements before the browser repaints the screen. This is useful for components that need to measure their size or position and adjust rendering based on that information without the user seeing intermediate states.

useLayoutEffect example: tooltip height measurement

import { useState, useRef, useLayoutEffect } from 'react'; function Tooltip() { const ref = useRef(null); const [tooltipHeight, setTooltipHeight] = useState(0); useLayoutEffect(() => { const { height } = ref.current.getBoundingClientRect(); setTooltipHeight(height); }, []); // ...use tooltipHeight in the rendering logic below... } This example shows measuring the tooltip's height before the browser repaints the screen, allowing the tooltip to be positioned correctly in the second render pass without flickering.

Give your agent this brain