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

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

When to use refs: imperative behaviors only

Refs should only be used 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, it should use props instead. Effects can help expose imperative behaviors via props.

forwardRef forwarding through multiple components

A ref can be forwarded through multiple components. If ComponentA forwards a ref to ComponentB, and ComponentB forwards that ref to a DOM node or uses it with useImperativeHandle, then a ref passed to ComponentA will ultimately reference what ComponentB exposes.

forwardRef ref null when conditionally rendered

If the DOM node that the ref is forwarded to is conditionally rendered, the ref will be null when the condition is false. This can happen when the ref is only attached to an element inside a conditional block or when the condition is hidden inside another component.

forwardRef pitfall: not actually using the ref parameter

A common mistake is wrapping a component in forwardRef but forgetting to actually use the ref parameter that is received. The ref must be passed to a DOM node or another component that can accept a ref, otherwise the ref will be null.

forwardRef example: imperative handle with custom methods

Example of using forwardRef with useImperativeHandle: import { forwardRef, useRef, useImperativeHandle } from 'react'; const MyInput = forwardRef(function MyInput(props, ref) { const inputRef = useRef(null); useImperativeHandle(ref, () => { return { focus() { inputRef.current.focus(); }, scrollIntoView() { inputRef.current.scrollIntoView(); }, }; }, []); return <input {...props} ref={inputRef} />; });

forwardRef with useImperativeHandle to expose custom methods

Instead of exposing an entire DOM node, you can use useImperativeHandle to expose a custom object with a constrained set of methods. Create a separate ref to hold the DOM node, then pass the forwarded ref to useImperativeHandle and specify the value you want to expose. This limits the information exposed about the DOM node to the minimum.

forwardRef is deprecated in React 19

In React 19, forwardRef is no longer necessary. The API will be deprecated in a future release. Instead of using forwardRef, pass ref as a prop directly.

forwardRef function signature and returns

forwardRef accepts a render function as its only parameter. It returns a React component that can be rendered in JSX. Unlike plain function components, the component returned by forwardRef is able to receive a ref prop.

static childContextTypes removed in React 19

The class component static property childContextTypes was removed in React 19. Use static contextType instead.

static propTypes removed in React 19

The class component static property propTypes was removed in React 19. Use a type system like TypeScript instead.

this.refs removed in React 19, use createRef instead

The class component instance property this.refs was removed in React 19. Use createRef instead.

cloneElement creates React element from another element

cloneElement lets you create a React element using another element as a starting point. It is a legacy API with alternatives available.

Component class for defining React components

Component lets you define a React component as a JavaScript class. It is a legacy API with alternatives available.

createElement creates React elements, use JSX instead

createElement lets you create a React element. Typically, you'll use JSX instead of calling this directly.

createRef creates ref object for arbitrary values

createRef creates a ref object which can contain arbitrary value. It is a legacy API with alternatives available.

forwardRef exposes DOM node to parent via ref

forwardRef lets your component expose a DOM node to parent component with a ref. This allows parent components to access child DOM nodes directly.

isValidElement checks if value is React element

isValidElement checks whether a value is a React element. It is typically used with cloneElement.

PureComponent skips re-renders with same props

PureComponent is similar to Component but it skips re-renders when props and state are the same. It is a legacy API with alternatives available.

createFactory removed in React 19, use JSX instead

createFactory was removed in React 19. Use JSX instead.

static getChildContext removed in React 19

The class component static method getChildContext was removed in React 19. Use Context with Provider instead.

Legacy APIs exported from react package

The react package exports several APIs that are not recommended for use in newly written code. These legacy APIs include: Children, cloneElement, Component, createElement, createRef, forwardRef, isValidElement, and PureComponent. Each has recommended alternatives documented on their individual reference pages.

lazy() caching behavior

Both the returned Promise and the Promise's resolved value will be cached, so React will not call the load function more than once.

lazy() return value

lazy() returns a React component that can be rendered in a component tree. While the code for the lazy component is still loading, attempting to render it will suspend. Use Suspense to display a loading indicator while it's loading.

lazy() load parameter requirements

The load parameter is a function that receives no parameters and must return a Promise or a thenable (a Promise-like object with a .then method). The Promise must eventually resolve to an object whose .default property is a valid React component type, such as a function, memo, or forwardRef component. React will not call load until the first time the returned component is rendered.

lazy() example with Suspense

import { useState, Suspense, lazy } from 'react'; import Loading from './Loading.js'; const MarkdownPreview = lazy(() => import('./MarkdownPreview.js')); export default function MarkdownEditor() { const [showPreview, setShowPreview] = useState(false); const [markdown, setMarkdown] = useState('Hello, **world**!'); return ( <> <textarea value={markdown} onChange={e => setMarkdown(e.target.value)} /> <label> <input type="checkbox" checked={showPreview} onChange={e => setShowPreview(e.target.checked)} /> Show preview </label> <hr /> {showPreview && ( <Suspense fallback={<Loading />}> <h2>Preview</h2> <MarkdownPreview markdown={markdown} /> </Suspense> )} </> ); }

lazy() must be declared at module level, not inside components

Do not declare lazy components inside other components, as this will cause all state to be reset on re-renders. Always declare lazy components at the top level of your module.

lazy() requires default export

The lazy-loaded component must be exported as a default export from the module. This pattern uses dynamic import() which requires that the lazy component was exported as the default export.

lazy() requires Suspense for loading states

When using a lazy component, wrap it or any of its parents in a Suspense boundary to specify what should be displayed while the component code is loading. Use the fallback prop to provide a loading indicator.

lazy() error handling

If the Promise returned by the load function rejects, React will throw the rejection reason for the nearest Error Boundary to handle.

lazy() function signature and basic usage

lazy() takes a load function and returns a React component that can be rendered. The load function should return a Promise or thenable that resolves to a module with a .default export. Call lazy() outside components to declare a lazy-loaded React component. Example: const MarkdownPreview = lazy(() => import('./MarkdownPreview.js'))

startTransition basic usage example

import { startTransition } from 'react'; function TabContainer() { const [tab, setTab] = useState('about'); function selectTab(nextTab) { startTransition(() => { setTab(nextTab); }); } // ... }

startTransition marks state updates as non-blocking Transitions

startTransition lets you mark a state update as a Transition, which makes the UI stay responsive during re-renders. State updates marked as Transitions will not display unwanted loading indicators.

startTransition with async state updates

Any async calls awaited in the action function will be included in the transition. However, any set functions called after an await must be wrapped in an additional startTransition call to be marked as Transitions.

startTransition does not track pending state

startTransition does not provide a way to track whether a Transition is pending. To show a pending indicator while a Transition is ongoing, use useTransition instead.

startTransition action executes immediately

The function passed to startTransition is called immediately. All state updates that happen synchronously while it executes are marked as Transitions. State updates in setTimeout or other asynchronous callbacks are not marked as Transitions unless explicitly wrapped.

startTransition cannot control text inputs

Transition updates marked with startTransition cannot be used to control text inputs.

startTransition works outside components

startTransition can be called outside components, such as from a data library, unlike useTransition which only works inside React components.

startTransition vs useTransition

startTransition is very similar to useTransition, except that it does not provide the isPending flag to track whether a Transition is ongoing. startTransition can be called outside components where useTransition is not available.

memo: optimize only when needed

You should only rely on memo as a performance optimization. If your code doesn't work without it, find and fix the underlying problem first. memo is only valuable when a component re-renders often with the same exact props and its re-rendering logic is expensive. If there is no perceptible lag when the component re-renders, memo is unnecessary.

memo: ineffective with always-changing props

memo is completely useless if the props passed to your component are always different, such as if you pass an object or a plain function defined during rendering. In these cases, you will often need useMemo and useCallback together with memo.

memo example: basic usage

Example of wrapping a component in memo: const Greeting = memo(function Greeting({ name }) { return <h1>Hello, {name}!</h1>; }); export default Greeting;

memo example: custom arePropsEqual function

Example of providing a custom comparison function: const Chart = memo(function Chart({ dataPoints }) { // ... }, arePropsEqual); function arePropsEqual(oldProps, newProps) { return oldProps.dataPoints.length === newProps.dataPoints.length && oldProps.dataPoints.every((oldPoint, index) => { const newPoint = newProps.dataPoints[index]; return oldPoint.x === newPoint.x && oldPoint.y === newPoint.y; }); }

memo purpose: skip re-renders on unchanged props

memo lets you skip re-rendering a component when its props are unchanged. The memoized component will usually not be re-rendered when its parent re-renders as long as its props have not changed. However, React may still re-render it; memoization is a performance optimization, not a guarantee.

memo parameters

memo accepts two parameters: (1) Component - the component to memoize, which can be any valid React component including functions and forwardRef components; (2) arePropsEqual (optional) - a function that accepts previous props and new props, returning true if they are equal (component will render the same output), false otherwise. By default, React uses Object.is to compare each prop.

memo return value

memo returns a new React component that behaves the same as the original component except that React will not re-render it when its parent re-renders unless its props have changed.

memo with pure components requirement

A React component wrapped in memo should always have pure rendering logic, meaning it must return the same output if its props, state, and context haven't changed. By using memo, you tell React that your component complies with this requirement.

memo does not prevent re-renders from context changes

Even when a component is memoized, it will still re-render when a context that it uses changes. Memoization only has to do with props that are passed from the parent component.

memo prop comparison uses shallow equality

When you use memo, your component re-renders whenever any prop is not shallowly equal to what it was previously. React compares every prop using Object.is comparison. Object.is(3, 3) returns true, but Object.is({}, {}) returns false.

memo with objects: use useMemo in parent

To prevent re-renders when passing an object prop to a memoized component, use useMemo in the parent component to prevent recreating the object every time the parent re-renders.

memo with functions: use useCallback in parent

When you need to pass a function to a memoized component, either declare it outside your component so it never changes, or use useCallback to cache its definition between re-renders.

memo custom arePropsEqual function

You can provide a custom comparison function as the second argument to memo. This function receives oldProps and newProps and should return true if they are equal (component renders the same output), false otherwise. React uses this instead of shallow equality.

memo arePropsEqual pitfall: must compare all props including functions

If you provide a custom arePropsEqual implementation, you must compare every prop, including functions. Functions often close over props and state of parent components. If you return true when functions differ, your component will keep seeing props and state from a previous render, leading to confusing bugs. Avoid deep equality checks in arePropsEqual unless you are certain the data structure has limited depth, as deep equality checks can become very slow and freeze the app.

memo with React Compiler

When React Compiler is enabled, you typically do not need React.memo anymore. The compiler automatically optimizes component re-rendering by tracking prop changes and reusing previously created JSX when props haven't changed, eliminating the need for manual memoization. The compiler's optimization is more comprehensive than memo; it also memoizes intermediate values and expensive computations within components.

memo basic signature

The memo function signature is: const MemoizedComponent = memo(SomeComponent, arePropsEqual?). It takes a component and an optional comparison function, and returns a new memoized component.

Pitfall: Promises passed to use must be cached

Promises created during render are recreated on every render, which causes React to show the Suspense fallback repeatedly. Instead, pass a Promise from a cache, a Suspense-enabled framework, or a Server Component. Do not pass `fetch('/albums')` directly to `use`; instead use a cached `fetchData('/albums')`.

Re-fetching data with use and startTransition

To refresh data at the same URL, invalidate the cache entry and start a new fetch inside `startTransition`. Store the resulting Promise in state to trigger a re-render. While the new Promise is pending, React keeps showing the existing content because the update is inside a Transition. The refetch pattern: function App() { const [albumsPromise, setAlbumsPromise] = useState(fetchData('/albums')); const [isPending, startTransition] = useTransition(); function handleRefresh() { startTransition(() => { setAlbumsPromise(refetchData('/albums')); }); } }

Preloading data on hover with use

Start loading data before it is needed by calling `fetchData` during a hover event. Since `fetchData` caches the Promise, the data may already be available by the time the user clicks. If the Promise has resolved by the time `use` reads it, React renders the component immediately without showing a Suspense fallback. Example: onMouseEnter={() => fetchData(`/${id}/albums`)}

Streaming data from server to client with use

Data can be streamed from the server to the client by passing a Promise as a prop from a Server Component to a Client Component. The Client Component receives the Promise and passes it to `use`, allowing it to read the value from the Promise initially created by the Server Component. The Client Component should be wrapped in a Suspense boundary to display a fallback while the Promise is pending.

Streaming data example - Server Component

import { fetchMessage } from './lib.js'; import { Message } from './message.js'; import { Suspense } from 'react'; export default function App() { const messagePromise = fetchMessage(); return ( <Suspense fallback={<p>waiting for message...</p>}> <Message messagePromise={messagePromise} /> </Suspense> ); }

Streaming data example - Client Component

'use client'; import { use } from 'react'; export function Message({ messagePromise }) { const messageContent = use(messagePromise); return <p>Here is the message: {messageContent}</p>; }

Give your agent this brain