----
url: https://18.react.dev/reference/react
----

React-dom contains features that are only supported for web applications (which run in the browser DOM environment). This section is broken into the following:

* [Hooks](/reference/react-dom/hooks) - Hooks for web applications which run in the browser DOM environment.
* [Components](/reference/react-dom/components) - React supports all of the browser built-in HTML and SVG components.
* [APIs](/reference/react-dom) - The `react-dom` package contains methods supported only in web applications.
* [Client APIs](/reference/react-dom/client) - The `react-dom/client` APIs let you render React components on the client (in the browser).
* [Server APIs](/reference/react-dom/server) - The `react-dom/server` APIs let you render React components to HTML on the server.

***

----
url: https://18.react.dev/learn/queueing-a-series-of-state-updates
----

99

9

10

11

12

13

14

15

16

17

import { useState } from 'react';



export default function Counter() {

const \[number, setNumber] = useState(0);



return (

<>

\<h1>{number}\</h1>

\<button onClick={() => {

setNumber(number + 1);

setNumber(number + 1);

setNumber(number + 1);

}}>+3\</button>

\</>

)

}



However, as you might recall from the previous section, [each render’s state values are fixed](/learn/state-as-a-snapshot#rendering-takes-a-snapshot-in-time), so the value of `number` inside the first render’s event handler is always `0`, no matter how many times you call `setNumber(1)`:

```
setNumber(0 + 1);

setNumber(0 + 1);

setNumber(0 + 1);
```

```
import { useState } from 'react';

export default function Counter() {
  const [number, setNumber] = useState(0);

  return (
    <>
      <h1>{number}</h1>
      <button onClick={() => {
        setNumber(n => n + 1);
        setNumber(n => n + 1);
        setNumber(n => n + 1);
      }}>+3</button>
    </>
  )
}
```

Here, `n => n + 1` is called an **updater function.** When you pass it to a state setter:

1. React queues this function to be processed after all the other code in the event handler has run.
2. During the next render, React goes through the queue and gives you the final updated state.

```
setNumber(n => n + 1);

setNumber(n => n + 1);

setNumber(n => n + 1);
```

Here’s how React works through these lines of code while executing the event handler:

1. `setNumber(n => n + 1)`: `n => n + 1` is a function. React adds it to a queue.
2. `setNumber(n => n + 1)`: `n => n + 1` is a function. React adds it to a queue.
3. `setNumber(n => n + 1)`: `n => n + 1` is a function. React adds it to a queue.

When you call `useState` during the next render, React goes through the queue. The previous `number` state was `0`, so that’s what React passes to the first updater function as the `n` argument. Then React takes the return value of your previous updater function and passes it to the next updater as `n`, and so on:

| queued update | `n` | returns     |
| ------------- | --- | ----------- |
| `n => n + 1`  | `0` | `0 + 1 = 1` |
| `n => n + 1`  | `1` | `1 + 1 = 2` |
| `n => n + 1`  | `2` | `2 + 1 = 3` |

React stores `3` as the final result and returns it from `useState`.

This is why clicking “+3” in the above example correctly increments the value by 3.

### What happens if you update state after replacing it[](#what-happens-if-you-update-state-after-replacing-it "Link for What happens if you update state after replacing it ")

What about this event handler? What do you think `number` will be in the next render?

```
<button onClick={() => {

  setNumber(number + 5);

  setNumber(n => n + 1);

}}>
```

```
import { useState } from 'react';

export default function Counter() {
  const [number, setNumber] = useState(0);

  return (
    <>
      <h1>{number}</h1>
      <button onClick={() => {
        setNumber(number + 5);
        setNumber(n => n + 1);
      }}>Increase the number</button>
    </>
  )
}
```

Here’s what this event handler tells React to do:

1. `setNumber(number + 5)`: `number` is `0`, so `setNumber(0 + 5)`. React adds *“replace with `5`”* to its queue.
2. `setNumber(n => n + 1)`: `n => n + 1` is an updater function. React adds *that function* to its queue.

During the next render, React goes through the state queue:

| queued update      | `n`          | returns     |
| ------------------ | ------------ | ----------- |
| ”replace with `5`” | `0` (unused) | `5`         |
| `n => n + 1`       | `5`          | `5 + 1 = 6` |

React stores `6` as the final result and returns it from `useState`.

### Note

You may have noticed that `setState(5)` actually works like `setState(n => 5)`, but `n` is unused!

### What happens if you replace state after updating it[](#what-happens-if-you-replace-state-after-updating-it "Link for What happens if you replace state after updating it ")

Let’s try one more example. What do you think `number` will be in the next render?

```
<button onClick={() => {

  setNumber(number + 5);

  setNumber(n => n + 1);

  setNumber(42);

}}>
```

```
import { useState } from 'react';

export default function Counter() {
  const [number, setNumber] = useState(0);

  return (
    <>
      <h1>{number}</h1>
      <button onClick={() => {
        setNumber(number + 5);
        setNumber(n => n + 1);
        setNumber(42);
      }}>Increase the number</button>
    </>
  )
}
```

Here’s how React works through these lines of code while executing this event handler:

1. `setNumber(number + 5)`: `number` is `0`, so `setNumber(0 + 5)`. React adds *“replace with `5`”* to its queue.
2. `setNumber(n => n + 1)`: `n => n + 1` is an updater function. React adds *that function* to its queue.
3. `setNumber(42)`: React adds *“replace with `42`”* to its queue.

During the next render, React goes through the state queue:

| queued update       | `n`          | returns     |
| ------------------- | ------------ | ----------- |
| ”replace with `5`”  | `0` (unused) | `5`         |
| `n => n + 1`        | `5`          | `5 + 1 = 6` |
| ”replace with `42`” | `6` (unused) | `42`        |

```
setEnabled(e => !e);

setLastName(ln => ln.reverse());

setFriendCount(fc => fc * 2);
```

```
import { useState } from 'react';

export default function RequestTracker() {
  const [pending, setPending] = useState(0);
  const [completed, setCompleted] = useState(0);

  async function handleClick() {
    setPending(pending + 1);
    await delay(3000);
    setPending(pending - 1);
    setCompleted(completed + 1);
  }

  return (
    <>
      <h3>
        Pending: {pending}
      </h3>
      <h3>
        Completed: {completed}
      </h3>
      <button onClick={handleClick}>
        Buy     
      </button>
    </>
  );
}

function delay(ms) {
  return new Promise(resolve => {
    setTimeout(resolve, ms);
  });
}
```

[PreviousState as a Snapshot](/learn/state-as-a-snapshot)

[NextUpdating Objects in State](/learn/updating-objects-in-state)

***

----
url: https://legacy.reactjs.org/blog/2014/06/27/community-roundup-19.html
----

June 27, 2014 by [Cheng Lou](https://twitter.com/_chenglou)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

## [](#react-meetups)React Meetups!

Ever wanted to find developers who also share the same interest in React than you? Recently, there has been a React Meetup in [San Francisco](http://www.meetup.com/ReactJS-San-Francisco/) (courtesy of [Telmate](http://www.telmate.com)), and one in [London](http://www.meetup.com/London-React-User-Group/) (courtesy of [Stuart Harris](http://www.meetup.com/London-React-User-Group/members/105837542/), [Cain Ullah](http://www.meetup.com/London-React-User-Group/members/15509971/) and [Zoe Merchant](http://www.meetup.com/London-React-User-Group/members/137058242/)). These two events have been big successes; a second one in London is [already planned](http://www.meetup.com/London-React-User-Group/events/191406572/).

If you don’t live near San Francisco or London, why not start one in your community?

## [](#complementary-tools)Complementary Tools

In case you haven’t seen it, we’ve consolidated the tooling solution around React on [this wiki page](https://github.com/facebook/react/wiki/Complementary-Tools). Some of the notable recent entries include:

* [Ryan Florence](https://github.com/rpflorence) and [Michael Jackson](https://github.com/mjackson)’s [react-nested-router](https://github.com/rpflorence/react-nested-router), which is a translation of the Ember router API to React.
* [Stephen J. Collings](https://github.com/stevoland)’s [react-bootstrap](https://github.com/react-bootstrap/react-bootstrap), which wraps the popular framework with a bit of React goodness. The [website](https://react-bootstrap.github.io/components.html) features live-editable demos.
* [Andrey Popp](https://github.com/andreypopp)’s [react-quickstart](https://github.com/andreypopp/react-quickstart), which gives you a quick template for server-side rendering and routing, among other features.

These are some of the links that often pop up on the #reactjs IRC channel. If you made something that you think deserves to be shown on the wiki, feel free to add it!

## [](#react-in-interesting-places)React in Interesting Places

The core concepts React themselves is something very valuable that the community is exploring and pushing further. A year ago, we wouldn’t have imagined something like [Bruce Hauman](http://rigsomelight.com)’s [Flappy Bird ClojureScript port](http://rigsomelight.com/2014/05/01/interactive-programming-flappy-bird-clojurescript.html), whose interactive programming has been made possible through React:

And don’t forget [Pete Hunt](https://github.com/petehunt)’s Wolfenstein 3D rendering engine in React ([source code](https://github.com/petehunt/wolfenstein3D-react/blob/master/js/renderer.js#L183)). While it’s nearly a year old, it’s still a nice demo.

[](http://www.petehunt.net/wolfenstein3D-react/wolf3d.html)

Give us a shoutout on IRC or [React Google Groups](https://groups.google.com/forum/#!forum/reactjs) if you’ve used React in some Interesting places.

## [](#even-more-people-using-react)Even More People Using React

### [](#prismatic)Prismatic

[Prismatic](http://getprismatic.com/home) recently shrank their codebase fivefold with the help of React and its popular ClojureScript wrapper, [Om](https://github.com/swannodette/om). They detailed their very positive experience [here](http://blog.getprismatic.com/om-sweet-om-high-functional-frontend-engineering-with-clojurescript-and-react/).

> Finally, the state is normalized: each piece of information is represented in a single place. Since React ensures consistency between the DOM and the application data, the programmer can focus on ensuring that the state properly stays up to date in response to user input. If the application state is normalized, then this consistency is guaranteed by definition, completely avoiding the possibility of an entire class of common bugs.

### [](#adobe-brackets)Adobe Brackets

[Kevin Dangoor](http://www.kevindangoor.com) works on [Brackets](http://brackets.io/?lang=en), the open-source code editor. After writing [his first impression on React](http://www.kevindangoor.com/2014/05/simplifying-code-with-react/), he followed up with another insightful [article](http://www.kevindangoor.com/2014/05/react-in-brackets/) on how to gradually make the code transition, how to preserve the editor’s good parts, and how to tune Brackets’ tooling around JSX.

> We don’t need to switch to React everywhere, all at once. It’s not a framework that imposes anything on the application structure. \[…] Easy, iterative adoption is definitely something in React’s favor for us.

### [](#storehouse)Storehouse

[Storehouse](https://www.storehouse.co) (Apple Design Award 2014)‘s web presence is build with React. Here’s [an example story](https://www.storehouse.co/stories/y2ad-mexico-city-clouds). Congratulations on the award!

### [](#vim-awesome)Vim Awesome

[Vim Awesome](http://vimawesome.com), an open-source Vim plugins directory built on React, was just launched. Be sure to [check out the source code](https://github.com/divad12/vim-awesome) if you’re curious to see an example of how to build a small single-page React app.

## [](#random-tweets)Random Tweets

> Spent 12 hours so far with [#reactjs](https://twitter.com/hashtag/reactjs?src=hash). Spent another 2 wondering why we've been doing JS frameworks wrong until now. React makes me happy.
>
> — Paul Irwin (@paulirwin) [June 24, 2014](https://twitter.com/paulirwin/statuses/481263947589242882)

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2014-06-27-community-roundup-19.md)

----
url: https://legacy.reactjs.org/docs/create-fragment.html
----

> Note:
>
> `React.addons` entry point is deprecated as of React v15.5. We now have first class support for fragments which you can read about [here](/docs/fragments.html).

## [](#importing)Importing

```
import createFragment from 'react-addons-create-fragment'; // ES6
var createFragment = require('react-addons-create-fragment'); // ES5 with npm
```

## [](#overview)Overview

In most cases, you can use the `key` prop to specify keys on the elements you’re returning from `render`. However, this breaks down in one situation: if you have two sets of children that you need to reorder, there’s no way to put a key on each set without adding a wrapper element.

That is, if you have a component such as:

```
function Swapper(props) {
  let children;
  if (props.swapped) {
    children = [props.rightChildren, props.leftChildren];
  } else {
    children = [props.leftChildren, props.rightChildren];
  }
  return <div>{children}</div>;
}
```

The children will unmount and remount as you change the `swapped` prop because there aren’t any keys marked on the two sets of children.

To solve this problem, you can use the `createFragment` add-on to give keys to the sets of children.

#### [](#arrayreactnode-createfragmentobject-children)`Array<ReactNode> createFragment(object children)`

Instead of creating arrays, we write:

```
import createFragment from 'react-addons-create-fragment';

function Swapper(props) {
  let children;
  if (props.swapped) {
    children = createFragment({
      right: props.rightChildren,
      left: props.leftChildren
    });
  } else {
    children = createFragment({
      left: props.leftChildren,
      right: props.rightChildren
    });
  }
  return <div>{children}</div>;
}
```

The keys of the passed object (that is, `left` and `right`) are used as keys for the entire set of children, and the order of the object’s keys is used to determine the order of the rendered children. With this change, the two sets of children will be properly reordered in the DOM without unmounting.

The return value of `createFragment` should be treated as an opaque object; you can use the [`React.Children`](/docs/react-api.html#react.children) helpers to loop through a fragment but should not access it directly. Note also that we’re relying on the JavaScript engine preserving object enumeration order here, which is not guaranteed by the spec but is implemented by all major browsers and VMs for objects with non-numeric keys.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/addons-create-fragment.md)

----
url: https://react.dev/reference/eslint-plugin-react-hooks/lints/refs
----

[API Reference](/reference/react)

[Lints](/reference/eslint-plugin-react-hooks)

# refs[](#undefined "Link for this heading")

Validates correct usage of refs, not reading/writing during render. See the “pitfalls” section in [`useRef()` usage](/reference/react/useRef#usage).

## Rule Details[](#rule-details "Link for Rule Details ")

Refs hold values that aren’t used for rendering. Unlike state, changing a ref doesn’t trigger a re-render. Reading or writing `ref.current` during render breaks React’s expectations. Refs might not be initialized when you try to read them, and their values can be stale or inconsistent.

## How It Detects Refs[](#how-it-detects-refs "Link for How It Detects Refs ")

The lint only applies these rules to values it knows are refs. A value is inferred as a ref when the compiler sees any of the following patterns:

* Returned from `useRef()` or `React.createRef()`.

  ```
  const scrollRef = useRef(null);
  ```

* An identifier named `ref` or ending in `Ref` that reads from or writes to `.current`.

  ```
  buttonRef.current = node;
  ```

* Passed through a JSX `ref` prop (for example `<div ref={someRef} />`).

  ```
  <input ref={inputRef} />
  ```

Once something is marked as a ref, that inference follows the value through assignments, destructuring, or helper calls. This lets the lint surface violations even when `ref.current` is accessed inside another function that received the ref as an argument.

## Common Violations[](#common-violations "Link for Common Violations ")

* Reading `ref.current` during render
* Updating `refs` during render
* Using `refs` for values that should be state

### Invalid[](#invalid "Link for Invalid ")

Examples of incorrect code for this rule:

```
// ❌ Reading ref during render

function Component() {

  const ref = useRef(0);

  const value = ref.current; // Don't read during render

  return <div>{value}</div>;

}



// ❌ Modifying ref during render

function Component({value}) {

  const ref = useRef(null);

  ref.current = value; // Don't modify during render

  return <div />;

}
```

### Valid[](#valid "Link for Valid ")

Examples of correct code for this rule:

```
// ✅ Read ref in effects/handlers

function Component() {

  const ref = useRef(null);



  useEffect(() => {

    if (ref.current) {

      console.log(ref.current.offsetWidth); // OK in effect

    }

  });



  return <div ref={ref} />;

}



// ✅ Use state for UI values

function Component() {

  const [count, setCount] = useState(0);



  return (

    <button onClick={() => setCount(count + 1)}>

      {count}

    </button>

  );

}



// ✅ Lazy initialization of ref value

function Component() {

  const ref = useRef(null);



  // Initialize only once on first use

  if (ref.current === null) {

    ref.current = expensiveComputation(); // OK - lazy initialization

  }



  const handleClick = () => {

    console.log(ref.current); // Use the initialized value

  };



  return <button onClick={handleClick}>Click</button>;

}
```

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### The lint flagged my plain object with `.current`[](#plain-object-current "Link for this heading")

The name heuristic intentionally treats `ref.current` and `fooRef.current` as real refs. If you’re modeling a custom container object, pick a different name (for example, `box`) or move the mutable value into state. Renaming avoids the lint because the compiler stops inferring it as a ref.

[Previouspurity](/reference/eslint-plugin-react-hooks/lints/purity)

[Nextset-state-in-effect](/reference/eslint-plugin-react-hooks/lints/set-state-in-effect)

***

----
url: https://react.dev/community/team
----

[elicwhite](https://github.com/elicwhite)

### Hendrik Liebau[](#hendrik-liebau "Link for Hendrik Liebau")

Engineer at Vercel

Hendrik’s journey in tech started in the late 90s when he built his first websites with Netscape Communicator. After earning a diploma in computer science and working at digital agencies, he built a React Server Components bundler and library, paving the way to his role on the Next.js team. Outside of work, he enjoys cycling and tinkering in his workshop.

[unstubbable](https://twitter.com/unstubbable)

[unstubbable.bsky.social](https://bsky.app/profile/unstubbable.bsky.social)

[unstubbable](https://github.com/unstubbable)

### Jordan Brown[](#jordan-brown "Link for Jordan Brown")

Engineer at Meta

Jordan started coding by building iPhone apps, where he was pushing and popping view controllers before he knew that for-loops were a thing. He enjoys working on technology that developers love, which naturally drew him to React. Outside of work he enjoys reading, kiteboarding, and playing guitar.

[jbrown215](https://github.com/jbrown215)


Lauren’s programming career peaked when she first discovered the `<marquee>` tag. She’s been chasing that high ever since. She studied Finance instead of CS in college, so she learned to code using Excel. Lauren enjoys dropping cheeky memes in chat, playing video games with her partner, learning Korean, and petting her dog Zelda.

[potetotes](https://twitter.com/potetotes)

[potetotes](https://threads.net/potetotes)

[no.lol](https://bsky.app/profile/no.lol)

[poteto](https://github.com/poteto)

### Matt Carroll[](#matt-carroll "Link for Matt Carroll")

Developer Advocate at Meta

Matt stumbled into coding, and since then, has become enamored with creating things in communities that can’t be created alone. Prior to React, he worked on YouTube, the Google Assistant, Fuchsia, and Google Cloud AI and Evernote. When he’s not trying to make better developer tools he enjoys the mountains, jazz, and spending time with his family.

[mattcarrollcode](https://twitter.com/mattcarrollcode)

[mattcarrollcode](https://threads.net/mattcarrollcode)

[mattcarrollcode](https://github.com/mattcarrollcode)

### Mike Vitousek[](#mike-vitousek "Link for Mike Vitousek")

Engineer at Meta

Mike went to grad school dreaming of becoming a professor but realized that he liked building things a lot more than writing grant applications. Mike joined Meta to work on Javascript infrastructure, which ultimately led him to work on the React Compiler. When not hacking on either Javascript or OCaml, Mike can often be found hiking or skiing in the Pacific Northwest.

[mvitousek](https://github.com/mvitousek)

### Mofei Zhang[](#mofei-zhang "Link for Mofei Zhang")

Engineer at Meta

Mofei started programming when she realized it can help her cheat in video games. She focused on operating systems in undergrad / grad school, but now finds herself happily tinkering on React. Outside of work, she enjoys debugging bouldering problems and planning her next backpacking trip(s).

[z\_mofei](https://threads.net/z_mofei)

[mofeiZ](https://github.com/mofeiZ)

### Pieter Vanderwerff[](#pieter-vanderwerff "Link for Pieter Vanderwerff")

Engineer at Meta

Pieter studied building science but after failing to get a job he made himself a website and things escalated from there. At Meta, he enjoys working on performance, languages and now React. When he’s not programming you can find him off-road in the mountains.

[pietervanderwerff](https://threads.net/pietervanderwerff)

[pieterv](https://github.com/pieterv)

***

----
url: https://react.dev/community/translations
----

[Community](/community)

# Translations[](#undefined "Link for this heading")

React docs are translated by the global community into many languages all over the world.

## Source site[](#main-site "Link for Source site ")

All translations are provided from the canonical source docs:

* [English](https://react.dev/) — [Contribute](https://github.com/reactjs/react.dev/)

## Full translations[](#full-translations "Link for Full translations ")

* [French (Français)](https://fr.react.dev/) — [Contribute](https://github.com/reactjs/fr.react.dev)
* [Japanese (日本語)](https://ja.react.dev/) — [Contribute](https://github.com/reactjs/ja.react.dev)
* [Korean (한국어)](https://ko.react.dev/) — [Contribute](https://github.com/reactjs/ko.react.dev)
* [Simplified Chinese (简体中文)](https://zh-hans.react.dev/) — [Contribute](https://github.com/reactjs/zh-hans.react.dev)
* [Spanish (Español)](https://es.react.dev/) — [Contribute](https://github.com/reactjs/es.react.dev)
* [Turkish (Türkçe)](https://tr.react.dev/) — [Contribute](https://github.com/reactjs/tr.react.dev)

## In-progress translations[](#in-progress-translations "Link for In-progress translations ")

For the progress of each translation, see: [Is React Translated Yet?](https://translations.react.dev/)

* [Arabic (العربية)](https://ar.react.dev/) — [Contribute](https://github.com/reactjs/ar.react.dev)
* [Azerbaijani (Azərbaycanca)](https://az.react.dev/) — [Contribute](https://github.com/reactjs/az.react.dev)
* [Belarusian (Беларуская)](https://be.react.dev/) — [Contribute](https://github.com/reactjs/be.react.dev)
* [Bengali (বাংলা)](https://bn.react.dev/) — [Contribute](https://github.com/reactjs/bn.react.dev)
* [Czech (Čeština)](https://cs.react.dev/) — [Contribute](https://github.com/reactjs/cs.react.dev)
* [Finnish (Suomi)](https://fi.react.dev/) — [Contribute](https://github.com/reactjs/fi.react.dev)
* [German (Deutsch)](https://de.react.dev/) — [Contribute](https://github.com/reactjs/de.react.dev)
* [Gujarati (ગુજરાતી)](https://gu.react.dev/) — [Contribute](https://github.com/reactjs/gu.react.dev)
* [Hebrew (עברית)](https://he.react.dev/) — [Contribute](https://github.com/reactjs/he.react.dev)
* [Hindi (हिन्दी)](https://hi.react.dev/) — [Contribute](https://github.com/reactjs/hi.react.dev)
* [Hungarian (magyar)](https://hu.react.dev/) — [Contribute](https://github.com/reactjs/hu.react.dev)
* [Icelandic (Íslenska)](https://is.react.dev/) — [Contribute](https://github.com/reactjs/is.react.dev)
* [Indonesian (Bahasa Indonesia)](https://id.react.dev/) — [Contribute](https://github.com/reactjs/id.react.dev)
* [Italian (Italiano)](https://it.react.dev/) — [Contribute](https://github.com/reactjs/it.react.dev)
* [Kazakh (Қазақша)](https://kk.react.dev/) — [Contribute](https://github.com/reactjs/kk.react.dev)
* [Lao (ພາສາລາວ)](https://lo.react.dev/) — [Contribute](https://github.com/reactjs/lo.react.dev)
* [Macedonian (Македонски)](https://mk.react.dev/) — [Contribute](https://github.com/reactjs/mk.react.dev)
* [Malayalam (മലയാളം)](https://ml.react.dev/) — [Contribute](https://github.com/reactjs/ml.react.dev)
* [Mongolian (Монгол хэл)](https://mn.react.dev/) — [Contribute](https://github.com/reactjs/mn.react.dev)
* [Persian (فارسی)](https://fa.react.dev/) — [Contribute](https://github.com/reactjs/fa.react.dev)
* [Polish (Polski)](https://pl.react.dev/) — [Contribute](https://github.com/reactjs/pl.react.dev)
* [Portuguese (Brazil) (Português do Brasil)](https://pt-br.react.dev/) — [Contribute](https://github.com/reactjs/pt-br.react.dev)
* [Russian (Русский)](https://ru.react.dev/) — [Contribute](https://github.com/reactjs/ru.react.dev)
* [Serbian (Srpski)](https://sr.react.dev/) — [Contribute](https://github.com/reactjs/sr.react.dev)
* [Sinhala (සිංහල)](https://si.react.dev/) — [Contribute](https://github.com/reactjs/si.react.dev)
* [Swahili (Kiswahili)](https://sw.react.dev/) — [Contribute](https://github.com/reactjs/sw.react.dev)
* [Tamil (தமிழ்)](https://ta.react.dev/) — [Contribute](https://github.com/reactjs/ta.react.dev)
* [Telugu (తెలుగు)](https://te.react.dev/) — [Contribute](https://github.com/reactjs/te.react.dev)
* [Traditional Chinese (繁體中文)](https://zh-hant.react.dev/) — [Contribute](https://github.com/reactjs/zh-hant.react.dev)
* [Ukrainian (Українська)](https://uk.react.dev/) — [Contribute](https://github.com/reactjs/uk.react.dev)
* [Urdu (اردو)](https://ur.react.dev/) — [Contribute](https://github.com/reactjs/ur.react.dev)
* [Vietnamese (Tiếng Việt)](https://vi.react.dev/) — [Contribute](https://github.com/reactjs/vi.react.dev)

## How to contribute[](#how-to-contribute "Link for How to contribute ")

You can contribute to the translation efforts!

The community conducts the translation work for the React docs on each language-specific fork of react.dev. Typical translation work involves directly translating a Markdown file and creating a pull request. Click the “contribute” link above to the GitHub repository for your language, and follow the instructions there to help with the translation effort.

If you want to start a new translation for your language, visit: [translations.react.dev](https://github.com/reactjs/translations.react.dev)

[PreviousDocs Contributors](/community/docs-contributors)

[NextAcknowledgements](/community/acknowledgements)

***

----
url: https://react.dev/blog/2024/04/25/react-19-upgrade-guide
----

[Blog](/blog)

# React 19 Upgrade Guide[](#undefined "Link for this heading")

April 25, 2024 by [Ricky Hanlon](https://twitter.com/rickhanlonii)

***

The improvements added to React 19 require some breaking changes, but we’ve worked to make the upgrade as smooth as possible, and we don’t expect the changes to impact most apps.

### Note

#### React 18.3 has also been published[](#react-18-3 "Link for React 18.3 has also been published ")

To help make the upgrade to React 19 easier, we’ve published a `react@18.3` release that is identical to 18.2 but adds warnings for deprecated APIs and other changes that are needed for React 19.

We recommend upgrading to React 18.3 first to help identify any issues before upgrading to React 19.

For a list of changes in 18.3 see the [Release Notes](https://github.com/facebook/react/blob/main/CHANGELOG.md#1830-april-25-2024).

In this post, we will guide you through the steps for upgrading to React 19:

* [Installing](#installing)
* [Codemods](#codemods)
* [Breaking changes](#breaking-changes)
* [New deprecations](#new-deprecations)
* [Notable changes](#notable-changes)
* [TypeScript changes](#typescript-changes)
* [Changelog](#changelog)

If you’d like to help us test React 19, follow the steps in this upgrade guide and [report any issues](https://github.com/facebook/react/issues/new?assignees=\&labels=React+19\&projects=\&template=19.md\&title=%5BReact+19%5D) you encounter. For a list of new features added to React 19, see the [React 19 release post](/blog/2024/12/05/react-19).

***

## Installing[](#installing "Link for Installing ")

### Note

#### New JSX Transform is now required[](#new-jsx-transform-is-now-required "Link for New JSX Transform is now required ")

We introduced a [new JSX transform](https://legacy.reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html) in 2020 to improve bundle size and use JSX without importing React. In React 19, we’re adding additional improvements like using ref as a prop and JSX speed improvements that require the new transform.

If the new transform is not enabled, you will see this warning:

Console

Your app (or one of its dependencies) is using an outdated JSX transform. Update to the modern JSX transform for faster performance: <https://react.dev/link/new-jsx-transform>

We expect most apps will not be affected since the transform is enabled in most environments already. For manual instructions on how to upgrade, please see the [announcement post](https://legacy.reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html).

To install the latest version of React and React DOM:

```
npm install --save-exact react@^19.0.0 react-dom@^19.0.0
```

Or, if you’re using Yarn:

```
yarn add --exact react@^19.0.0 react-dom@^19.0.0
```

If you’re using TypeScript, you also need to update the types.

```
npm install --save-exact @types/react@^19.0.0 @types/react-dom@^19.0.0
```

Or, if you’re using Yarn:

```
yarn add --exact @types/react@^19.0.0 @types/react-dom@^19.0.0
```

We’re also including a codemod for the most common replacements. See [TypeScript changes](#typescript-changes) below.

## Codemods[](#codemods "Link for Codemods ")

To help with the upgrade, we’ve worked with the team at [codemod.com](https://codemod.com) to publish codemods that will automatically update your code to many of the new APIs and patterns in React 19.

All codemods are available in the [`react-codemod` repo](https://github.com/reactjs/react-codemod) and the Codemod team have joined in helping maintain the codemods. To run these codemods, we recommend using the `codemod` command instead of the `react-codemod` because it runs faster, handles more complex code migrations, and provides better support for TypeScript.

### Note

#### Run all React 19 codemods[](#run-all-react-19-codemods "Link for Run all React 19 codemods ")

Run all codemods listed in this guide with the React 19 `codemod` recipe:

```
npx codemod@latest react/19/migration-recipe
```

This will run the following codemods from `react-codemod`:

* [`replace-reactdom-render`](https://github.com/reactjs/react-codemod?tab=readme-ov-file#replace-reactdom-render)
* [`replace-string-ref`](https://github.com/reactjs/react-codemod?tab=readme-ov-file#replace-string-ref)
* [`replace-act-import`](https://github.com/reactjs/react-codemod?tab=readme-ov-file#replace-act-import)
* [`replace-use-form-state`](https://github.com/reactjs/react-codemod?tab=readme-ov-file#replace-use-form-state)
* [`prop-types-typescript`](https://github.com/reactjs/react-codemod#react-proptypes-to-prop-types)

This does not include the TypeScript changes. See [TypeScript changes](#typescript-changes) below.

Changes that include a codemod include the command below.

For a list of all available codemods, see the [`react-codemod` repo](https://github.com/reactjs/react-codemod).

## Breaking changes[](#breaking-changes "Link for Breaking changes ")

### Errors in render are not re-thrown[](#errors-in-render-are-not-re-thrown "Link for Errors in render are not re-thrown ")

In previous versions of React, errors thrown during render were caught and rethrown. In DEV, we would also log to `console.error`, resulting in duplicate error logs.

In React 19, we’ve [improved how errors are handled](/blog/2024/04/25/react-19#error-handling) to reduce duplication by not re-throwing:

* **Uncaught Errors**: Errors that are not caught by an Error Boundary are reported to `window.reportError`.
* **Caught Errors**: Errors that are caught by an Error Boundary are reported to `console.error`.

This change should not impact most apps, but if your production error reporting relies on errors being re-thrown, you may need to update your error handling. To support this, we’ve added new methods to `createRoot` and `hydrateRoot` for custom error handling:

```
const root = createRoot(container, {

  onUncaughtError: (error, errorInfo) => {

    // ... log error report

  },

  onCaughtError: (error, errorInfo) => {

    // ... log error report

  }

});
```

For more info, see the docs for [`createRoot`](https://react.dev/reference/react-dom/client/createRoot) and [`hydrateRoot`](https://react.dev/reference/react-dom/client/hydrateRoot).

### Removed deprecated React APIs[](#removed-deprecated-react-apis "Link for Removed deprecated React APIs ")

#### Removed: `propTypes` and `defaultProps` for functions[](#removed-proptypes-and-defaultprops "Link for this heading")

`PropTypes` were deprecated in [April 2017 (v15.5.0)](https://legacy.reactjs.org/blog/2017/04/07/react-v15.5.0.html#new-deprecation-warnings).

In React 19, we’re removing the `propType` checks from the React package, and using them will be silently ignored. If you’re using `propTypes`, we recommend migrating to TypeScript or another type-checking solution.

We’re also removing `defaultProps` from function components in place of ES6 default parameters. Class components will continue to support `defaultProps` since there is no ES6 alternative.

```
// Before

import PropTypes from 'prop-types';



function Heading({text}) {

  return <h1>{text}</h1>;

}

Heading.propTypes = {

  text: PropTypes.string,

};

Heading.defaultProps = {

  text: 'Hello, world!',

};
```

```
// After

interface Props {

  text?: string;

}

function Heading({text = 'Hello, world!'}: Props) {

  return <h1>{text}</h1>;

}
```

### Note

Codemod `propTypes` to TypeScript with:

```
npx codemod@latest react/prop-types-typescript
```

#### Removed: Legacy Context using `contextTypes` and `getChildContext`[](#removed-removing-legacy-context "Link for this heading")

Legacy Context was deprecated in [October 2018 (v16.6.0)](https://legacy.reactjs.org/blog/2018/10/23/react-v-16-6.html).

Legacy Context was only available in class components using the APIs `contextTypes` and `getChildContext`, and was replaced with `contextType` due to subtle bugs that were easy to miss. In React 19, we’re removing Legacy Context to make React slightly smaller and faster.

If you’re still using Legacy Context in class components, you’ll need to migrate to the new `contextType` API:

```
// Before

import PropTypes from 'prop-types';



class Parent extends React.Component {

  static childContextTypes = {

    foo: PropTypes.string.isRequired,

  };



  getChildContext() {

    return { foo: 'bar' };

  }



  render() {

    return <Child />;

  }

}



class Child extends React.Component {

  static contextTypes = {

    foo: PropTypes.string.isRequired,

  };



  render() {

    return <div>{this.context.foo}</div>;

  }

}
```

```
// After

const FooContext = React.createContext();



class Parent extends React.Component {

  render() {

    return (

      <FooContext value='bar'>

        <Child />

      </FooContext>

    );

  }

}



class Child extends React.Component {

  static contextType = FooContext;



  render() {

    return <div>{this.context}</div>;

  }

}
```

#### Removed: string refs[](#removed-string-refs "Link for Removed: string refs ")

String refs were deprecated in [March, 2018 (v16.3.0)](https://legacy.reactjs.org/blog/2018/03/27/update-on-async-rendering.html).

Class components supported string refs before being replaced by ref callbacks due to [multiple downsides](https://github.com/facebook/react/issues/1373). In React 19, we’re removing string refs to make React simpler and easier to understand.

If you’re still using string refs in class components, you’ll need to migrate to ref callbacks:

```
// Before

class MyComponent extends React.Component {

  componentDidMount() {

    this.refs.input.focus();

  }



  render() {

    return <input ref='input' />;

  }

}
```

```
// After

class MyComponent extends React.Component {

  componentDidMount() {

    this.input.focus();

  }



  render() {

    return <input ref={input => this.input = input} />;

  }

}
```

### Note

Codemod string refs with `ref` callbacks:

```
npx codemod@latest react/19/replace-string-ref
```

#### Removed: Module pattern factories[](#removed-module-pattern-factories "Link for Removed: Module pattern factories ")

Module pattern factories were deprecated in [August 2019 (v16.9.0)](https://legacy.reactjs.org/blog/2019/08/08/react-v16.9.0.html#deprecating-module-pattern-factories).

This pattern was rarely used and supporting it causes React to be slightly larger and slower than necessary. In React 19, we’re removing support for module pattern factories, and you’ll need to migrate to regular functions:

```
// Before

function FactoryComponent() {

  return { render() { return <div />; } }

}
```

```
// After

function FactoryComponent() {

  return <div />;

}
```

#### Removed: `React.createFactory`[](#removed-createfactory "Link for this heading")

`createFactory` was deprecated in [February 2020 (v16.13.0)](https://legacy.reactjs.org/blog/2020/02/26/react-v16.13.0.html#deprecating-createfactory).

Using `createFactory` was common before broad support for JSX, but it’s rarely used today and can be replaced with JSX. In React 19, we’re removing `createFactory` and you’ll need to migrate to JSX:

```
// Before

import { createFactory } from 'react';



const button = createFactory('button');
```

```
// After

const button = <button />;
```

#### Removed: `react-test-renderer/shallow`[](#removed-react-test-renderer-shallow "Link for this heading")

In React 18, we updated `react-test-renderer/shallow` to re-export [react-shallow-renderer](https://github.com/enzymejs/react-shallow-renderer). In React 19, we’re removing `react-test-render/shallow` to prefer installing the package directly:

```
npm install react-shallow-renderer --save-dev
```

```
- import ShallowRenderer from 'react-test-renderer/shallow';

+ import ShallowRenderer from 'react-shallow-renderer';
```

### Note

##### Please reconsider shallow rendering[](#please-reconsider-shallow-rendering "Link for Please reconsider shallow rendering ")

Shallow rendering depends on React internals and can block you from future upgrades. We recommend migrating your tests to [@testing-library/react](https://testing-library.com/docs/react-testing-library/intro/) or [@testing-library/react-native](https://testing-library.com/docs/react-native-testing-library/intro).

### Removed deprecated React DOM APIs[](#removed-deprecated-react-dom-apis "Link for Removed deprecated React DOM APIs ")

#### Removed: `react-dom/test-utils`[](#removed-react-dom-test-utils "Link for this heading")

We’ve moved `act` from `react-dom/test-utils` to the `react` package:

Console

`ReactDOMTestUtils.act` is deprecated in favor of `React.act`. Import `act` from `react` instead of `react-dom/test-utils`. See <https://react.dev/warnings/react-dom-test-utils> for more info.

To fix this warning, you can import `act` from `react`:

```
- import {act} from 'react-dom/test-utils'

+ import {act} from 'react';
```

All other `test-utils` functions have been removed. These utilities were uncommon, and made it too easy to depend on low level implementation details of your components and React. In React 19, these functions will error when called and their exports will be removed in a future version.

See the [warning page](https://react.dev/warnings/react-dom-test-utils) for alternatives.

### Note

Codemod `ReactDOMTestUtils.act` to `React.act`:

```
npx codemod@latest react/19/replace-act-import
```

#### Removed: `ReactDOM.render`[](#removed-reactdom-render "Link for this heading")

`ReactDOM.render` was deprecated in [March 2022 (v18.0.0)](https://react.dev/blog/2022/03/08/react-18-upgrade-guide). In React 19, we’re removing `ReactDOM.render` and you’ll need to migrate to using [`ReactDOM.createRoot`](https://react.dev/reference/react-dom/client/createRoot):

```
// Before

import {render} from 'react-dom';

render(<App />, document.getElementById('root'));



// After

import {createRoot} from 'react-dom/client';

const root = createRoot(document.getElementById('root'));

root.render(<App />);
```

### Note

Codemod `ReactDOM.render` to `ReactDOMClient.createRoot`:

```
npx codemod@latest react/19/replace-reactdom-render
```

#### Removed: `ReactDOM.hydrate`[](#removed-reactdom-hydrate "Link for this heading")

`ReactDOM.hydrate` was deprecated in [March 2022 (v18.0.0)](https://react.dev/blog/2022/03/08/react-18-upgrade-guide). In React 19, we’re removing `ReactDOM.hydrate` you’ll need to migrate to using [`ReactDOM.hydrateRoot`](https://react.dev/reference/react-dom/client/hydrateRoot),

```
// Before

import {hydrate} from 'react-dom';

hydrate(<App />, document.getElementById('root'));



// After

import {hydrateRoot} from 'react-dom/client';

hydrateRoot(document.getElementById('root'), <App />);
```

### Note

Codemod `ReactDOM.hydrate` to `ReactDOMClient.hydrateRoot`:

```
npx codemod@latest react/19/replace-reactdom-render
```

#### Removed: `unmountComponentAtNode`[](#removed-unmountcomponentatnode "Link for this heading")

`ReactDOM.unmountComponentAtNode` was deprecated in [March 2022 (v18.0.0)](https://react.dev/blog/2022/03/08/react-18-upgrade-guide). In React 19, you’ll need to migrate to using `root.unmount()`.

```
// Before

unmountComponentAtNode(document.getElementById('root'));



// After

root.unmount();
```

For more see `root.unmount()` for [`createRoot`](https://react.dev/reference/react-dom/client/createRoot#root-unmount) and [`hydrateRoot`](https://react.dev/reference/react-dom/client/hydrateRoot#root-unmount).

### Note

Codemod `unmountComponentAtNode` to `root.unmount`:

```
npx codemod@latest react/19/replace-reactdom-render
```

#### Removed: `ReactDOM.findDOMNode`[](#removed-reactdom-finddomnode "Link for this heading")

`ReactDOM.findDOMNode` was [deprecated in October 2018 (v16.6.0)](https://legacy.reactjs.org/blog/2018/10/23/react-v-16-6.html#deprecations-in-strictmode).

We’re removing `findDOMNode` because it was a legacy escape hatch that was slow to execute, fragile to refactoring, only returned the first child, and broke abstraction levels (see more [here](https://legacy.reactjs.org/docs/strict-mode.html#warning-about-deprecated-finddomnode-usage)). You can replace `ReactDOM.findDOMNode` with [DOM refs](/learn/manipulating-the-dom-with-refs):

```
// Before

import {findDOMNode} from 'react-dom';



function AutoselectingInput() {

  useEffect(() => {

    const input = findDOMNode(this);

    input.select()

  }, []);



  return <input defaultValue="Hello" />;

}
```

```
// After

function AutoselectingInput() {

  const ref = useRef(null);

  useEffect(() => {

    ref.current.select();

  }, []);



  return <input ref={ref} defaultValue="Hello" />

}
```

## New deprecations[](#new-deprecations "Link for New deprecations ")

### Deprecated: `element.ref`[](#deprecated-element-ref "Link for this heading")

React 19 supports [`ref` as a prop](/blog/2024/04/25/react-19#ref-as-a-prop), so we’re deprecating the `element.ref` in place of `element.props.ref`.

Accessing `element.ref` will warn:

Console

Accessing element.ref is no longer supported. ref is now a regular prop. It will be removed from the JSX Element type in a future release.

### Deprecated: `react-test-renderer`[](#deprecated-react-test-renderer "Link for this heading")

We are deprecating `react-test-renderer` because it implements its own renderer environment that doesn’t match the environment users use, promotes testing implementation details, and relies on introspection of React’s internals.

The test renderer was created before there were more viable testing strategies available like [React Testing Library](https://testing-library.com), and we now recommend using a modern testing library instead.

In React 19, `react-test-renderer` logs a deprecation warning, and has switched to concurrent rendering. We recommend migrating your tests to [@testing-library/react](https://testing-library.com/docs/react-testing-library/intro/) or [@testing-library/react-native](https://testing-library.com/docs/react-native-testing-library/intro) for a modern and well supported testing experience.

## Notable changes[](#notable-changes "Link for Notable changes ")

### StrictMode changes[](#strict-mode-improvements "Link for StrictMode changes ")

React 19 includes several fixes and improvements to Strict Mode.

When double rendering in Strict Mode in development, `useMemo` and `useCallback` will reuse the memoized results from the first render during the second render. Components that are already Strict Mode compatible should not notice a difference in behavior.

As with all Strict Mode behaviors, these features are designed to proactively surface bugs in your components during development so you can fix them before they are shipped to production. For example, during development, Strict Mode will double-invoke ref callback functions on initial mount, to simulate what happens when a mounted component is replaced by a Suspense fallback.

### Improvements to Suspense[](#improvements-to-suspense "Link for Improvements to Suspense ")

In React 19, when a component suspends, React will immediately commit the fallback of the nearest Suspense boundary without waiting for the entire sibling tree to render. After the fallback commits, React schedules another render for the suspended siblings to “pre-warm” lazy requests in the rest of the tree:

Previously, when a component suspended, the suspended siblings were rendered and then the fallback was committed.

In React 19, when a component suspends, the fallback is committed and then the suspended siblings are rendered.

This change means Suspense fallbacks display faster, while still warming lazy requests in the suspended tree.

### UMD builds removed[](#umd-builds-removed "Link for UMD builds removed ")

UMD was widely used in the past as a convenient way to load React without a build step. Now, there are modern alternatives for loading modules as scripts in HTML documents. Starting with React 19, React will no longer produce UMD builds to reduce the complexity of its testing and release process.

To load React 19 with a script tag, we recommend using an ESM-based CDN such as [esm.sh](https://esm.sh/).

```
<script type="module">

  import React from "https://esm.sh/react@19/?dev"

  import ReactDOMClient from "https://esm.sh/react-dom@19/client?dev"

  ...

</script>
```

### Libraries depending on React internals may block upgrades[](#libraries-depending-on-react-internals-may-block-upgrades "Link for Libraries depending on React internals may block upgrades ")

This release includes changes to React internals that may impact libraries that ignore our pleas to not use internals like `SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED`. These changes are necessary to land improvements in React 19, and will not break libraries that follow our guidelines.

Based on our [Versioning Policy](https://react.dev/community/versioning-policy#what-counts-as-a-breaking-change), these updates are not listed as breaking changes, and we are not including docs for how to upgrade them. The recommendation is to remove any code that depends on internals.

To reflect the impact of using internals, we have renamed the `SECRET_INTERNALS` suffix to:

`_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE`

In the future we will more aggressively block accessing internals from React to discourage usage and ensure users are not blocked from upgrading.

## TypeScript changes[](#typescript-changes "Link for TypeScript changes ")

### Removed deprecated TypeScript types[](#removed-deprecated-typescript-types "Link for Removed deprecated TypeScript types ")

We’ve cleaned up the TypeScript types based on the removed APIs in React 19. Some of the removed have types been moved to more relevant packages, and others are no longer needed to describe React’s behavior.

### Note

We’ve published [`types-react-codemod`](https://github.com/eps1lon/types-react-codemod/) to migrate most type related breaking changes:

```
npx types-react-codemod@latest preset-19 ./path-to-app
```

If you have a lot of unsound access to `element.props`, you can run this additional codemod:

```
npx types-react-codemod@latest react-element-default-any-props ./path-to-your-react-ts-files
```

Check out [`types-react-codemod`](https://github.com/eps1lon/types-react-codemod/) for a list of supported replacements. If you feel a codemod is missing, it can be tracked in the [list of missing React 19 codemods](https://github.com/eps1lon/types-react-codemod/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A%22React+19%22+label%3Aenhancement).

### `ref` cleanups required[](#ref-cleanup-required "Link for this heading")

*This change is included in the `react-19` codemod preset as [`no-implicit-ref-callback-return `](https://github.com/eps1lon/types-react-codemod/#no-implicit-ref-callback-return).*

Due to the introduction of ref cleanup functions, returning anything else from a ref callback will now be rejected by TypeScript. The fix is usually to stop using implicit returns:

```
- <div ref={current => (instance = current)} />

+ <div ref={current => {instance = current}} />
```

The original code returned the instance of the `HTMLDivElement` and TypeScript wouldn’t know if this was supposed to be a cleanup function or not.

### `useRef` requires an argument[](#useref-requires-argument "Link for this heading")

*This change is included in the `react-19` codemod preset as [`refobject-defaults`](https://github.com/eps1lon/types-react-codemod/#refobject-defaults).*

A long-time complaint of how TypeScript and React work has been `useRef`. We’ve changed the types so that `useRef` now requires an argument. This significantly simplifies its type signature. It’ll now behave more like `createContext`.

```
// @ts-expect-error: Expected 1 argument but saw none

useRef();

// Passes

useRef(undefined);

// @ts-expect-error: Expected 1 argument but saw none

createContext();

// Passes

createContext(undefined);
```

This now also means that all refs are mutable. You’ll no longer hit the issue where you can’t mutate a ref because you initialised it with `null`:

```
const ref = useRef<number>(null);



// Cannot assign to 'current' because it is a read-only property

ref.current = 1;
```

`MutableRef` is now deprecated in favor of a single `RefObject` type which `useRef` will always return:

```
interface RefObject<T> {

  current: T

}



declare function useRef<T>: RefObject<T>
```

`useRef` still has a convenience overload for `useRef<T>(null)` that automatically returns `RefObject<T | null>`. To ease migration due to the required argument for `useRef`, a convenience overload for `useRef(undefined)` was added that automatically returns `RefObject<T | undefined>`.

Check out [\[RFC\] Make all refs mutable](https://github.com/DefinitelyTyped/DefinitelyTyped/pull/64772) for prior discussions about this change.

### Changes to the `ReactElement` TypeScript type[](#changes-to-the-reactelement-typescript-type "Link for this heading")

*This change is included in the [`react-element-default-any-props`](https://github.com/eps1lon/types-react-codemod#react-element-default-any-props) codemod.*

The `props` of React elements now default to `unknown` instead of `any` if the element is typed as `ReactElement`. This does not affect you if you pass a type argument to `ReactElement`:

```
type Example2 = ReactElement<{ id: string }>["props"];

//   ^? { id: string }
```

But if you relied on the default, you now have to handle `unknown`:

```
type Example = ReactElement["props"];

//   ^? Before, was 'any', now 'unknown'
```

You should only need it if you have a lot of legacy code relying on unsound access of element props. Element introspection only exists as an escape hatch, and you should make it explicit that your props access is unsound via an explicit `any`.

### The JSX namespace in TypeScript[](#the-jsx-namespace-in-typescript "Link for The JSX namespace in TypeScript ")

This change is included in the `react-19` codemod preset as [`scoped-jsx`](https://github.com/eps1lon/types-react-codemod#scoped-jsx)

A long-time request is to remove the global `JSX` namespace from our types in favor of `React.JSX`. This helps prevent pollution of global types which prevents conflicts between different UI libraries that leverage JSX.

You’ll now need to wrap module augmentation of the JSX namespace in \`declare module ”…”:

```
// global.d.ts

+ declare module "react" {

    namespace JSX {

      interface IntrinsicElements {

        "my-element": {

          myElementProps: string;

        };

      }

    }

+ }
```

The exact module specifier depends on the JSX runtime you specified in the `compilerOptions` of your `tsconfig.json`:

* For `"jsx": "react-jsx"` it would be `react/jsx-runtime`.
* For `"jsx": "react-jsxdev"` it would be `react/jsx-dev-runtime`.
* For `"jsx": "react"` and `"jsx": "preserve"` it would be `react`.

### Better `useReducer` typings[](#better-usereducer-typings "Link for this heading")

`useReducer` now has improved type inference thanks to [@mfp22](https://github.com/mfp22).

However, this required a breaking change where `useReducer` doesn’t accept the full reducer type as a type parameter but instead either needs none (and rely on contextual typing) or needs both the state and action type.

The new best practice is *not* to pass type arguments to `useReducer`.

```
- useReducer<React.Reducer<State, Action>>(reducer)

+ useReducer(reducer)
```

This may not work in edge cases where you can explicitly type the state and action, by passing in the `Action` in a tuple:

```
- useReducer<React.Reducer<State, Action>>(reducer)

+ useReducer<State, [Action]>(reducer)
```

If you define the reducer inline, we encourage to annotate the function parameters instead:

```
- useReducer<React.Reducer<State, Action>>((state, action) => state)

+ useReducer((state: State, action: Action) => state)
```

This is also what you’d also have to do if you move the reducer outside of the `useReducer` call:

```
const reducer = (state: State, action: Action) => state;
```

## Changelog[](#changelog "Link for Changelog ")

### Other breaking changes[](#other-breaking-changes "Link for Other breaking changes ")

* **react-dom**: Error for javascript URLs in `src` and `href` [#26507](https://github.com/facebook/react/pull/26507)
* **react-dom**: Remove `errorInfo.digest` from `onRecoverableError` [#28222](https://github.com/facebook/react/pull/28222)
* **react-dom**: Remove `unstable_flushControlled` [#26397](https://github.com/facebook/react/pull/26397)
* **react-dom**: Remove `unstable_createEventHandle` [#28271](https://github.com/facebook/react/pull/28271)
* **react-dom**: Remove `unstable_renderSubtreeIntoContainer` [#28271](https://github.com/facebook/react/pull/28271)
* **react-dom**: Remove `unstable_runWithPriority` [#28271](https://github.com/facebook/react/pull/28271)
* **react-is**: Remove deprecated methods from `react-is` [28224](https://github.com/facebook/react/pull/28224)

### Other notable changes[](#other-notable-changes "Link for Other notable changes ")

* **react**: Batch sync, default and continuous lanes [#25700](https://github.com/facebook/react/pull/25700)
* **react**: Don’t prerender siblings of suspended component [#26380](https://github.com/facebook/react/pull/26380)
* **react**: Detect infinite update loops caused by render phase updates [#26625](https://github.com/facebook/react/pull/26625)
* **react-dom**: Transitions in popstate are now synchronous [#26025](https://github.com/facebook/react/pull/26025)
* **react-dom**: Remove layout effect warning during SSR [#26395](https://github.com/facebook/react/pull/26395)
* **react-dom**: Warn and don’t set empty string for src/href (except anchor tags) [#28124](https://github.com/facebook/react/pull/28124)

For a full list of changes, please see the [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md#1900-december-5-2024).

***

Thanks to [Andrew Clark](https://twitter.com/acdlite), [Eli White](https://twitter.com/Eli_White), [Jack Pope](https://github.com/jackpope), [Jan Kassens](https://github.com/kassens), [Josh Story](https://twitter.com/joshcstory), [Matt Carroll](https://twitter.com/mattcarrollcode), [Noah Lemen](https://twitter.com/noahlemen), [Sophie Alpert](https://twitter.com/sophiebits), and [Sebastian Silbermann](https://twitter.com/sebsilbermann) for reviewing and editing this post.

[PreviousReact 19 RC](/blog/2024/04/25/react-19)

[NextReact Labs: What We've Been Working On – February 2024](/blog/2024/02/15/react-labs-what-we-have-been-working-on-february-2024)

***

----
url: https://react.dev/reference/react-dom/components/link
----

[API Reference](/reference/react)

[Components](/reference/react-dom/components)

# \<link>[](#undefined "Link for this heading")

The [built-in browser `<link>` component](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link) lets you use external resources such as stylesheets or annotate the document with link metadata.

```
<link rel="icon" href="favicon.ico" />
```

***

## Reference[](#reference "Link for Reference ")

### `<link>`[](#link "Link for this heading")

To link to external resources such as stylesheets, fonts, and icons, or to annotate the document with link metadata, render the [built-in browser `<link>` component](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link). You can render `<link>` from any component and React will [in most cases](#special-rendering-behavior) place the corresponding DOM element in the document head.

```
<link rel="icon" href="favicon.ico" />
```

[See more examples below.](#usage)

#### Props[](#props "Link for Props ")

`<link>` supports all [common element props.](/reference/react-dom/components/common#common-props)

***

## Usage[](#usage "Link for Usage ")

### Linking to related resources[](#linking-to-related-resources "Link for Linking to related resources ")

You can annotate the document with links to related resources such as an icon, canonical URL, or pingback. React will place this metadata within the document `<head>` regardless of where in the React tree it is rendered.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import ShowRenderedHTML from './ShowRenderedHTML.js';

export default function BlogPage() {
  return (
    <ShowRenderedHTML>
      <link rel="icon" href="favicon.ico" />
      <link rel="pingback" href="http://www.example.com/xmlrpc.php" />
      <h1>My Blog</h1>
      <p>...</p>
    </ShowRenderedHTML>
  );
}
```

### Linking to a stylesheet[](#linking-to-a-stylesheet "Link for Linking to a stylesheet ")

If a component depends on a certain stylesheet in order to be displayed correctly, you can render a link to that stylesheet within the component. Your component will [suspend](/reference/react/Suspense) while the stylesheet is loading. You must supply the `precedence` prop, which tells React where to place this stylesheet relative to others — stylesheets with higher precedence can override those with lower precedence.

### Note

When you want to use a stylesheet, it can be beneficial to call the [preinit](/reference/react-dom/preinit) function. Calling this function may allow the browser to start fetching the stylesheet earlier than if you just render a `<link>` component, for example by sending an [HTTP Early Hints response](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/103).

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import ShowRenderedHTML from './ShowRenderedHTML.js';

export default function SiteMapPage() {
  return (
    <ShowRenderedHTML>
      <link rel="stylesheet" href="sitemap.css" precedence="medium" />
      <p>...</p>
    </ShowRenderedHTML>
  );
}
```

### Controlling stylesheet precedence[](#controlling-stylesheet-precedence "Link for Controlling stylesheet precedence ")

Stylesheets can conflict with each other, and when they do, the browser goes with the one that comes later in the document. React lets you control the order of stylesheets with the `precedence` prop. In this example, three components render stylesheets, and the ones with the same precedence are grouped together in the `<head>`.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import ShowRenderedHTML from './ShowRenderedHTML.js';

export default function HomePage() {
  return (
    <ShowRenderedHTML>
      <FirstComponent />
      <SecondComponent />
      <ThirdComponent/>
      ...
    </ShowRenderedHTML>
  );
}

function FirstComponent() {
  return <link rel="stylesheet" href="first.css" precedence="first" />;
}

function SecondComponent() {
  return <link rel="stylesheet" href="second.css" precedence="second" />;
}

function ThirdComponent() {
  return <link rel="stylesheet" href="third.css" precedence="first" />;
}
```

Note the `precedence` values themselves are arbitrary and their naming is up to you. React will infer that precedence values it discovers first are “lower” and precedence values it discovers later are “higher”.

### Deduplicated stylesheet rendering[](#deduplicated-stylesheet-rendering "Link for Deduplicated stylesheet rendering ")

If you render the same stylesheet from multiple components, React will place only a single `<link>` in the document head.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import ShowRenderedHTML from './ShowRenderedHTML.js';

export default function HomePage() {
  return (
    <ShowRenderedHTML>
      <Component />
      <Component />
      ...
    </ShowRenderedHTML>
  );
}

function Component() {
  return <link rel="stylesheet" href="styles.css" precedence="medium" />;
}
```

### Annotating specific items within the document with links[](#annotating-specific-items-within-the-document-with-links "Link for Annotating specific items within the document with links ")

You can use the `<link>` component with the `itemProp` prop to annotate specific items within the document with links to related resources. In this case, React will *not* place these annotations within the document `<head>` but will place them like any other React component.

```
<section itemScope>

  <h3>Annotating specific items</h3>

  <link itemProp="author" href="http://example.com/" />

  <p>...</p>

</section>
```

[Previous\<textarea>](/reference/react-dom/components/textarea)

[Next\<meta>](/reference/react-dom/components/meta)

***

----
url: https://18.react.dev/reference/react/lazy
----

[API Reference](/reference/react)

[APIs](/reference/react/apis)

# lazy[](#undefined "Link for this heading")

`lazy` lets you defer loading component’s code until it is rendered for the first time.

```
const SomeComponent = lazy(load)
```

***

## Reference[](#reference "Link for Reference ")

### `lazy(load)`[](#lazy "Link for this heading")

Call `lazy` outside your components to declare a lazy-loaded React component:

```
import { lazy } from 'react';



const MarkdownPreview = lazy(() => import('./MarkdownPreview.js'));
```

[See more examples below.](#usage)

#### Parameters[](#parameters "Link for Parameters ")

* `load`: A function that returns a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) or another *thenable* (a Promise-like object with a `then` method). React will not call `load` until the first time you attempt to render the returned component. After React first calls `load`, it will wait for it to resolve, and then render the resolved value’s `.default` as a React component. Both the returned Promise and the Promise’s resolved value will be cached, so React will not call `load` more than once. If the Promise rejects, React will `throw` the rejection reason for the nearest Error Boundary to handle.

#### Returns[](#returns "Link for Returns ")

`lazy` returns a React component you can render in your tree. While the code for the lazy component is still loading, attempting to render it will *suspend.* Use [`<Suspense>`](/reference/react/Suspense) to display a loading indicator while it’s loading.

***

### `load` function[](#load "Link for this heading")

#### Parameters[](#load-parameters "Link for Parameters ")

`load` receives no parameters.

#### Returns[](#load-returns "Link for Returns ")

You need to return a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) or some other *thenable* (a Promise-like object with a `then` method). It needs to eventually resolve to an object whose `.default` property is a valid React component type, such as a function, [`memo`](/reference/react/memo), or a [`forwardRef`](/reference/react/forwardRef) component.

***

## Usage[](#usage "Link for Usage ")

### Lazy-loading components with Suspense[](#suspense-for-code-splitting "Link for Lazy-loading components with Suspense ")

Usually, you import components with the static [`import`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import) declaration:

```
import MarkdownPreview from './MarkdownPreview.js';
```

To defer loading this component’s code until it’s rendered for the first time, replace this import with:

```
import { lazy } from 'react';



const MarkdownPreview = lazy(() => import('./MarkdownPreview.js'));
```

This code relies on [dynamic `import()`,](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import) which might require support from your bundler or framework. Using this pattern requires that the lazy component you’re importing was exported as the `default` export.

Now that your component’s code loads on demand, you also need to specify what should be displayed while it is loading. You can do this by wrapping the lazy component or any of its parents into a [`<Suspense>`](/reference/react/Suspense) boundary:

```
<Suspense fallback={<Loading />}>

  <h2>Preview</h2>

  <MarkdownPreview />

</Suspense>
```

In this example, the code for `MarkdownPreview` won’t be loaded until you attempt to render it. If `MarkdownPreview` hasn’t loaded yet, `Loading` will be shown in its place. Try ticking the checkbox:

```
import { useState, Suspense, lazy } from 'react';
import Loading from './Loading.js';

const MarkdownPreview = lazy(() => delayForDemo(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>
      )}
    </>
  );
}

// Add a fixed delay so you can see the loading state
function delayForDemo(promise) {
  return new Promise(resolve => {
    setTimeout(resolve, 2000);
  }).then(() => promise);
}
```

This demo loads with an artificial delay. The next time you untick and tick the checkbox, `Preview` will be cached, so there will be no loading state. To see the loading state again, click “Reset” on the sandbox.

[Learn more about managing loading states with Suspense.](/reference/react/Suspense)

***

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### My `lazy` component’s state gets reset unexpectedly[](#my-lazy-components-state-gets-reset-unexpectedly "Link for this heading")

Do not declare `lazy` components *inside* other components:

```
import { lazy } from 'react';



function Editor() {

  // 🔴 Bad: This will cause all state to be reset on re-renders

  const MarkdownPreview = lazy(() => import('./MarkdownPreview.js'));

  // ...

}
```

Instead, always declare them at the top level of your module:

```
import { lazy } from 'react';



// ✅ Good: Declare lazy components outside of your components

const MarkdownPreview = lazy(() => import('./MarkdownPreview.js'));



function Editor() {

  // ...

}
```

[PreviousforwardRef](/reference/react/forwardRef)

[Nextmemo](/reference/react/memo)

***

----
url: https://legacy.reactjs.org/docs/react-dom-server.html
----

> These docs are old and won’t be updated. Go to [react.dev](https://react.dev/) for the new React docs.
>
> These new documentation pages teach modern React:
>
> * [`react-dom`: Server APIs](https://react.dev/reference/react-dom/server)

The `ReactDOMServer` object enables you to render components to static markup. Typically, it’s used on a Node server:

```
// ES modules
import * as ReactDOMServer from 'react-dom/server';
// CommonJS
var ReactDOMServer = require('react-dom/server');
```

## [](#overview)Overview

These methods are only available in the **environments with [Node.js Streams](https://nodejs.org/api/stream.html):**

* [`renderToPipeableStream()`](#rendertopipeablestream)
* [`renderToNodeStream()`](#rendertonodestream) (Deprecated)
* [`renderToStaticNodeStream()`](#rendertostaticnodestream)

These methods are only available in the **environments with [Web Streams](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API)** (this includes browsers, Deno, and some modern edge runtimes):

* [`renderToReadableStream()`](#rendertoreadablestream)

The following methods can be used in the environments that don’t support streams:

* [`renderToString()`](#rendertostring)
* [`renderToStaticMarkup()`](#rendertostaticmarkup)

## [](#reference)Reference

### [](#rendertopipeablestream)`renderToPipeableStream()`

> This content is out of date.
>
> Read the new React documentation for [`renderToPipeableStream`](https://react.dev/reference/react-dom/server/renderToPipeableStream).

```
ReactDOMServer.renderToPipeableStream(element, options)
```

Render a React element to its initial HTML. Returns a stream with a `pipe(res)` method to pipe the output and `abort()` to abort the request. Fully supports Suspense and streaming of HTML with “delayed” content blocks “popping in” via inline `<script>` tags later. [Read more](https://github.com/reactwg/react-18/discussions/37)

If you call [`ReactDOM.hydrateRoot()`](/docs/react-dom-client.html#hydrateroot) on a node that already has this server-rendered markup, React will preserve it and only attach event handlers, allowing you to have a very performant first-load experience.

```
let didError = false;
const stream = renderToPipeableStream(
  <App />,
  {
    onShellReady() {
      // The content above all Suspense boundaries is ready.
      // If something errored before we started streaming, we set the error code appropriately.
      res.statusCode = didError ? 500 : 200;
      res.setHeader('Content-type', 'text/html');
      stream.pipe(res);
    },
    onShellError(error) {
      // Something errored before we could complete the shell so we emit an alternative shell.
      res.statusCode = 500;
      res.send(
        '<!doctype html><p>Loading...</p><script src="clientrender.js"></script>'
      );
    },
    onAllReady() {
      // If you don't want streaming, use this instead of onShellReady.
      // This will fire after the entire page content is ready.
      // You can use this for crawlers or static generation.

      // res.statusCode = didError ? 500 : 200;
      // res.setHeader('Content-type', 'text/html');
      // stream.pipe(res);
    },
    onError(err) {
      didError = true;
      console.error(err);
    },
  }
);
```

See the [full list of options](https://github.com/facebook/react/blob/14c2be8dac2d5482fda8a0906a31d239df8551fc/packages/react-dom/src/server/ReactDOMFizzServerNode.js#L36-L46).

> Note:
>
> This is a Node.js-specific API. Environments with [Web Streams](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API), like Deno and modern edge runtimes, should use [`renderToReadableStream`](#rendertoreadablestream) instead.

***

### [](#rendertoreadablestream)`renderToReadableStream()`

> This content is out of date.
>
> Read the new React documentation for [`renderToReadableStream`](https://react.dev/reference/react-dom/server/renderToReadableStream).

```
ReactDOMServer.renderToReadableStream(element, options);
```

Streams a React element to its initial HTML. Returns a Promise that resolves to a [Readable Stream](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream). Fully supports Suspense and streaming of HTML. [Read more](https://github.com/reactwg/react-18/discussions/127)

If you call [`ReactDOM.hydrateRoot()`](/docs/react-dom-client.html#hydrateroot) on a node that already has this server-rendered markup, React will preserve it and only attach event handlers, allowing you to have a very performant first-load experience.

```
let controller = new AbortController();
let didError = false;
try {
  let stream = await renderToReadableStream(
    <html>
      <body>Success</body>
    </html>,
    {
      signal: controller.signal,
      onError(error) {
        didError = true;
        console.error(error);
      }
    }
  );
  
  // This is to wait for all Suspense boundaries to be ready. You can uncomment
  // this line if you want to buffer the entire HTML instead of streaming it.
  // You can use this for crawlers or static generation:

  // await stream.allReady;

  return new Response(stream, {
    status: didError ? 500 : 200,
    headers: {'Content-Type': 'text/html'},
  });
} catch (error) {
  return new Response(
    '<!doctype html><p>Loading...</p><script src="clientrender.js"></script>',
    {
      status: 500,
      headers: {'Content-Type': 'text/html'},
    }
  );
}
```

See the [full list of options](https://github.com/facebook/react/blob/14c2be8dac2d5482fda8a0906a31d239df8551fc/packages/react-dom/src/server/ReactDOMFizzServerBrowser.js#L27-L35).

> Note:
>
> This API depends on [Web Streams](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API). For Node.js, use [`renderToPipeableStream`](#rendertopipeablestream) instead.

***

### [](#rendertonodestream)`renderToNodeStream()` (Deprecated)

> This content is out of date.
>
> Read the new React documentation for [`renderToNodeStream`](https://react.dev/reference/react-dom/server/renderToNodeStream).

```
ReactDOMServer.renderToNodeStream(element)
```

Render a React element to its initial HTML. Returns a [Node.js Readable stream](https://nodejs.org/api/stream.html#stream_readable_streams) that outputs an HTML string. The HTML output by this stream is exactly equal to what [`ReactDOMServer.renderToString`](#rendertostring) would return. You can use this method to generate HTML on the server and send the markup down on the initial request for faster page loads and to allow search engines to crawl your pages for SEO purposes.

If you call [`ReactDOM.hydrateRoot()`](/docs/react-dom-client.html#hydrateroot) on a node that already has this server-rendered markup, React will preserve it and only attach event handlers, allowing you to have a very performant first-load experience.

> Note:
>
> Server-only. This API is not available in the browser.
>
> The stream returned from this method will return a byte stream encoded in utf-8. If you need a stream in another encoding, take a look at a project like [iconv-lite](https://www.npmjs.com/package/iconv-lite), which provides transform streams for transcoding text.

***

### [](#rendertostaticnodestream)`renderToStaticNodeStream()`

> This content is out of date.
>
> Read the new React documentation for [`renderToStaticNodeStream`](https://react.dev/reference/react-dom/server/renderToStaticNodeStream).

```
ReactDOMServer.renderToStaticNodeStream(element)
```

Similar to [`renderToNodeStream`](#rendertonodestream), except this doesn’t create extra DOM attributes that React uses internally, such as `data-reactroot`. This is useful if you want to use React as a simple static page generator, as stripping away the extra attributes can save some bytes.

The HTML output by this stream is exactly equal to what [`ReactDOMServer.renderToStaticMarkup`](#rendertostaticmarkup) would return.

If you plan to use React on the client to make the markup interactive, do not use this method. Instead, use [`renderToNodeStream`](#rendertonodestream) on the server and [`ReactDOM.hydrateRoot()`](/docs/react-dom-client.html#hydrateroot) on the client.

> Note:
>
> Server-only. This API is not available in the browser.
>
> The stream returned from this method will return a byte stream encoded in utf-8. If you need a stream in another encoding, take a look at a project like [iconv-lite](https://www.npmjs.com/package/iconv-lite), which provides transform streams for transcoding text.

***

### [](#rendertostring)`renderToString()`

> This content is out of date.
>
> Read the new React documentation for [`renderToString`](https://react.dev/reference/react-dom/server/renderToString).

```
ReactDOMServer.renderToString(element)
```

Render a React element to its initial HTML. React will return an HTML string. You can use this method to generate HTML on the server and send the markup down on the initial request for faster page loads and to allow search engines to crawl your pages for SEO purposes.

If you call [`ReactDOM.hydrateRoot()`](/docs/react-dom-client.html#hydrateroot) on a node that already has this server-rendered markup, React will preserve it and only attach event handlers, allowing you to have a very performant first-load experience.

> Note
>
> This API has limited Suspense support and does not support streaming.
>
> On the server, it is recommended to use either [`renderToPipeableStream`](#rendertopipeablestream) (for Node.js) or [`renderToReadableStream`](#rendertoreadablestream) (for Web Streams) instead.

***

### [](#rendertostaticmarkup)`renderToStaticMarkup()`

> This content is out of date.
>
> Read the new React documentation for [`renderToStaticMarkup`](https://react.dev/reference/react-dom/server/renderToStaticMarkup).

```
ReactDOMServer.renderToStaticMarkup(element)
```

Similar to [`renderToString`](#rendertostring), except this doesn’t create extra DOM attributes that React uses internally, such as `data-reactroot`. This is useful if you want to use React as a simple static page generator, as stripping away the extra attributes can save some bytes.

If you plan to use React on the client to make the markup interactive, do not use this method. Instead, use [`renderToString`](#rendertostring) on the server and [`ReactDOM.hydrateRoot()`](/docs/react-dom-client.html#hydrateroot) on the client.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/reference-react-dom-server.md)

----
url: https://legacy.reactjs.org/blog/2022/06/15/react-labs-what-we-have-been-working-on-june-2022.html
----

June 15, 2022 by [Andrew Clark](https://twitter.com/acdlite), [Dan Abramov](https://twitter.com/dan_abramov), [Jan Kassens](https://twitter.com/kassens), [Joseph Savona](https://twitter.com/en_JS), [Josh Story](https://twitter.com/joshcstory), [Lauren Tan](https://twitter.com/potetotes), [Luna Ruan](https://twitter.com/lunaruan), [Mengdi Chen](https://twitter.com/mengdi_en), [Rick Hanlon](https://twitter.com/rickhanlonii), [Robert Zhang](https://twitter.com/jiaxuanzhang01), [Sathya Gunasekaran](https://twitter.com/_gsathya), [Sebastian Markbåge](https://twitter.com/sebmarkbage), and [Xuan Huang](https://twitter.com/Huxpro)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

[React 18](https://reactjs.org/blog/2022/03/29/react-v18.html) was years in the making, and with it brought valuable lessons for the React team. Its release was the result of many years of research and exploring many paths. Some of those paths were successful; many more were dead-ends that led to new insights. One lesson we’ve learned is that it’s frustrating for the community to wait for new features without having insight into these paths that we’re exploring.

We typically have a number of projects being worked on at any time, ranging from the more experimental to the clearly defined. Looking ahead, we’d like to start regularly sharing more about what we’ve been working on with the community across these projects.

To set expectations, this is not a roadmap with clear timelines. Many of these projects are under active research and are difficult to put concrete ship dates on. They may possibly never even ship in their current iteration depending on what we learn. Instead, we want to share with you the problem spaces we’re actively thinking about, and what we’ve learned so far.

## [](#server-components)Server Components

We announced an [experimental demo of React Server Components](https://reactjs.org/blog/2020/12/21/data-fetching-with-react-server-components.html) (RSC) in December 2020. Since then we’ve been finishing up its dependencies in React 18, and working on changes inspired by experimental feedback.

In particular, we’re abandoning the idea of having forked I/O libraries (eg react-fetch), and instead adopting an async/await model for better compatibility. This doesn’t technically block RSC’s release because you can also use routers for data fetching. Another change is that we’re also moving away from the file extension approach in favor of [annotating boundaries](https://github.com/reactjs/rfcs/pull/189#issuecomment-1116482278).

We’re working together with Vercel and Shopify to unify bundler support for shared semantics in both Webpack and Vite. Before launch, we want to make sure that the semantics of RSCs are the same across the whole React ecosystem. This is the major blocker for reaching stable.

## [](#asset-loading)Asset Loading

Currently, assets like scripts, external styles, fonts, and images are typically preloaded and loaded using external systems. This can make it tricky to coordinate across new environments like streaming, server components, and more. We’re looking at adding APIs to preload and load deduplicated external assets through React APIs that work in all React environments.

We’re also looking at having these support Suspense so you can have images, CSS, and fonts that block display until they’re loaded but don’t block streaming and concurrent rendering. This can help avoid [“popcorning“](https://twitter.com/sebmarkbage/status/1516852731251724293) as the visuals pop and layout shifts.

## [](#static-server-rendering-optimizations)Static Server Rendering Optimizations

Static Site Generation (SSG) and Incremental Static Regeneration (ISR) are great ways to get performance for cacheable pages, but we think we can add features to improve performance of dynamic Server Side Rendering (SSR) – especially when most but not all of the content is cacheable. We’re exploring ways to optimize server rendering utilizing compilation and static passes.

## [](#react-compiler)React Optimizing Compiler

We gave an [early preview](https://www.youtube.com/watch?v=lGEMwh32soc) of React Forget at React Conf 2021. It’s a compiler that automatically generates the equivalent of `useMemo` and `useCallback` calls to minimize the cost of re-rendering, while retaining React’s programming model.

Recently, we finished a rewrite of the compiler to make it more reliable and capable. This new architecture allows us to analyze and memoize more complex patterns such as the use of [local mutations](https://react.dev/learn/keeping-components-pure#local-mutation-your-components-little-secret), and opens up many new compile-time optimization opportunities beyond just being on par with memoization hooks.

We’re also working on a playground for exploring many aspects of the compiler. While the goal of the playground is to make development of the compiler easier, we think that it will make it easier to try it out and build intuition for what the compiler does. It reveals various insights into how it works under the hood, and live renders the compiler’s outputs as you type. This will be shipped together with the compiler when it’s released.

## [](#offscreen)Offscreen

## [](#transition-tracing)Transition Tracing

Currently, React has two profiling tools. The [original Profiler](https://reactjs.org/blog/2018/09/10/introducing-the-react-profiler.html) shows an overview of all the commits in a profiling session. For each commit, it also shows all components that rendered and the amount of time it took for them to render. We also have a beta version of a [Timeline Profiler](https://github.com/reactwg/react-18/discussions/76) introduced in React 18 that shows when components schedule updates and when React works on these updates. Both of these profilers help developers identify performance problems in their code.

We’ve realized that developers don’t find knowing about individual slow commits or components out of context that useful. It’s more useful to know about what actually causes the slow commits. And that developers want to be able to track specific interactions (eg a button click, an initial load, or a page navigation) to watch for performance regressions and to understand why an interaction was slow and how to fix it.

We previously tried to solve this issue by creating an [Interaction Tracing API](https://gist.github.com/bvaughn/8de925562903afd2e7a12554adcdda16), but it had some fundamental design flaws that reduced the accuracy of tracking why an interaction was slow and sometimes resulted in interactions never ending. We ended up [removing this API](https://github.com/facebook/react/pull/20037) because of these issues.

We are working on a new version for the Interaction Tracing API (tentatively called Transition Tracing because it is initiated via `startTransition`) that solves these problems.

## [](#new-react-docs)New React Docs

Last year, we announced the [beta version](https://react.dev/) of the new React documentation website. The new learning materials teach Hooks first and has new diagrams, illustrations, as well as many interactive examples and challenges. We took a break from that work to focus on the React 18 release, but now that React 18 is out, we’re actively working to finish and ship the new documentation.

We are currently writing a detailed section about effects, as we’ve heard that is one of the more challenging topics for both new and experienced React users. [Synchronizing with Effects](https://react.dev/learn/synchronizing-with-effects) is the first published page in the series, and there are more to come in the following weeks. When we first started writing a detailed section about effects, we’ve realized that many common effect patterns can be simplified by adding a new primitive to React. We’ve shared some initial thoughts on that in the [useEvent RFC](https://github.com/reactjs/rfcs/pull/220). It is currently in early research, and we are still iterating on the idea. We appreciate the community’s comments on the RFC so far, as well as the [feedback](https://github.com/reactjs/reactjs.org/issues/3308) and contributions to the ongoing documentation rewrite. We’d specifically like to thank [Harish Kumar](https://github.com/harish-sethuraman) for submitting and reviewing many improvements to the new website implementation.

*Thanks to [Sophie Alpert](https://twitter.com/sophiebits) for reviewing this blog post!*

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2022-06-15-react-labs-what-we-have-been-working-on-june-2022.md)

----
url: https://18.react.dev/learn/responding-to-events
----

[Fork](https://codesandbox.io/api/v1/sandboxes/define?parameters=N4IgZglgNgpgziAXKOAnAxgeggOwCYwAeAdAFYLIjoD2OALjPUiBALYAO1qdABAEowAhujoAaHsB4BlOqggiAstQI8AvjzCpqrHgB0QqISP0BuXTjaduEnukOCGfatV7rN2vQaN0AtHm2Y6FAQjHSm5pZcvPrEmHB0AJ6wcMTocHDhOBEcUTwAguzsGlo6MZgF7JnmNDjxPFouPAC8tvaOznQAFP7oAK6socQA5jB0AKKwA_QAQgkAknid-g1hIACUa2Y4K8SG-DCoSzg8PAA8MnKKyjAAfOYnJ6cVPJh3x2eYF_J0SgRvmyBRCw4NNcIJUAkkGBBFA4DBVED2MIANaCEZkOC0JCgGoMJiIEDAe6eHCCAb6RCeewiYgEABu-lExP0dIOcAgtApngADMRedzGcyQKxBLgufo4hhsPsSORBe99HA7BB2HQMkgJMSToq6ODVpTlt4fEq5Kq4Dx4nr5Q9PAAjXrQPDirzCXwmlVqnj2x3Wh76BjxZ3Ut3Ks08AO8Hw-Rh0prkfysX3akAwUgwYwaw2u42hz2p9OrYkIoUEdiMAg4dAhdWUonvZPB50APQAjAAOPl8pNUo0J5vtzsCwFanvZ91m5sAVkH-iLTIVIHpABEYGX9pXq1zgKpzKpAcDQaSIVCYXCESB2L1bcEsLgCCQABZ0VhQbFUWh4ujMU4AQiXAHkAGEABUAE0AAUxh4J8XzeU4YKgHgoEEHAhiafRGH0OCHyEPA3keAZdVsB9wThOh0JAABVYCADEfDbLDiVOQjBB4UkBgoukQgAdysVZbA_UIKO4iA8DoB8mnpeQYB8ESxIfcRcAgOgIBhHMYRgJoWy7EB8LOFS6FgG4l2oPopjoU5MAMozzEsnDBDw2zbWUBI9NOPAIDpHhRIolYsMsjy6TgzBnLwVzbMwBCbn3CAQTBY9EGhWF4SBNAsAqDE31xUJmCIPieAIaFeigXgwF6SsVNoHhpl6Og6FoTo1k1d5DDoXpUGOI4bVOe06toPSbTmAraAAcl4fweBQhJxNwIYR0s3r6pwPTNl3cwYrio9IUS08UpANK4kSZJUnSLLBPxEAACpmpOZzCGNCAAC9ZspZzUAIVAfDurYdyyHBQoSG6NA_HxoVYaAEkpOAULgY0DggMAthOEVUCGXBKQAJm5dhCCRngkTwDzUMpbkfvMcwHxbIGUbRnAfHq9gSbxsAQfZR6YExjGcbJv6Hwx6nwVp-nqEZnhSeJFn6Ae9nMex3G1t5gBmAXUdwYXRfF95JbdJ6OZ4dtuYVimABYVaFhmmYl1ndcpFsADZDZwX6KcnM21YtsXmetmX9eNx3nZwB87bdumPc1k5telvWWy5-WnfJytriByO2ej4gMZgVgefMYqgYJomhh8XBghwGTLW4WX_YTjbD3BbakrPc8GA4ZCGGYOwhAYHxgx8QRChAVQgA\&query=file%3D%252Fsrc%252FApp.js%26utm_medium%3Dsandpack\&environment=create-react-app "Open in CodeSandbox")

9

export default function Button() {

return (

\<button>

I don't do anything

\</button>

);

}



[Open Sandbox](https://codesandbox.io/api/v1/sandboxes/define?parameters=N4IgZglgNgpgziAXKOAnAxgeggOwCYwAeAdAFYLIjoD2OALjPUiBALYAO1qdABAEowAhujoAaHsB4BlOqggiAstQI8AvjzCpqrHgB0QqISP0BuXTjaduEnukOCGfatV7rN2vQaN0AtHm2Y6FAQjHSm5pZcvPrEmHB0AJ6wcMTocHDhOBEcUTwAguzsGlo6MZgF7JnmNDjxPFouPAC8tvaOznQAFP7oAK6socQA5jB0AKKwA_QAQgkAknid-g1hIACUa2Y4K8SG-DCoSzg8PAA8MnKKyjAAfOYnJ6cVPJh3x2eYF_J0SgRvmyBRCw4NNcIJUAkkGBBFA4DBVED2MIANaCEZkOC0JCgGoMJiIEDAe6eHCCAb6RCeewiYgEABu-lExP0dIOcAgtApngADMRedzGcyQKxBLgufo4hhsPsSORBe99HA7BB2HQMkgJMSToq6ODVpTlt4fEq5Kq4Dx4nr5Q9PAAjXrQPDirzCXwmlVqnj2x3Wh76BjxZ3Ut3Ks08AO8Hw-Rh0prkfysX3akAwUgwYwaw2u42hz2p9OrYkIoUEdiMAg4dAhdWUonvZPB50APQAjAAOPl8pNUo0J5vtzsCwFanvZ91m5sAVkH-iLTIVIHpABEYGX9pXq1zgKpzKpAcDQaSIVCYXCESB2L1bcEsLgCCQABZ0VhQbFUWh4ujMU4AQiXAHkAGEABUAE0AAUxh4J8XzeU4YKgHgoEEHAhiafRGH0OCHyEPA3keAZdVsB9wThOh0JAABVYCADEfDbLDiVOQjBB4UkBgoukQgAdysVZbA_UIKO4iA8DoB8mnpeQYB8ESxIfcRcAgOgIBhHMYRgJoWy7EB8LOFS6FgG4l2oPopjoU5MAMozzEsnDBDw2zbWUBI9NOPAIDpHhRIolYsMsjy6TgzBnLwVzbMwBCbn3CAQTBY9EGhWF4SBNAsAqDE31xUJmCIPieAIaFeigXgwF6SsVNoHhpl6Og6FoTo1k1d5DDoXpUGOI4bVOe06toPSbTmAraAAcl4fweBQhJxNwIYR0s3r6pwPTNl3cwYrio9IUS08UpANK4kSZJUnSLLBPxEAACpmpOZzCGNCAAC9ZspZzUAIVAfDurYdyyHBQoSG6NA_HxoVYaAEkpOAULgY0DggMAthOEVUCGXBKQAJm5dhCCRngkTwDzUMpbkfvMcwHxbIGUbRnAfHq9gSbxsAQfZR6YExjGcbJv6Hwx6nwVp-nqEZnhSeJFn6Ae9nMex3G1t5gBmAXUdwYXRfF95JbdJ6OZ4dtuYVimABYVaFhmmYl1ndcpFsADZDZwX6KcnM21YtsXmetmX9eNx3nZwB87bdumPc1k5telvWWy5-WnfJytriByO2ej4gMZgVgefMYqgYJomhh8XBghwGTLW4WX_YTjbD3BbakrPc8GA4ZCGGYOwhAYHxgx8QRChAVQgA\&query=file%3D%252Fsrc%252FApp.js%26utm_medium%3Dsandpack\&environment=create-react-app "Open in CodeSandbox")

You can make it show a message when a user clicks by following these three steps:

1. Declare a function called `handleClick` *inside* your `Button` component.
2. Implement the logic inside that function (use `alert` to show the message).
3. Add `onClick={handleClick}` to the `<button>` JSX.

```
export default function Button() {
  function handleClick() {
    alert('You clicked me!');
  }

  return (
    <button onClick={handleClick}>
      Click me
    </button>
  );
}
```

You defined the `handleClick` function and then [passed it as a prop](/learn/passing-props-to-a-component) to `<button>`. `handleClick` is an **event handler.** Event handler functions:

* Are usually defined *inside* your components.
* Have names that start with `handle`, followed by the name of the event.

By convention, it is common to name event handlers as `handle` followed by the event name. You’ll often see `onClick={handleClick}`, `onMouseEnter={handleMouseEnter}`, and so on.

Alternatively, you can define an event handler inline in the JSX:

```
<button onClick={function handleClick() {

  alert('You clicked me!');

}}>
```

Or, more concisely, using an arrow function:

```
<button onClick={() => {

  alert('You clicked me!');

}}>
```

All of these styles are equivalent. Inline event handlers are convenient for short functions.

### Pitfall

Functions passed to event handlers must be passed, not called. For example:

| passing a function (correct)     | calling a function (incorrect)     |
| -------------------------------- | ---------------------------------- |
| `<button onClick={handleClick}>` | `<button onClick={handleClick()}>` |

The difference is subtle. In the first example, the `handleClick` function is passed as an `onClick` event handler. This tells React to remember it and only call your function when the user clicks the button.

In the second example, the `()` at the end of `handleClick()` fires the function *immediately* during [rendering](/learn/render-and-commit), without any clicks. This is because JavaScript inside the [JSX `{` and `}`](/learn/javascript-in-jsx-with-curly-braces) executes right away.

When you write code inline, the same pitfall presents itself in a different way:

| passing a function (correct)            | calling a function (incorrect)    |
| --------------------------------------- | --------------------------------- |
| `<button onClick={() => alert('...')}>` | `<button onClick={alert('...')}>` |

Passing inline code like this won’t fire on click—it fires every time the component renders:

```
// This alert fires when the component renders, not when clicked!

<button onClick={alert('You clicked me!')}>
```

If you want to define your event handler inline, wrap it in an anonymous function like so:

```
<button onClick={() => alert('You clicked me!')}>
```

```
function AlertButton({ message, children }) {
  return (
    <button onClick={() => alert(message)}>
      {children}
    </button>
  );
}

export default function Toolbar() {
  return (
    <div>
      <AlertButton message="Playing!">
        Play Movie
      </AlertButton>
      <AlertButton message="Uploading!">
        Upload Image
      </AlertButton>
    </div>
  );
}
```

This lets these two buttons show different messages. Try changing the messages passed to them.

### Passing event handlers as props[](#passing-event-handlers-as-props "Link for Passing event handlers as props ")

Often you’ll want the parent component to specify a child’s event handler. Consider buttons: depending on where you’re using a `Button` component, you might want to execute a different function—perhaps one plays a movie and another uploads an image.

To do this, pass a prop the component receives from its parent as the event handler like so:

```
function Button({ onClick, children }) {
  return (
    <button onClick={onClick}>
      {children}
    </button>
  );
}

function PlayButton({ movieName }) {
  function handlePlayClick() {
    alert(`Playing ${movieName}!`);
  }

  return (
    <Button onClick={handlePlayClick}>
      Play "{movieName}"
    </Button>
  );
}

function UploadButton() {
  return (
    <Button onClick={() => alert('Uploading!')}>
      Upload Image
    </Button>
  );
}

export default function Toolbar() {
  return (
    <div>
      <PlayButton movieName="Kiki's Delivery Service" />
      <UploadButton />
    </div>
  );
}
```

```
function Button({ onSmash, children }) {
  return (
    <button onClick={onSmash}>
      {children}
    </button>
  );
}

export default function App() {
  return (
    <div>
      <Button onSmash={() => alert('Playing!')}>
        Play Movie
      </Button>
      <Button onSmash={() => alert('Uploading!')}>
        Upload Image
      </Button>
    </div>
  );
}
```

In this example, `<button onClick={onSmash}>` shows that the browser `<button>` (lowercase) still needs a prop called `onClick`, but the prop name received by your custom `Button` component is up to you!

When your component supports multiple interactions, you might name event handler props for app-specific concepts. For example, this `Toolbar` component receives `onPlayMovie` and `onUploadImage` event handlers:

```
export default function App() {
  return (
    <Toolbar
      onPlayMovie={() => alert('Playing!')}
      onUploadImage={() => alert('Uploading!')}
    />
  );
}

function Toolbar({ onPlayMovie, onUploadImage }) {
  return (
    <div>
      <Button onClick={onPlayMovie}>
        Play Movie
      </Button>
      <Button onClick={onUploadImage}>
        Upload Image
      </Button>
    </div>
  );
}

function Button({ onClick, children }) {
  return (
    <button onClick={onClick}>
      {children}
    </button>
  );
}
```

Notice how the `App` component does not need to know *what* `Toolbar` will do with `onPlayMovie` or `onUploadImage`. That’s an implementation detail of the `Toolbar`. Here, `Toolbar` passes them down as `onClick` handlers to its `Button`s, but it could later also trigger them on a keyboard shortcut. Naming props after app-specific interactions like `onPlayMovie` gives you the flexibility to change how they’re used later.

### Note

Make sure that you use the appropriate HTML tags for your event handlers. For example, to handle clicks, use [`<button onClick={handleClick}>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button) instead of `<div onClick={handleClick}>`. Using a real browser `<button>` enables built-in browser behaviors like keyboard navigation. If you don’t like the default browser styling of a button and want to make it look more like a link or a different UI element, you can achieve it with CSS. [Learn more about writing accessible markup.](https://developer.mozilla.org/en-US/docs/Learn/Accessibility/HTML)

## Event propagation[](#event-propagation "Link for Event propagation ")

Event handlers will also catch events from any children your component might have. We say that an event “bubbles” or “propagates” up the tree: it starts with where the event happened, and then goes up the tree.

This `<div>` contains two buttons. Both the `<div>` *and* each button have their own `onClick` handlers. Which handlers do you think will fire when you click a button?

```
export default function Toolbar() {
  return (
    <div className="Toolbar" onClick={() => {
      alert('You clicked on the toolbar!');
    }}>
      <button onClick={() => alert('Playing!')}>
        Play Movie
      </button>
      <button onClick={() => alert('Uploading!')}>
        Upload Image
      </button>
    </div>
  );
}
```

If you click on either button, its `onClick` will run first, followed by the parent `<div>`’s `onClick`. So two messages will appear. If you click the toolbar itself, only the parent `<div>`’s `onClick` will run.

### Pitfall

All events propagate in React except `onScroll`, which only works on the JSX tag you attach it to.

### Stopping propagation[](#stopping-propagation "Link for Stopping propagation ")

Event handlers receive an **event object** as their only argument. By convention, it’s usually called `e`, which stands for “event”. You can use this object to read information about the event.

That event object also lets you stop the propagation. If you want to prevent an event from reaching parent components, you need to call `e.stopPropagation()` like this `Button` component does:

```
function Button({ onClick, children }) {
  return (
    <button onClick={e => {
      e.stopPropagation();
      onClick();
    }}>
      {children}
    </button>
  );
}

export default function Toolbar() {
  return (
    <div className="Toolbar" onClick={() => {
      alert('You clicked on the toolbar!');
    }}>
      <Button onClick={() => alert('Playing!')}>
        Play Movie
      </Button>
      <Button onClick={() => alert('Uploading!')}>
        Upload Image
      </Button>
    </div>
  );
}
```

```
<div onClickCapture={() => { /* this runs first */ }}>

  <button onClick={e => e.stopPropagation()} />

  <button onClick={e => e.stopPropagation()} />

</div>
```

```
function Button({ onClick, children }) {

  return (

    <button onClick={e => {

      e.stopPropagation();

      onClick();

    }}>

      {children}

    </button>

  );

}
```

You could add more code to this handler before calling the parent `onClick` event handler, too. This pattern provides an *alternative* to propagation. It lets the child component handle the event, while also letting the parent component specify some additional behavior. Unlike propagation, it’s not automatic. But the benefit of this pattern is that you can clearly follow the whole chain of code that executes as a result of some event.

If you rely on propagation and it’s difficult to trace which handlers execute and why, try this approach instead.

### Preventing default behavior[](#preventing-default-behavior "Link for Preventing default behavior ")

Some browser events have default behavior associated with them. For example, a `<form>` submit event, which happens when a button inside of it is clicked, will reload the whole page by default:

```
export default function Signup() {
  return (
    <form onSubmit={() => alert('Submitting!')}>
      <input />
      <button>Send</button>
    </form>
  );
}
```

You can call `e.preventDefault()` on the event object to stop this from happening:

```
export default function Signup() {
  return (
    <form onSubmit={e => {
      e.preventDefault();
      alert('Submitting!');
    }}>
      <input />
      <button>Send</button>
    </form>
  );
}
```

```
export default function LightSwitch() {
  function handleClick() {
    let bodyStyle = document.body.style;
    if (bodyStyle.backgroundColor === 'black') {
      bodyStyle.backgroundColor = 'white';
    } else {
      bodyStyle.backgroundColor = 'black';
    }
  }

  return (
    <button onClick={handleClick()}>
      Toggle the lights
    </button>
  );
}
```

[PreviousAdding Interactivity](/learn/adding-interactivity)

[NextState: A Component's Memory](/learn/state-a-components-memory)

***

----
url: https://react.dev/reference/react/useContext
----

[API Reference](/reference/react)

[Hooks](/reference/react/hooks)

# useContext[](#undefined "Link for this heading")

`useContext` is a React Hook that lets you read and subscribe to [context](/learn/passing-data-deeply-with-context) from your component.

```
const value = useContext(SomeContext)
```

***

## Reference[](#reference "Link for Reference ")

### `useContext(SomeContext)`[](#usecontext "Link for this heading")

Call `useContext` at the top level of your component to read and subscribe to [context.](/learn/passing-data-deeply-with-context)

```
import { useContext } from 'react';



function MyComponent() {

  const theme = useContext(ThemeContext);

  // ...
```

[See more examples below.](#usage)

#### Parameters[](#parameters "Link for Parameters ")

* `SomeContext`: The context that you’ve previously created with [`createContext`](/reference/react/createContext). The context itself does not hold the information, it only represents the kind of information you can provide or read from components.

#### Returns[](#returns "Link for Returns ")

`useContext` returns the context value for the calling component. It is determined as the `value` passed to the closest `SomeContext` above the calling component in the tree. If there is no such provider, then the returned value will be the `defaultValue` you have passed to [`createContext`](/reference/react/createContext) for that context. The returned value is always up-to-date. React automatically re-renders components that read some context if it changes.

#### Caveats[](#caveats "Link for Caveats ")

* `useContext()` call in a component is not affected by providers returned from the *same* component. The corresponding `<Context>` **needs to be *above*** the component doing the `useContext()` call.
* React **automatically re-renders** all the children that use a particular context starting from the provider that receives a different `value`. The previous and the next values are compared with the [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) comparison. Skipping re-renders with [`memo`](/reference/react/memo) does not prevent the children receiving fresh context values.
* If your build system produces duplicates modules in the output (which can happen with symlinks), this can break context. Passing something via context only works if `SomeContext` that you use to provide context and `SomeContext` that you use to read it are ***exactly* the same object**, as determined by a `===` comparison.

***

## Usage[](#usage "Link for Usage ")

### Passing data deeply into the tree[](#passing-data-deeply-into-the-tree "Link for Passing data deeply into the tree ")

Call `useContext` at the top level of your component to read and subscribe to [context.](/learn/passing-data-deeply-with-context)

```
import { useContext } from 'react';



function Button() {

  const theme = useContext(ThemeContext);

  // ...
```

`useContext` returns the context value for the context you passed. To determine the context value, React searches the component tree and finds **the closest context provider above** for that particular context.

To pass context to a `Button`, wrap it or one of its parent components into the corresponding context provider:

```
function MyPage() {

  return (

    <ThemeContext value="dark">

      <Form />

    </ThemeContext>

  );

}



function Form() {

  // ... renders buttons inside ...

}
```

It doesn’t matter how many layers of components there are between the provider and the `Button`. When a `Button` *anywhere* inside of `Form` calls `useContext(ThemeContext)`, it will receive `"dark"` as the value.

### Pitfall

`useContext()` always looks for the closest provider *above* the component that calls it. It searches upwards and **does not** consider providers in the component from which you’re calling `useContext()`.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { createContext, useContext } from 'react';

const ThemeContext = createContext(null);

export default function MyApp() {
  return (
    <ThemeContext value="dark">
      <Form />
    </ThemeContext>
  )
}

function Form() {
  return (
    <Panel title="Welcome">
      <Button>Sign up</Button>
      <Button>Log in</Button>
    </Panel>
  );
}

function Panel({ title, children }) {
  const theme = useContext(ThemeContext);
  const className = 'panel-' + theme;
  return (
    <section className={className}>
      <h1>{title}</h1>
      {children}
    </section>
  )
}

function Button({ children }) {
  const theme = useContext(ThemeContext);
  const className = 'button-' + theme;
  return (
    <button className={className}>
      {children}
    </button>
  );
}
```

***

### Updating data passed via context[](#updating-data-passed-via-context "Link for Updating data passed via context ")

Often, you’ll want the context to change over time. To update context, combine it with [state.](/reference/react/useState) Declare a state variable in the parent component, and pass the current state down as the context value to the provider.

```
function MyPage() {

  const [theme, setTheme] = useState('dark');

  return (

    <ThemeContext value={theme}>

      <Form />

      <Button onClick={() => {

        setTheme('light');

      }}>

        Switch to light theme

      </Button>

    </ThemeContext>

  );

}
```

Now any `Button` inside of the provider will receive the current `theme` value. If you call `setTheme` to update the `theme` value that you pass to the provider, all `Button` components will re-render with the new `'light'` value.

#### Examples of updating context[](#examples-basic "Link for Examples of updating context")

#### Example 1 of 5:Updating a value via context[](#updating-a-value-via-context "Link for this heading")

In this example, the `MyApp` component holds a state variable which is then passed to the `ThemeContext` provider. Checking the “Dark mode” checkbox updates the state. Changing the provided value re-renders all the components using that context.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { createContext, useContext, useState } from 'react';

const ThemeContext = createContext(null);

export default function MyApp() {
  const [theme, setTheme] = useState('light');
  return (
    <ThemeContext value={theme}>
      <Form />
      <label>
        <input
          type="checkbox"
          checked={theme === 'dark'}
          onChange={(e) => {
            setTheme(e.target.checked ? 'dark' : 'light')
          }}
        />
        Use dark mode
      </label>
    </ThemeContext>
  )
}

function Form({ children }) {
  return (
    <Panel title="Welcome">
      <Button>Sign up</Button>
      <Button>Log in</Button>
    </Panel>
  );
}

function Panel({ title, children }) {
  const theme = useContext(ThemeContext);
  const className = 'panel-' + theme;
  return (
    <section className={className}>
      <h1>{title}</h1>
      {children}
    </section>
  )
}

function Button({ children }) {
  const theme = useContext(ThemeContext);
  const className = 'button-' + theme;
  return (
    <button className={className}>
      {children}
    </button>
  );
}
```

Note that `value="dark"` passes the `"dark"` string, but `value={theme}` passes the value of the JavaScript `theme` variable with [JSX curly braces.](/learn/javascript-in-jsx-with-curly-braces) Curly braces also let you pass context values that aren’t strings.

***

### Specifying a fallback default value[](#specifying-a-fallback-default-value "Link for Specifying a fallback default value ")

If React can’t find any providers of that particular context in the parent tree, the context value returned by `useContext()` will be equal to the default value that you specified when you [created that context](/reference/react/createContext):

```
const ThemeContext = createContext(null);
```

The default value **never changes**. If you want to update context, use it with state as [described above.](#updating-data-passed-via-context)

Often, instead of `null`, there is some more meaningful value you can use as a default, for example:

```
const ThemeContext = createContext('light');
```

This way, if you accidentally render some component without a corresponding provider, it won’t break. This also helps your components work well in a test environment without setting up a lot of providers in the tests.

In the example below, the “Toggle theme” button is always light because it’s **outside any theme context provider** and the default context theme value is `'light'`. Try editing the default theme to be `'dark'`.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { createContext, useContext, useState } from 'react';

const ThemeContext = createContext('light');

export default function MyApp() {
  const [theme, setTheme] = useState('light');
  return (
    <>
      <ThemeContext value={theme}>
        <Form />
      </ThemeContext>
      <Button onClick={() => {
        setTheme(theme === 'dark' ? 'light' : 'dark');
      }}>
        Toggle theme
      </Button>
    </>
  )
}

function Form({ children }) {
  return (
    <Panel title="Welcome">
      <Button>Sign up</Button>
      <Button>Log in</Button>
    </Panel>
  );
}

function Panel({ title, children }) {
  const theme = useContext(ThemeContext);
  const className = 'panel-' + theme;
  return (
    <section className={className}>
      <h1>{title}</h1>
      {children}
    </section>
  )
}

function Button({ children, onClick }) {
  const theme = useContext(ThemeContext);
  const className = 'button-' + theme;
  return (
    <button className={className} onClick={onClick}>
      {children}
    </button>
  );
}
```

***

### Overriding context for a part of the tree[](#overriding-context-for-a-part-of-the-tree "Link for Overriding context for a part of the tree ")

You can override the context for a part of the tree by wrapping that part in a provider with a different value.

```
<ThemeContext value="dark">

  ...

  <ThemeContext value="light">

    <Footer />

  </ThemeContext>

  ...

</ThemeContext>
```

You can nest and override providers as many times as you need.

#### Examples of overriding context[](#examples "Link for Examples of overriding context")

#### Example 1 of 2:Overriding a theme[](#overriding-a-theme "Link for this heading")

Here, the button *inside* the `Footer` receives a different context value (`"light"`) than the buttons outside (`"dark"`).

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { createContext, useContext } from 'react';

const ThemeContext = createContext(null);

export default function MyApp() {
  return (
    <ThemeContext value="dark">
      <Form />
    </ThemeContext>
  )
}

function Form() {
  return (
    <Panel title="Welcome">
      <Button>Sign up</Button>
      <Button>Log in</Button>
      <ThemeContext value="light">
        <Footer />
      </ThemeContext>
    </Panel>
  );
}

function Footer() {
  return (
    <footer>
      <Button>Settings</Button>
    </footer>
  );
}

function Panel({ title, children }) {
  const theme = useContext(ThemeContext);
  const className = 'panel-' + theme;
  return (
    <section className={className}>
      {title && <h1>{title}</h1>}
      {children}
    </section>
  )
}

function Button({ children }) {
  const theme = useContext(ThemeContext);
  const className = 'button-' + theme;
  return (
    <button className={className}>
      {children}
    </button>
  );
}
```

***

### Optimizing re-renders when passing objects and functions[](#optimizing-re-renders-when-passing-objects-and-functions "Link for Optimizing re-renders when passing objects and functions ")

You can pass any values via context, including objects and functions.

```
function MyApp() {

  const [currentUser, setCurrentUser] = useState(null);



  function login(response) {

    storeCredentials(response.credentials);

    setCurrentUser(response.user);

  }



  return (

    <AuthContext value={{ currentUser, login }}>

      <Page />

    </AuthContext>

  );

}
```

Here, the context value is a JavaScript object with two properties, one of which is a function. Whenever `MyApp` re-renders (for example, on a route update), this will be a *different* object pointing at a *different* function, so React will also have to re-render all components deep in the tree that call `useContext(AuthContext)`.

In smaller apps, this is not a problem. However, there is no need to re-render them if the underlying data, like `currentUser`, has not changed. To help React take advantage of that fact, you may wrap the `login` function with [`useCallback`](/reference/react/useCallback) and wrap the object creation into [`useMemo`](/reference/react/useMemo). This is a performance optimization:

```
import { useCallback, useMemo } from 'react';



function MyApp() {

  const [currentUser, setCurrentUser] = useState(null);



  const login = useCallback((response) => {

    storeCredentials(response.credentials);

    setCurrentUser(response.user);

  }, []);



  const contextValue = useMemo(() => ({

    currentUser,

    login

  }), [currentUser, login]);



  return (

    <AuthContext value={contextValue}>

      <Page />

    </AuthContext>

  );

}
```

As a result of this change, even if `MyApp` needs to re-render, the components calling `useContext(AuthContext)` won’t need to re-render unless `currentUser` has changed.

Read more about [`useMemo`](/reference/react/useMemo#skipping-re-rendering-of-components) and [`useCallback`.](/reference/react/useCallback#skipping-re-rendering-of-components)

***

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### My component doesn’t see the value from my provider[](#my-component-doesnt-see-the-value-from-my-provider "Link for My component doesn’t see the value from my provider ")

There are a few common ways that this can happen:

1. You’re rendering `<SomeContext>` in the same component (or below) as where you’re calling `useContext()`. Move `<SomeContext>` *above and outside* the component calling `useContext()`.
2. You may have forgotten to wrap your component with `<SomeContext>`, or you might have put it in a different part of the tree than you thought. Check whether the hierarchy is right using [React DevTools.](/learn/react-developer-tools)
3. You might be running into some build issue with your tooling that causes `SomeContext` as seen from the providing component and `SomeContext` as seen by the reading component to be two different objects. This can happen if you use symlinks, for example. You can verify this by assigning them to globals like `window.SomeContext1` and `window.SomeContext2` and then checking whether `window.SomeContext1 === window.SomeContext2` in the console. If they’re not the same, fix that issue on the build tool level.

### I am always getting `undefined` from my context although the default value is different[](#i-am-always-getting-undefined-from-my-context-although-the-default-value-is-different "Link for this heading")

You might have a provider without a `value` in the tree:

```
// 🚩 Doesn't work: no value prop

<ThemeContext>

   <Button />

</ThemeContext>
```

If you forget to specify `value`, it’s like passing `value={undefined}`.

You may have also mistakingly used a different prop name by mistake:

```
// 🚩 Doesn't work: prop should be called "value"

<ThemeContext theme={theme}>

   <Button />

</ThemeContext>
```

In both of these cases you should see a warning from React in the console. To fix them, call the prop `value`:

```
// ✅ Passing the value prop

<ThemeContext value={theme}>

   <Button />

</ThemeContext>
```

Note that the [default value from your `createContext(defaultValue)` call](#specifying-a-fallback-default-value) is only used **if there is no matching provider above at all.** If there is a `<SomeContext value={undefined}>` component somewhere in the parent tree, the component calling `useContext(SomeContext)` *will* receive `undefined` as the context value.

[PrevioususeCallback](/reference/react/useCallback)

[NextuseDebugValue](/reference/react/useDebugValue)

***

----
url: https://legacy.reactjs.org/blog/2015/03/10/react-v0.13.html
----

March 10, 2015 by [Sophie Alpert](https://sophiebits.com/)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

Today, we’re happy to release React v0.13!

The most notable new feature is [support for ES6 classes](/blog/2015/01/27/react-v0.13.0-beta-1.html), which allows developers to have more flexibility when writing components. Our eventual goal is for ES6 classes to replace `React.createClass` completely, but until we have a replacement for current mixin use cases and support for class property initializers in the language, we don’t plan to deprecate `React.createClass`.

At EmberConf and ng-conf last week, we were excited to see that Ember and Angular have been working on speed improvements and now both have performance comparable to React. We’ve always thought that performance isn’t the most important reason to choose React, but we’re still planning more optimizations to **make React even faster**.

Our planned optimizations require that ReactElement objects are immutable, which has always been a best practice when writing idiomatic React code. In this release, we’ve added runtime warnings that fire when props are changed or added between the time an element is created and when it’s rendered. When migrating your code, you may want to use new `React.cloneElement` API (which is similar to `React.addons.cloneWithProps` but preserves `key` and `ref` and does not merge `style` or `className` automatically). For more information about our planned optimizations, see GitHub issues [#3226](https://github.com/facebook/react/issues/3226), [#3227](https://github.com/facebook/react/issues/3227), [#3228](https://github.com/facebook/react/issues/3228).

The release is now available for download:

* **React**\
  Dev build with warnings: <https://fb.me/react-0.13.0.js>\
  Minified build for production: <https://fb.me/react-0.13.0.min.js>
* **React with Add-Ons**\
  Dev build with warnings: <https://fb.me/react-with-addons-0.13.0.js>\
  Minified build for production: <https://fb.me/react-with-addons-0.13.0.min.js>
* **In-Browser JSX transformer**\
  <https://fb.me/JSXTransformer-0.13.0.js>

We’ve also published version `0.13.0` of the `react` and `react-tools` packages on npm and the `react` package on bower.

***

## [](#changelog)Changelog

### [](#react-core)React Core

#### [](#breaking-changes)Breaking Changes

* Deprecated patterns that warned in 0.12 no longer work: most prominently, calling component classes without using JSX or React.createElement and using non-component functions with JSX or createElement

* Support for using ES6 classes to build React components; see the [v0.13.0 beta 1 notes](/blog/2015/01/27/react-v0.13.0-beta-1.html) for details.
* Added new top-level API `React.findDOMNode(component)`, which should be used in place of `component.getDOMNode()`. The base class for ES6-based components will not have `getDOMNode`. This change will enable some more patterns moving forward.
* Added a new top-level API `React.cloneElement(el, props)` for making copies of React elements – see the [v0.13 RC2 notes](/blog/2015/03/03/react-v0.13-rc2.html#react.cloneelement) for more details.
* New `ref` style, allowing a callback to be used in place of a name: `<Photo ref={(c) => this._photo = c} />` allows you to reference the component with `this._photo` (as opposed to `ref="photo"` which gives `this.refs.photo`).
* `this.setState()` can now take a function as the first argument for transactional state updates, such as `this.setState((state, props) => ({count: state.count + 1}));` – this means that you no longer need to use `this._pendingState`, which is now gone.
* Support for iterators and immutable-js sequences as children.

#### [](#deprecations)Deprecations

* `ComponentClass.type` is deprecated. Just use `ComponentClass` (usually as `element.type === ComponentClass`).
* Some methods that are available on `createClass`-based components are removed or deprecated from ES6 classes (`getDOMNode`, `replaceState`, `isMounted`, `setProps`, `replaceProps`).

### [](#react-with-add-ons)React with Add-Ons

#### [](#new-features-1)New Features

* [`React.addons.createFragment` was added](/docs/create-fragment.html) for adding keys to entire sets of children.

#### [](#deprecations-1)Deprecations

* `React.addons.classSet` is now deprecated. This functionality can be replaced with several freely available modules. [classnames](https://www.npmjs.com/package/classnames) is one such module.
* Calls to `React.addons.cloneWithProps` can be migrated to use `React.cloneElement` instead – make sure to merge `style` and `className` manually if desired.

### [](#react-tools)React Tools

#### [](#breaking-changes-1)Breaking Changes

* When transforming ES6 syntax, `class` methods are no longer enumerable by default, which requires `Object.defineProperty`; if you support browsers such as IE8, you can pass `--target es3` to mirror the old behavior

#### [](#new-features-2)New Features

* `--target` option is available on the jsx command, allowing users to specify and ECMAScript version to target.

  * `es5` is the default.
  * `es3` restores the previous default behavior. An additional transform is added here to ensure the use of reserved words as properties is safe (eg `this.static` will become `this['static']` for IE8 compatibility).

* The transform for the call spread syntax has also been enabled.

### [](#jsx)JSX

#### [](#breaking-changes-2)Breaking Changes

* A change was made to how some JSX was parsed, specifically around the use of `>` or `}` when inside an element. Previously it would be treated as a string but now it will be treated as a parse error. The [`jsx_orphaned_brackets_transformer`](https://www.npmjs.com/package/jsx_orphaned_brackets_transformer) package on npm can be used to find and fix potential issues in your JSX code.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2015-03-10-react-v0.13.md)

----
url: https://react.dev/reference/react-compiler/directives/use-no-memo
----

[API Reference](/reference/react)

[Directives](/reference/react-compiler/directives)

# use no memo[](#undefined "Link for this heading")

`"use no memo"` prevents a function from being optimized by React Compiler.

* [Reference](#reference)

  * [`"use no memo"`](#use-no-memo)
  * [How `"use no memo"` opts-out of optimization](#how-use-no-memo-opts-out)
  * [When to use `"use no memo"`](#when-to-use)

* [Usage](#usage)

* [Troubleshooting](#troubleshooting)

  * [Directive not preventing compilation](#not-preventing)
  * [Best practices](#best-practices)
  * [See also](#see-also)

***

## Reference[](#reference "Link for Reference ")

### `"use no memo"`[](#use-no-memo "Link for this heading")

Add `"use no memo"` at the beginning of a function to prevent React Compiler optimization.

```
function MyComponent() {

  "use no memo";

  // ...

}
```

When a function contains `"use no memo"`, the React Compiler will skip it entirely during optimization. This is useful as a temporary escape hatch when debugging or when dealing with code that doesn’t work correctly with the compiler.

#### Caveats[](#caveats "Link for Caveats ")

* `"use no memo"` must be at the very beginning of a function body, before any imports or other code (comments are OK).
* The directive must be written with double or single quotes, not backticks.
* The directive must exactly match `"use no memo"` or its alias `"use no forget"`.
* This directive takes precedence over all compilation modes and other directives.
* It’s intended as a temporary debugging tool, not a permanent solution.

### How `"use no memo"` opts-out of optimization[](#how-use-no-memo-opts-out "Link for this heading")

React Compiler analyzes your code at build time to apply optimizations. `"use no memo"` creates an explicit boundary that tells the compiler to skip a function entirely.

This directive takes precedence over all other settings:

* In `all` mode: The function is skipped despite the global setting
* In `infer` mode: The function is skipped even if heuristics would optimize it

The compiler treats these functions as if the React Compiler wasn’t enabled, leaving them exactly as written.

### When to use `"use no memo"`[](#when-to-use "Link for this heading")

`"use no memo"` should be used sparingly and temporarily. Common scenarios include:

#### Debugging compiler issues[](#debugging-compiler "Link for Debugging compiler issues ")

When you suspect the compiler is causing issues, temporarily disable optimization to isolate the problem:

```
function ProblematicComponent({ data }) {

  "use no memo"; // TODO: Remove after fixing issue #123



  // Rules of React violations that weren't statically detected

  // ...

}
```

#### Third-party library integration[](#third-party "Link for Third-party library integration ")

When integrating with libraries that might not be compatible with the compiler:

```
function ThirdPartyWrapper() {

  "use no memo";



  useThirdPartyHook(); // Has side effects that compiler might optimize incorrectly

  // ...

}
```

***

## Usage[](#usage "Link for Usage ")

The `"use no memo"` directive is placed at the beginning of a function body to prevent React Compiler from optimizing that function:

```
function MyComponent() {

  "use no memo";

  // Function body

}
```

The directive can also be placed at the top of a file to affect all functions in that module:

```
"use no memo";



// All functions in this file will be skipped by the compiler
```

`"use no memo"` at the function level overrides the module level directive.

***

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### Directive not preventing compilation[](#not-preventing "Link for Directive not preventing compilation ")

If `"use no memo"` isn’t working:

```
// ❌ Wrong - directive after code

function Component() {

  const data = getData();

  "use no memo"; // Too late!

}



// ✅ Correct - directive first

function Component() {

  "use no memo";

  const data = getData();

}
```

Also check:

* Spelling - must be exactly `"use no memo"`
* Quotes - must use single or double quotes, not backticks

### Best practices[](#best-practices "Link for Best practices ")

**Always document why** you’re disabling optimization:

```
// ✅ Good - clear explanation and tracking

function DataProcessor() {

  "use no memo"; // TODO: Remove after fixing rule of react violation

  // ...

}



// ❌ Bad - no explanation

function Mystery() {

  "use no memo";

  // ...

}
```

### See also[](#see-also "Link for See also ")

* [`"use memo"`](/reference/react-compiler/directives/use-memo) - Opt into compilation
* [React Compiler](/learn/react-compiler) - Getting started guide

[Previous"use memo"](/reference/react-compiler/directives/use-memo)

[NextCompiling Libraries](/reference/react-compiler/compiling-libraries)

***

----
url: https://18.react.dev/reference/rsc/directives
----

[API Reference](/reference/react)

# Directives[](#undefined "Link for this heading")

### Canary

These directives are needed only if you’re [using React Server Components](/learn/start-a-new-react-project#bleeding-edge-react-frameworks) or building a library compatible with them.

Directives provide instructions to [bundlers compatible with React Server Components](/learn/start-a-new-react-project#bleeding-edge-react-frameworks).

***

## Source code directives[](#source-code-directives "Link for Source code directives ")

* [`'use client'`](/reference/rsc/use-client) lets you mark what code runs on the client.
* [`'use server'`](/reference/rsc/use-server) marks server-side functions that can be called from client-side code.

[PreviousServer Actions](/reference/rsc/server-actions)

[Next'use client'](/reference/rsc/use-client)

***

----
url: https://18.react.dev/learn/javascript-in-jsx-with-curly-braces
----

```
export default function Avatar() {
  return (
    <img
      className="avatar"
      src="https://i.imgur.com/7vQD0fPs.jpg"
      alt="Gregorio Y. Zara"
    />
  );
}
```

Here, `"https://i.imgur.com/7vQD0fPs.jpg"` and `"Gregorio Y. Zara"` are being passed as strings.

But what if you want to dynamically specify the `src` or `alt` text? You could **use a value from JavaScript by replacing `"` and `"` with `{` and `}`**:

```
export default function Avatar() {
  const avatar = 'https://i.imgur.com/7vQD0fPs.jpg';
  const description = 'Gregorio Y. Zara';
  return (
    <img
      className="avatar"
      src={avatar}
      alt={description}
    />
  );
}
```

Notice the difference between `className="avatar"`, which specifies an `"avatar"` CSS class name that makes the image round, and `src={avatar}` that reads the value of the JavaScript variable called `avatar`. That’s because curly braces let you work with JavaScript right there in your markup!

## Using curly braces: A window into the JavaScript world[](#using-curly-braces-a-window-into-the-javascript-world "Link for Using curly braces: A window into the JavaScript world ")

JSX is a special way of writing JavaScript. That means it’s possible to use JavaScript inside it—with curly braces `{ }`. The example below first declares a name for the scientist, `name`, then embeds it with curly braces inside the `<h1>`:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?parameters=N4IgZglgNgpgziAXKOAnAxgeggOwCYwAeAdAFYLIjoD2OALjPUiBALYAO1qdABAEowAhujoAaHsB4BlOqggiAstQI8AvjzCpqrHgB0QqISP0BuXTjaduEnukOCGfatV7rN2vQaN0AtHm2Y6FAQjHSm5pZcvPrEmHB0AJ6wcMTocHDhOBEcUTwAguzsGlo6MZgF7JnmNDjxPFouPAC8tvaOznQAFP7oAK6socQA5jB0AKKwA_QAQgkAknid-g1hIACUa2Y4K8SG-DCoSzg8PAA8MnKKyjAAfOYnJ6cVPJh3x2eYF_J0SgRvmyBRCw4NNcIJUAkkGBBFA4DBVED2MIANaCEZkOC0JCgGoMJiIEDAe6eHCCAb6RCeewiYgEABu-lExP0dIOcAgtApngADMRedzGcyQKxBLgufo4hhsPsSORBe99HA7BB2HQMkgJMSToq6ODVpTlt4fEq5Kq4Dx4nr5Q9PAAjXrQPDirzCXwmlVqnj2x3Wh76BjxZ3Ut3Ks08AO8Hw-Rh0prkfysX3akAwUgwYwaw2u42hz2p9OrYkIoUEdiMAg4dAhdWUonvZPB50APQAjAAOPl8pNUo0J5vtzsCwFanvZ91m5sAVkH-iLTIVIHpABEYGX9pXq1zgKpzKpAcDQaSIVCYXCESB2L1bcEsLgCCQABZ0VhQbFUWh4ujMU4AQiXAHkAGEABUAE0AAUxh4J8XzeU4YKgHgoEEHAhiafRGH0OCHyEPA3keAZdVsB9wThOh0JAABVYCADEfDbLDiVOQjBB4UkBgoukQgAdysVZbA_UIKO4iA8DoB8mnpeQYB8ESxIfcRcAgOgIBhHMYRgJoWy7EB8LOFS6FgG4l2oPopjoU5MAMozzEsnDBDw2zbWUBI9NOPAIDpHhRIolYsMsjy6TgzBnLwVzbMwBCbn3CAQTBY9EGhWF4SBNAsAqDE31xUJmCIPieAIaFeigXgwF6SsVNoHhgOUagABlYq6NZNXeGo6nYmBmh4AByABxQwhi4DkeFA4geAALXBQRuq2E5DDoXpUGOI4bXglsbmADrVG680ap4EyeAa-I7PW4lNl3cwYrio9IUS08UpANK4kSZJUnSLLBPxEAACoWpOZzCGNCAAC9cCGSlnNQAhUB8AGth3LIcFChI_o0D8fGhVhoASSk4BQuBjQOCAwFmngRVQIZcEpAAmbl2EIUmkTwDzUMpbl4fMcwHxbVHycpnAfDoah2DZ0mwHR9lgZgGnqfpjnEYfanefBfnBeF0XiXF-ggalmm6YZi6FYAZmVincDVkWeHZzWJZB6WeHbOXDa5gAWU3VaFy3rfeLW3TtykWwANidnAEa5yd3fNz2NZ923dYdl2Q7DnAH0DyOBejq2xbj-2W1lg3Q85ytrlR32ddz4hqZgVh5fMYrUaZlmhh8XBghwGTLW4PWk6Lq7D3BW6krPc8GA4ZCGGYOwhAYHxgx8QRChAVQgA\&query=file%3D%252Fsrc%252FApp.js%26utm_medium%3Dsandpack\&environment=create-react-app "Open in CodeSandbox")

```
export default function TodoList() {
  const name = 'Gregorio Y. Zara';
  return (
    <h1>{name}'s To Do List</h1>
  );
}
```

Try changing the `name`’s value from `'Gregorio Y. Zara'` to `'Hedy Lamarr'`. See how the list title changes?

Any JavaScript expression will work between curly braces, including function calls like `formatDate()`:

```
const today = new Date();

function formatDate(date) {
  return new Intl.DateTimeFormat(
    'en-US',
    { weekday: 'long' }
  ).format(date);
}

export default function TodoList() {
  return (
    <h1>To Do List for {formatDate(today)}</h1>
  );
}
```

```
export default function TodoList() {
  return (
    <ul style={{
      backgroundColor: 'black',
      color: 'pink'
    }}>
      <li>Improve the videophone</li>
      <li>Prepare aeronautics lectures</li>
      <li>Work on the alcohol-fuelled engine</li>
    </ul>
  );
}
```

Try changing the values of `backgroundColor` and `color`.

You can really see the JavaScript object inside the curly braces when you write it like this:

```
<ul style={

  {

    backgroundColor: 'black',

    color: 'pink'

  }

}>
```

The next time you see `{{` and `}}` in JSX, know that it’s nothing more than an object inside the JSX curlies!

### Pitfall

Inline `style` properties are written in camelCase. For example, HTML `<ul style="background-color: black">` would be written as `<ul style={{ backgroundColor: 'black' }}>` in your component.

## More fun with JavaScript objects and curly braces[](#more-fun-with-javascript-objects-and-curly-braces "Link for More fun with JavaScript objects and curly braces ")

You can move several expressions into one object, and reference them in your JSX inside curly braces:

```
const person = {
  name: 'Gregorio Y. Zara',
  theme: {
    backgroundColor: 'black',
    color: 'pink'
  }
};

export default function TodoList() {
  return (
    <div style={person.theme}>
      <h1>{person.name}'s Todos</h1>
      <img
        className="avatar"
        src="https://i.imgur.com/7vQD0fPs.jpg"
        alt="Gregorio Y. Zara"
      />
      <ul>
        <li>Improve the videophone</li>
        <li>Prepare aeronautics lectures</li>
        <li>Work on the alcohol-fuelled engine</li>
      </ul>
    </div>
  );
}
```

In this example, the `person` JavaScript object contains a `name` string and a `theme` object:

```
const person = {

  name: 'Gregorio Y. Zara',

  theme: {

    backgroundColor: 'black',

    color: 'pink'

  }

};
```

The component can use these values from `person` like so:

```
<div style={person.theme}>

  <h1>{person.name}'s Todos</h1>
```

```
const person = {
  name: 'Gregorio Y. Zara',
  theme: {
    backgroundColor: 'black',
    color: 'pink'
  }
};

export default function TodoList() {
  return (
    <div style={person.theme}>
      <h1>{person}'s Todos</h1>
      <img
        className="avatar"
        src="https://i.imgur.com/7vQD0fPs.jpg"
        alt="Gregorio Y. Zara"
      />
      <ul>
        <li>Improve the videophone</li>
        <li>Prepare aeronautics lectures</li>
        <li>Work on the alcohol-fuelled engine</li>
      </ul>
    </div>
  );
}
```

Can you find the problem?

[PreviousWriting Markup with JSX](/learn/writing-markup-with-jsx)

[NextPassing Props to a Component](/learn/passing-props-to-a-component)

***

----
url: https://legacy.reactjs.org/docs/profiler.html
----

> These docs are old and won’t be updated. Go to [react.dev](https://react.dev/) for the new React docs.
>
> These new documentation pages teach modern React:
>
> * [`<Profiler>`](https://react.dev/reference/react/Profiler)

The `Profiler` measures how often a React application renders and what the “cost” of rendering is. Its purpose is to help identify parts of an application that are slow and may benefit from [optimizations such as memoization](/docs/hooks-faq.html#how-to-memoize-calculations).

> Note:
>
> Profiling adds some additional overhead, so **it is disabled in [the production build](/docs/optimizing-performance.html#use-the-production-build)**.
>
> To opt into production profiling, React provides a special production build with profiling enabled. Read more about how to use this build at [fb.me/react-profiling](https://fb.me/react-profiling)

## [](#usage)Usage

A `Profiler` can be added anywhere in a React tree to measure the cost of rendering that part of the tree. It requires two props: an `id` (string) and an `onRender` callback (function) which React calls any time a component within the tree “commits” an update.

For example, to profile a `Navigation` component and its descendants:

```
render(
  <App>
    <Profiler id="Navigation" onRender={callback}>      <Navigation {...props} />
    </Profiler>
    <Main {...props} />
  </App>
);
```

Multiple `Profiler` components can be used to measure different parts of an application:

```
render(
  <App>
    <Profiler id="Navigation" onRender={callback}>      <Navigation {...props} />
    </Profiler>
    <Profiler id="Main" onRender={callback}>      <Main {...props} />
    </Profiler>
  </App>
);
```

`Profiler` components can also be nested to measure different components within the same subtree:

```
render(
  <App>
    <Profiler id="Panel" onRender={callback}>      <Panel {...props}>
        <Profiler id="Content" onRender={callback}>          <Content {...props} />
        </Profiler>
        <Profiler id="PreviewPane" onRender={callback}>          <PreviewPane {...props} />
        </Profiler>
      </Panel>
    </Profiler>
  </App>
);
```

> Note
>
> Although `Profiler` is a light-weight component, it should be used only when necessary; each use adds some CPU and memory overhead to an application.

## [](#onrender-callback)`onRender` Callback

The `Profiler` requires an `onRender` function as a prop. React calls this function any time a component within the profiled tree “commits” an update. It receives parameters describing what was rendered and how long it took.

```
function onRenderCallback(
  id, // the "id" prop of the Profiler tree that has just committed
  phase, // either "mount" (if the tree just mounted) or "update" (if it re-rendered)
  actualDuration, // time spent rendering the committed update
  baseDuration, // estimated time to render the entire subtree without memoization
  startTime, // when React began rendering this update
  commitTime, // when React committed this update
  interactions // the Set of interactions belonging to this update
) {
  // Aggregate or log render timings...
}
```

Let’s take a closer look at each of the props:

* **`id: string`** - The `id` prop of the `Profiler` tree that has just committed. This can be used to identify which part of the tree was committed if you are using multiple profilers.
* **`phase: "mount" | "update"`** - Identifies whether the tree has just been mounted for the first time or re-rendered due to a change in props, state, or hooks.
* **`actualDuration: number`** - Time spent rendering the `Profiler` and its descendants for the current update. This indicates how well the subtree makes use of memoization (e.g. [`React.memo`](/docs/react-api.html#reactmemo), [`useMemo`](/docs/hooks-reference.html#usememo), [`shouldComponentUpdate`](/docs/hooks-faq.html#how-do-i-implement-shouldcomponentupdate)). Ideally this value should decrease significantly after the initial mount as many of the descendants will only need to re-render if their specific props change.
* **`baseDuration: number`** - Duration of the most recent `render` time for each individual component within the `Profiler` tree. This value estimates a worst-case cost of rendering (e.g. the initial mount or a tree with no memoization).
* **`startTime: number`** - Timestamp when React began rendering the current update.
* **`commitTime: number`** - Timestamp when React committed the current update. This value is shared between all profilers in a commit, enabling them to be grouped if desirable.
* **`interactions: Set`** - Set of [“interactions”](https://fb.me/react-interaction-tracing) that were being traced when the update was scheduled (e.g. when `render` or `setState` were called).

> Note
>
> Interactions can be used to identify the cause of an update, although the API for tracing them is still experimental.
>
> Learn more about it at [fb.me/react-interaction-tracing](https://fb.me/react-interaction-tracing)

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/reference-profiler.md)

----
url: https://react.dev/reference/react-compiler/compilationMode
----

[API Reference](/reference/react)

[Configuration](/reference/react-compiler/configuration)

# compilationMode[](#undefined "Link for this heading")

The `compilationMode` option controls how the React Compiler selects which functions to compile.

```
{

  compilationMode: 'infer' // or 'annotation', 'syntax', 'all'

}
```

* [Reference](#reference)
  * [`compilationMode`](#compilationmode)

* [Usage](#usage)

  * [Default inference mode](#default-inference-mode)
  * [Incremental adoption with annotation mode](#incremental-adoption)
  * [Using Flow syntax mode](#flow-syntax-mode)
  * [Opting out specific functions](#opting-out)

* [Troubleshooting](#troubleshooting)
  * [Component not being compiled in infer mode](#component-not-compiled-infer)

***

## Reference[](#reference "Link for Reference ")

### `compilationMode`[](#compilationmode "Link for this heading")

Controls the strategy for determining which functions the React Compiler will optimize.

#### Type[](#type "Link for Type ")

```
'infer' | 'syntax' | 'annotation' | 'all'
```

#### Default value[](#default-value "Link for Default value ")

`'infer'`

#### Options[](#options "Link for Options ")

* **`'infer'`** (default): The compiler uses intelligent heuristics to identify React components and hooks:

  * Functions explicitly annotated with `"use memo"` directive
  * Functions that are named like components (PascalCase) or hooks (`use` prefix) AND create JSX and/or call other hooks

* **`'annotation'`**: Only compile functions explicitly marked with the `"use memo"` directive. Ideal for incremental adoption.

* **`'syntax'`**: Only compile components and hooks that use Flow’s [component](https://flow.org/en/docs/react/component-syntax/) and [hook](https://flow.org/en/docs/react/hook-syntax/) syntax.

* **`'all'`**: Compile all top-level functions. Not recommended as it may compile non-React functions.

#### Caveats[](#caveats "Link for Caveats ")

* The `'infer'` mode requires functions to follow React naming conventions to be detected
* Using `'all'` mode may negatively impact performance by compiling utility functions
* The `'syntax'` mode requires Flow and won’t work with TypeScript
* Regardless of mode, functions with `"use no memo"` directive are always skipped

***

## Usage[](#usage "Link for Usage ")

### Default inference mode[](#default-inference-mode "Link for Default inference mode ")

The default `'infer'` mode works well for most codebases that follow React conventions:

```
{

  compilationMode: 'infer'

}
```

With this mode, these functions will be compiled:

```
// ✅ Compiled: Named like a component + returns JSX

function Button(props) {

  return <button>{props.label}</button>;

}



// ✅ Compiled: Named like a hook + calls hooks

function useCounter() {

  const [count, setCount] = useState(0);

  return [count, setCount];

}



// ✅ Compiled: Explicit directive

function expensiveCalculation(data) {

  "use memo";

  return data.reduce(/* ... */);

}



// ❌ Not compiled: Not a component/hook pattern

function calculateTotal(items) {

  return items.reduce((a, b) => a + b, 0);

}
```

### Incremental adoption with annotation mode[](#incremental-adoption "Link for Incremental adoption with annotation mode ")

For gradual migration, use `'annotation'` mode to only compile marked functions:

```
{

  compilationMode: 'annotation'

}
```

Then explicitly mark functions to compile:

```
// Only this function will be compiled

function ExpensiveList(props) {

  "use memo";

  return (

    <ul>

      {props.items.map(item => (

        <li key={item.id}>{item.name}</li>

      ))}

    </ul>

  );

}



// This won't be compiled without the directive

function NormalComponent(props) {

  return <div>{props.content}</div>;

}
```

### Using Flow syntax mode[](#flow-syntax-mode "Link for Using Flow syntax mode ")

If your codebase uses Flow instead of TypeScript:

```
{

  compilationMode: 'syntax'

}
```

Then use Flow’s component syntax:

```
// Compiled: Flow component syntax

component Button(label: string) {

  return <button>{label}</button>;

}



// Compiled: Flow hook syntax

hook useCounter(initial: number) {

  const [count, setCount] = useState(initial);

  return [count, setCount];

}



// Not compiled: Regular function syntax

function helper(data) {

  return process(data);

}
```

### Opting out specific functions[](#opting-out "Link for Opting out specific functions ")

Regardless of compilation mode, use `"use no memo"` to skip compilation:

```
function ComponentWithSideEffects() {

  "use no memo"; // Prevent compilation



  // This component has side effects that shouldn't be memoized

  logToAnalytics('component_rendered');



  return <div>Content</div>;

}
```

***

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### Component not being compiled in infer mode[](#component-not-compiled-infer "Link for Component not being compiled in infer mode ")

In `'infer'` mode, ensure your component follows React conventions:

```
// ❌ Won't be compiled: lowercase name

function button(props) {

  return <button>{props.label}</button>;

}



// ✅ Will be compiled: PascalCase name

function Button(props) {

  return <button>{props.label}</button>;

}



// ❌ Won't be compiled: doesn't create JSX or call hooks

function useData() {

  return window.localStorage.getItem('data');

}



// ✅ Will be compiled: calls a hook

function useData() {

  const [data] = useState(() => window.localStorage.getItem('data'));

  return data;

}
```

[PreviousConfiguration](/reference/react-compiler/configuration)

[Nextgating](/reference/react-compiler/gating)

***

----
url: https://18.react.dev/reference/react/experimental_taintObjectReference
----

[API Reference](/reference/react)

[APIs](/reference/react/apis)

# experimental\_taintObjectReference[](#undefined "Link for this heading")

### Under Construction

```
experimental_taintObjectReference(message, object);
```

To prevent passing a key, hash or token, see [`taintUniqueValue`](/reference/react/experimental_taintUniqueValue).

* [Reference](#reference)
  * [`taintObjectReference(message, object)`](#taintobjectreference)
* [Usage](#usage)
  * [Prevent user data from unintentionally reaching the client](#prevent-user-data-from-unintentionally-reaching-the-client)

***

## Reference[](#reference "Link for Reference ")

### `taintObjectReference(message, object)`[](#taintobjectreference "Link for this heading")

Call `taintObjectReference` with an object to register it with React as something that should not be allowed to be passed to the Client as is:

```
import {experimental_taintObjectReference} from 'react';



experimental_taintObjectReference(

  'Do not pass ALL environment variables to the client.',

  process.env

);
```

***

## Usage[](#usage "Link for Usage ")

### Prevent user data from unintentionally reaching the client[](#prevent-user-data-from-unintentionally-reaching-the-client "Link for Prevent user data from unintentionally reaching the client ")

A Client Component should never accept objects that carry sensitive data. Ideally, the data fetching functions should not expose data that the current user should not have access to. Sometimes mistakes happen during refactoring. To protect against these mistakes happening down the line we can “taint” the user object in our data API.

```
import {experimental_taintObjectReference} from 'react';



export async function getUser(id) {

  const user = await db`SELECT * FROM users WHERE id = ${id}`;

  experimental_taintObjectReference(

    'Do not pass the entire user object to the client. ' +

      'Instead, pick off the specific properties you need for this use case.',

    user,

  );

  return user;

}
```

Now whenever anyone tries to pass this object to a Client Component, an error will be thrown with the passed in error message instead.

##### Deep Dive#### Protecting against leaks in data fetching[](#protecting-against-leaks-in-data-fetching "Link for Protecting against leaks in data fetching ")

If you’re running a Server Components environment that has access to sensitive data, you have to be careful not to pass objects straight through:

```
// api.js

export async function getUser(id) {

  const user = await db`SELECT * FROM users WHERE id = ${id}`;

  return user;

}
```

```
import { getUser } from 'api.js';

import { InfoCard } from 'components.js';



export async function Profile(props) {

  const user = await getUser(props.userId);

  // DO NOT DO THIS

  return <InfoCard user={user} />;

}
```

```
// components.js

"use client";



export async function InfoCard({ user }) {

  return <div>{user.name}</div>;

}
```

Ideally, the `getUser` should not expose data that the current user should not have access to. To prevent passing the `user` object to a Client Component down the line we can “taint” the user object:

```
// api.js

import {experimental_taintObjectReference} from 'react';



export async function getUser(id) {

  const user = await db`SELECT * FROM users WHERE id = ${id}`;

  experimental_taintObjectReference(

    'Do not pass the entire user object to the client. ' +

      'Instead, pick off the specific properties you need for this use case.',

    user,

  );

  return user;

}
```

Now if anyone tries to pass the `user` object to a Client Component, an error will be thrown with the passed in error message.

[Previoususe](/reference/react/use)

[Nextexperimental\_taintUniqueValue](/reference/react/experimental_taintUniqueValue)

***

----
url: https://legacy.reactjs.org/docs/how-to-contribute.html
----

React is one of Facebook’s first open source projects that is both under very active development and is also being used to ship code to everybody on [facebook.com](https://www.facebook.com). We’re still working out the kinks to make contributing to this project as easy and transparent as possible, but we’re not quite there yet. Hopefully this document makes the process for contributing clear and answers some questions that you may have.

### [](#code-of-conduct)[Code of Conduct](https://github.com/facebook/react/blob/main/CODE_OF_CONDUCT.md)

Facebook has adopted the [Contributor Covenant](https://www.contributor-covenant.org/) as its Code of Conduct, and we expect project participants to adhere to it. Please read [the full text](https://github.com/facebook/react/blob/main/CODE_OF_CONDUCT.md) so that you can understand what actions will and will not be tolerated.

### [](#open-development)Open Development

All work on React happens directly on [GitHub](https://github.com/facebook/react). Both core team members and external contributors send pull requests which go through the same review process.

### [](#semantic-versioning)Semantic Versioning

React follows [semantic versioning](https://semver.org/). We release patch versions for critical bugfixes, minor versions for new features or non-essential changes, and major versions for any breaking changes. When we make breaking changes, we also introduce deprecation warnings in a minor version so that our users learn about the upcoming changes and migrate their code in advance. Learn more about our commitment to stability and incremental migration in [our versioning policy](/docs/faq-versioning.html).

Every significant change is documented in the [changelog file](https://github.com/facebook/react/blob/main/CHANGELOG.md).

### [](#branch-organization)Branch Organization

Submit all changes directly to the [`main branch`](https://github.com/facebook/react/tree/main). We don’t use separate branches for development or for upcoming releases. We do our best to keep `main` in good shape, with all tests passing.

Code that lands in `main` must be compatible with the latest stable release. It may contain additional features, but no breaking changes. We should be able to release a new minor version from the tip of `main` at any time.

### [](#feature-flags)Feature Flags

To keep the `main` branch in a releasable state, breaking changes and experimental features must be gated behind a feature flag.

Feature flags are defined in [`packages/shared/ReactFeatureFlags.js`](https://github.com/facebook/react/blob/main/packages/shared/ReactFeatureFlags.js). Some builds of React may enable different sets of feature flags; for example, the React Native build may be configured differently than React DOM. These flags are found in [`packages/shared/forks`](https://github.com/facebook/react/tree/main/packages/shared/forks). Feature flags are statically typed by Flow, so you can run `yarn flow` to confirm that you’ve updated all the necessary files.

React’s build system will strip out disabled feature branches before publishing. A continuous integration job runs on every commit to check for changes in bundle size. You can use the change in size as a signal that a feature was gated correctly.

### [](#bugs)Bugs

#### [](#where-to-find-known-issues)Where to Find Known Issues

We are using [GitHub Issues](https://github.com/facebook/react/issues) for our public bugs. We keep a close eye on this and try to make it clear when we have an internal fix in progress. Before filing a new task, try to make sure your problem doesn’t already exist.

#### [](#reporting-new-issues)Reporting New Issues

The best way to get your bug fixed is to provide a reduced test case. This [JSFiddle template](https://jsfiddle.net/Luktwrdm/) is a great starting point.

#### [](#security-bugs)Security Bugs

Facebook has a [bounty program](https://www.facebook.com/whitehat/) for the safe disclosure of security bugs. With that in mind, please do not file public issues; go through the process outlined on that page.

### [](#how-to-get-in-touch)How to Get in Touch

* IRC: [#reactjs on freenode](https://webchat.freenode.net/?channels=reactjs)
* [Discussion forums](/community/support.html#popular-discussion-forums)

There is also [an active community of React users on the Discord chat platform](https://www.reactiflux.com/) in case you need help with React.

### [](#proposing-a-change)Proposing a Change

If you intend to change the public API, or make any non-trivial changes to the implementation, we recommend [filing an issue](https://github.com/facebook/react/issues/new). This lets us reach an agreement on your proposal before you put significant effort into it.

If you’re only fixing a bug, it’s fine to submit a pull request right away but we still recommend to file an issue detailing what you’re fixing. This is helpful in case we don’t accept that specific fix but want to keep track of the issue.

### [](#your-first-pull-request)Your First Pull Request

Working on your first Pull Request? You can learn how from this free video series:

**[How to Contribute to an Open Source Project on GitHub](https://egghead.io/courses/how-to-contribute-to-an-open-source-project-on-github)**

To help you get your feet wet and get you familiar with our contribution process, we have a list of **[good first issues](https://github.com/facebook/react/issues?q=is:open+is:issue+label:%22good+first+issue%22)** that contain bugs that have a relatively limited scope. This is a great place to get started.

If you decide to fix an issue, please be sure to check the comment thread in case somebody is already working on a fix. If nobody is working on it at the moment, please leave a comment stating that you intend to work on it so other people don’t accidentally duplicate your effort.

If somebody claims an issue but doesn’t follow up for more than two weeks, it’s fine to take it over but you should still leave a comment.

### [](#sending-a-pull-request)Sending a Pull Request

The core team is monitoring for pull requests. We will review your pull request and either merge it, request changes to it, or close it with an explanation. For API changes we may need to fix our internal uses at Facebook.com, which could cause some delay. We’ll do our best to provide updates and feedback throughout the process.

**Before submitting a pull request,** please make sure the following is done:

1. Fork [the repository](https://github.com/facebook/react) and create your branch from `main`.
2. Run `yarn` in the repository root.
3. If you’ve fixed a bug or added code that should be tested, add tests!
4. Ensure the test suite passes (`yarn test`). Tip: `yarn test --watch TestName` is helpful in development.
5. Run `yarn test --prod` to test in the production environment.
6. If you need a debugger, run `yarn test --debug --watch TestName`, open `chrome://inspect`, and press “Inspect”.
7. Format your code with [prettier](https://github.com/prettier/prettier) (`yarn prettier`).
8. Make sure your code lints (`yarn lint`). Tip: `yarn linc` to only check changed files.
9. Run the [Flow](https://flowtype.org/) typechecks (`yarn flow`).
10. If you haven’t already, complete the CLA.

### [](#contributor-license-agreement-cla)Contributor License Agreement (CLA)

In order to accept your pull request, we need you to submit a CLA. You only need to do this once, so if you’ve done this for another Facebook open source project, you’re good to go. If you are submitting a pull request for the first time, just let us know that you have completed the CLA and we can cross-check with your GitHub username.

**[Complete your CLA here.](https://code.facebook.com/cla)**

### [](#contribution-prerequisites)Contribution Prerequisites

* You have [Node](https://nodejs.org) installed at LTS and [Yarn](https://yarnpkg.com/en/) at v1.2.0+.
* You have [JDK](https://www.oracle.com/technetwork/java/javase/downloads/index.html) installed.
* You have `gcc` installed or are comfortable installing a compiler if needed. Some of our dependencies may require a compilation step. On OS X, the Xcode Command Line Tools will cover this. On Ubuntu, `apt-get install build-essential` will install the required packages. Similar commands should work on other Linux distros. Windows will require some additional steps, see the [`node-gyp` installation instructions](https://github.com/nodejs/node-gyp#installation) for details.
* You are familiar with Git.

### [](#development-workflow)Development Workflow

After cloning React, run `yarn` to fetch its dependencies. Then, you can run several commands:

* `yarn lint` checks the code style.
* `yarn linc` is like `yarn lint` but faster because it only checks files that differ in your branch.
* `yarn test` runs the complete test suite.
* `yarn test --watch` runs an interactive test watcher.
* `yarn test --prod` runs tests in the production environment.
* `yarn test <pattern>` runs tests with matching filenames.
* `yarn debug-test` is just like `yarn test` but with a debugger. Open `chrome://inspect` and press “Inspect”.
* `yarn flow` runs the [Flow](https://flowtype.org/) typechecks.
* `yarn build` creates a `build` folder with all the packages.
* `yarn build react/index,react-dom/index --type=UMD` creates UMD builds of just React and ReactDOM.

We recommend running `yarn test` (or its variations above) to make sure you don’t introduce any regressions as you work on your change. However, it can be handy to try your build of React in a real project.

First, run `yarn build`. This will produce pre-built bundles in `build` folder, as well as prepare npm packages inside `build/packages`.

The easiest way to try your changes is to run `yarn build react/index,react-dom/index --type=UMD` and then open `fixtures/packaging/babel-standalone/dev.html`. This file already uses `react.development.js` from the `build` folder so it will pick up your changes.

If you want to try your changes in your existing React project, you may copy `build/node_modules/react/umd/react.development.js`, `build/node_modules/react-dom/umd/react-dom.development.js`, or any other build products into your app and use them instead of the stable version.

If your project uses React from npm, you may delete `react` and `react-dom` in its dependencies and use `yarn link` to point them to your local `build` folder. Note that **instead of `--type=UMD` you’ll want to pass `--type=NODE` when building**. You’ll also need to build the `scheduler` package:

```
cd ~/path_to_your_react_clone/
yarn build react/index,react/jsx,react-dom/index,scheduler --type=NODE

cd build/node_modules/react
yarn link
cd build/node_modules/react-dom
yarn link

cd ~/path/to/your/project
yarn link react react-dom
```

Every time you run `yarn build` in the React folder, the updated versions will appear in your project’s `node_modules`. You can then rebuild your project to try your changes.

If some package is still missing (e.g. maybe you use `react-dom/server` in your project), you can always do a full build with `yarn build`. Note that running `yarn build` without options takes a long time.

We still require that your pull request contains unit tests for any new functionality. This way we can ensure that we don’t break your code in the future.

### [](#style-guide)Style Guide

We use an automatic code formatter called [Prettier](https://prettier.io/). Run `yarn prettier` after making any changes to the code.

Then, our linter will catch most issues that may exist in your code. You can check the status of your code styling by simply running `yarn linc`.

However, there are still some styles that the linter cannot pick up. If you are unsure about something, looking at [Airbnb’s Style Guide](https://github.com/airbnb/javascript) will guide you in the right direction.

### [](#request-for-comments-rfc)Request for Comments (RFC)

Many changes, including bug fixes and documentation improvements can be implemented and reviewed via the normal GitHub pull request workflow.

Some changes though are “substantial”, and we ask that these be put through a bit of a design process and produce a consensus among the React core team.

The “RFC” (request for comments) process is intended to provide a consistent and controlled path for new features to enter the project. You can contribute by visiting the [rfcs repository](https://github.com/reactjs/rfcs).

### [](#license)License

By contributing to React, you agree that your contributions will be licensed under its MIT license.

### [](#what-next)What Next?

Read the [next section](/docs/codebase-overview.html) to learn how the codebase is organized.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/how-to-contribute.md)

*

* Next article

  [Codebase Overview](/docs/codebase-overview.html)

----
url: https://18.react.dev/learn/sharing-state-between-components
----

```
import { useState } from 'react';

function Panel({ title, children }) {
  const [isActive, setIsActive] = useState(false);
  return (
    <section className="panel">
      <h3>{title}</h3>
      {isActive ? (
        <p>{children}</p>
      ) : (
        <button onClick={() => setIsActive(true)}>
          Show
        </button>
      )}
    </section>
  );
}

export default function Accordion() {
  return (
    <>
      <h2>Almaty, Kazakhstan</h2>
      <Panel title="About">
        With a population of about 2 million, Almaty is Kazakhstan's largest city. From 1929 to 1997, it was its capital city.
      </Panel>
      <Panel title="Etymology">
        The name comes from <span lang="kk-KZ">алма</span>, the Kazakh word for "apple" and is often translated as "full of apples". In fact, the region surrounding Almaty is thought to be the ancestral home of the apple, and the wild <i lang="la">Malus sieversii</i> is considered a likely candidate for the ancestor of the modern domestic apple.
      </Panel>
    </>
  );
}
```

```
const [isActive, setIsActive] = useState(false);
```

And instead, add `isActive` to the `Panel`’s list of props:

```
function Panel({ title, children, isActive }) {
```

```
import { useState } from 'react';

export default function Accordion() {
  return (
    <>
      <h2>Almaty, Kazakhstan</h2>
      <Panel title="About" isActive={true}>
        With a population of about 2 million, Almaty is Kazakhstan's largest city. From 1929 to 1997, it was its capital city.
      </Panel>
      <Panel title="Etymology" isActive={true}>
        The name comes from <span lang="kk-KZ">алма</span>, the Kazakh word for "apple" and is often translated as "full of apples". In fact, the region surrounding Almaty is thought to be the ancestral home of the apple, and the wild <i lang="la">Malus sieversii</i> is considered a likely candidate for the ancestor of the modern domestic apple.
      </Panel>
    </>
  );
}

function Panel({ title, children, isActive }) {
  return (
    <section className="panel">
      <h3>{title}</h3>
      {isActive ? (
        <p>{children}</p>
      ) : (
        <button onClick={() => setIsActive(true)}>
          Show
        </button>
      )}
    </section>
  );
}
```

Try editing the hardcoded `isActive` values in the `Accordion` component and see the result on the screen.

### Step 3: Add state to the common parent[](#step-3-add-state-to-the-common-parent "Link for Step 3: Add state to the common parent ")

Lifting state up often changes the nature of what you’re storing as state.

In this case, only one panel should be active at a time. This means that the `Accordion` common parent component needs to keep track of *which* panel is the active one. Instead of a `boolean` value, it could use a number as the index of the active `Panel` for the state variable:

```
const [activeIndex, setActiveIndex] = useState(0);
```

When the `activeIndex` is `0`, the first panel is active, and when it’s `1`, it’s the second one.

Clicking the “Show” button in either `Panel` needs to change the active index in `Accordion`. A `Panel` can’t set the `activeIndex` state directly because it’s defined inside the `Accordion`. The `Accordion` component needs to *explicitly allow* the `Panel` component to change its state by [passing an event handler down as a prop](/learn/responding-to-events#passing-event-handlers-as-props):

```
<>

  <Panel

    isActive={activeIndex === 0}

    onShow={() => setActiveIndex(0)}

  >

    ...

  </Panel>

  <Panel

    isActive={activeIndex === 1}

    onShow={() => setActiveIndex(1)}

  >

    ...

  </Panel>

</>
```

The `<button>` inside the `Panel` will now use the `onShow` prop as its click event handler:

```
import { useState } from 'react';

export default function Accordion() {
  const [activeIndex, setActiveIndex] = useState(0);
  return (
    <>
      <h2>Almaty, Kazakhstan</h2>
      <Panel
        title="About"
        isActive={activeIndex === 0}
        onShow={() => setActiveIndex(0)}
      >
        With a population of about 2 million, Almaty is Kazakhstan's largest city. From 1929 to 1997, it was its capital city.
      </Panel>
      <Panel
        title="Etymology"
        isActive={activeIndex === 1}
        onShow={() => setActiveIndex(1)}
      >
        The name comes from <span lang="kk-KZ">алма</span>, the Kazakh word for "apple" and is often translated as "full of apples". In fact, the region surrounding Almaty is thought to be the ancestral home of the apple, and the wild <i lang="la">Malus sieversii</i> is considered a likely candidate for the ancestor of the modern domestic apple.
      </Panel>
    </>
  );
}

function Panel({
  title,
  children,
  isActive,
  onShow
}) {
  return (
    <section className="panel">
      <h3>{title}</h3>
      {isActive ? (
        <p>{children}</p>
      ) : (
        <button onClick={onShow}>
          Show
        </button>
      )}
    </section>
  );
}
```

```
import { useState } from 'react';

export default function SyncedInputs() {
  return (
    <>
      <Input label="First input" />
      <Input label="Second input" />
    </>
  );
}

function Input({ label }) {
  const [text, setText] = useState('');

  function handleChange(e) {
    setText(e.target.value);
  }

  return (
    <label>
      {label}
      {' '}
      <input
        value={text}
        onChange={handleChange}
      />
    </label>
  );
}
```

[PreviousChoosing the State Structure](/learn/choosing-the-state-structure)

[NextPreserving and Resetting State](/learn/preserving-and-resetting-state)

***

----
url: https://18.react.dev/learn/reacting-to-input-with-state
----

```
async function handleFormSubmit(e) {
  e.preventDefault();
  disable(textarea);
  disable(button);
  show(loadingMessage);
  hide(errorMessage);
  try {
    await submitForm(textarea.value);
    show(successMessage);
    hide(form);
  } catch (err) {
    show(errorMessage);
    errorMessage.textContent = err.message;
  } finally {
    hide(loadingMessage);
    enable(textarea);
    enable(button);
  }
}

function handleTextareaChange() {
  if (textarea.value.length === 0) {
    disable(button);
  } else {
    enable(button);
  }
}

function hide(el) {
  el.style.display = 'none';
}

function show(el) {
  el.style.display = '';
}

function enable(el) {
  el.disabled = false;
}

function disable(el) {
  el.disabled = true;
}

function submitForm(answer) {
  // Pretend it's hitting the network.
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (answer.toLowerCase() === 'istanbul') {
        resolve();
      } else {
        reject(new Error('Good guess but a wrong answer. Try again!'));
      }
    }, 1500);
  });
}

let form = document.getElementById('form');
let textarea = document.getElementById('textarea');
let button = document.getElementById('button');
let loadingMessage = document.getElementById('loading');
let errorMessage = document.getElementById('error');
let successMessage = document.getElementById('success');
form.onsubmit = handleFormSubmit;
textarea.oninput = handleTextareaChange;
```

```
export default function Form({
  status = 'empty'
}) {
  if (status === 'success') {
    return <h1>That's right!</h1>
  }
  return (
    <>
      <h2>City quiz</h2>
      <p>
        In which city is there a billboard that turns air into drinkable water?
      </p>
      <form>
        <textarea />
        <br />
        <button>
          Submit
        </button>
      </form>
    </>
  )
}
```

You could call that prop anything you like, the naming is not important. Try editing `status = 'empty'` to `status = 'success'` to see the success message appear. Mocking lets you quickly iterate on the UI before you wire up any logic. Here is a more fleshed out prototype of the same component, still “controlled” by the `status` prop:

```
export default function Form({
  // Try 'submitting', 'error', 'success':
  status = 'empty'
}) {
  if (status === 'success') {
    return <h1>That's right!</h1>
  }
  return (
    <>
      <h2>City quiz</h2>
      <p>
        In which city is there a billboard that turns air into drinkable water?
      </p>
      <form>
        <textarea disabled={
          status === 'submitting'
        } />
        <br />
        <button disabled={
          status === 'empty' ||
          status === 'submitting'
        }>
          Submit
        </button>
        {status === 'error' &&
          <p className="Error">
            Good guess but a wrong answer. Try again!
          </p>
        }
      </form>
      </>
  );
}
```

##### Deep Dive#### Displaying many visual states at once[](#displaying-many-visual-states-at-once "Link for Displaying many visual states at once ")

If a component has a lot of visual states, it can be convenient to show them all on one page:

```
import Form from './Form.js';

let statuses = [
  'empty',
  'typing',
  'submitting',
  'success',
  'error',
];

export default function App() {
  return (
    <>
      {statuses.map(status => (
        <section key={status}>
          <h4>Form ({status}):</h4>
          <Form status={status} />
        </section>
      ))}
    </>
  );
}
```

```
const [answer, setAnswer] = useState('');

const [error, setError] = useState(null);
```

Then, you’ll need a state variable representing which one of the visual states that you want to display. There’s usually more than a single way to represent that in memory, so you’ll need to experiment with it.

If you struggle to think of the best way immediately, start by adding enough state that you’re *definitely* sure that all the possible visual states are covered:

```
const [isEmpty, setIsEmpty] = useState(true);

const [isTyping, setIsTyping] = useState(false);

const [isSubmitting, setIsSubmitting] = useState(false);

const [isSuccess, setIsSuccess] = useState(false);

const [isError, setIsError] = useState(false);
```

```
const [answer, setAnswer] = useState('');

const [error, setError] = useState(null);

const [status, setStatus] = useState('typing'); // 'typing', 'submitting', or 'success'
```

You know they are essential, because you can’t remove any of them without breaking the functionality.

##### Deep Dive#### Eliminating “impossible” states with a reducer[](#eliminating-impossible-states-with-a-reducer "Link for Eliminating “impossible” states with a reducer ")

These three variables are a good enough representation of this form’s state. However, there are still some intermediate states that don’t fully make sense. For example, a non-null `error` doesn’t make sense when `status` is `'success'`. To model the state more precisely, you can [extract it into a reducer.](/learn/extracting-state-logic-into-a-reducer) Reducers let you unify multiple state variables into a single object and consolidate all the related logic!

### Step 5: Connect the event handlers to set state[](#step-5-connect-the-event-handlers-to-set-state "Link for Step 5: Connect the event handlers to set state ")

Lastly, create event handlers that update the state. Below is the final form, with all event handlers wired up:

```
import { useState } from 'react';

export default function Form() {
  const [answer, setAnswer] = useState('');
  const [error, setError] = useState(null);
  const [status, setStatus] = useState('typing');

  if (status === 'success') {
    return <h1>That's right!</h1>
  }

  async function handleSubmit(e) {
    e.preventDefault();
    setStatus('submitting');
    try {
      await submitForm(answer);
      setStatus('success');
    } catch (err) {
      setStatus('typing');
      setError(err);
    }
  }

  function handleTextareaChange(e) {
    setAnswer(e.target.value);
  }

  return (
    <>
      <h2>City quiz</h2>
      <p>
        In which city is there a billboard that turns air into drinkable water?
      </p>
      <form onSubmit={handleSubmit}>
        <textarea
          value={answer}
          onChange={handleTextareaChange}
          disabled={status === 'submitting'}
        />
        <br />
        <button disabled={
          answer.length === 0 ||
          status === 'submitting'
        }>
          Submit
        </button>
        {error !== null &&
          <p className="Error">
            {error.message}
          </p>
        }
      </form>
    </>
  );
}

function submitForm(answer) {
  // Pretend it's hitting the network.
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      let shouldError = answer.toLowerCase() !== 'lima'
      if (shouldError) {
        reject(new Error('Good guess but a wrong answer. Try again!'));
      } else {
        resolve();
      }
    }, 1500);
  });
}
```

```
export default function Picture() {
  return (
    <div className="background background--active">
      <img
        className="picture"
        alt="Rainbow houses in Kampung Pelangi, Indonesia"
        src="https://i.imgur.com/5qwVYb1.jpeg"
      />
    </div>
  );
}
```

[PreviousManaging State](/learn/managing-state)

[NextChoosing the State Structure](/learn/choosing-the-state-structure)

***

----
url: https://legacy.reactjs.org/blog/2015/10/07/react-v0.14.html
----

October 07, 2015 by [Sophie Alpert](https://sophiebits.com/)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

We’re happy to announce the release of React 0.14 today! This release has a few major changes, primarily designed to simplify the code you write every day and to better support environments like React Native.

If you tried the release candidate, thank you – your support is invaluable and we’ve fixed a few bugs that you reported.

As with all of our releases, we consider this version to be stable enough to use in production and recommend that you upgrade in order to take advantage of our latest improvements.

## [](#upgrade-guide)Upgrade Guide

Like always, we have a few breaking changes in this release. We know changes can be painful (the Facebook codebase has over 15,000 React components), so we always try to make changes gradually in order to minimize the pain.

If your code is free of warnings when running under React 0.13, upgrading should be easy. We have two new small breaking changes that didn’t give a warning in 0.13 (see below). Every new change in 0.14, including the major changes below, is introduced with a runtime warning and will work as before until 0.15, so you don’t have to worry about your app breaking with this upgrade.

For the two major changes which require significant code changes, we’ve included [codemod scripts](https://github.com/reactjs/react-codemod/blob/master/README.md) to help you upgrade your code automatically.

  Dev build with warnings: <https://fb.me/react-0.14.0.js>\
  Minified build for production: <https://fb.me/react-0.14.0.min.js>
* **React with Add-Ons**\
  Dev build with warnings: <https://fb.me/react-with-addons-0.14.0.js>\
  Minified build for production: <https://fb.me/react-with-addons-0.14.0.min.js>
* **React DOM** (include React in the page before React DOM)\
  Dev build with warnings: <https://fb.me/react-dom-0.14.0.js>\
  Minified build for production: <https://fb.me/react-dom-0.14.0.min.js>

  ```
  var React = require('react');
  var ReactDOM = require('react-dom');

  var MyComponent = React.createClass({
    render: function() {
      return <div>Hello World</div>;
    }
  });

  ReactDOM.render(<MyComponent />, node);
  ```

  The old names will continue to work with a warning until 0.15 is released, and we’ve published the [automated codemod script](https://github.com/reactjs/react-codemod/blob/master/README.md) we used at Facebook to help you with this transition.

  The add-ons have moved to separate packages as well:

  * `react-addons-clone-with-props`
  * `react-addons-create-fragment`
  * `react-addons-css-transition-group`
  * `react-addons-linked-state-mixin`
  * `react-addons-perf`
  * `react-addons-pure-render-mixin`
  * `react-addons-shallow-compare`
  * `react-addons-test-utils`
  * `react-addons-transition-group`
  * `react-addons-update`
  * `ReactDOM.unstable_batchedUpdates` in `react-dom`.

  For now, please use matching versions of `react` and `react-dom` (and the add-ons, if you use them) in your apps to avoid versioning problems.

* #### [](#dom-node-refs)DOM node refs

  The other big change we’re making in this release is exposing refs to DOM components as the DOM node itself. That means: we looked at what you can do with a `ref` to a React DOM component and realized that the only useful thing you can do with it is call `this.refs.giraffe.getDOMNode()` to get the underlying DOM node. Starting with this release, `this.refs.giraffe` *is* the actual DOM node. **Note that refs to custom (user-defined) components work exactly as before; only the built-in DOM components are affected by this change.**

  ```
  var Zoo = React.createClass({
    render: function() {
      return <div>Giraffe name: <input ref="giraffe" /></div>;
    },
    showName: function() {
      // Previously: var input = this.refs.giraffe.getDOMNode();
      var input = this.refs.giraffe;
      alert(input.value);
    }
  });
  ```

  This change also applies to the return result of `ReactDOM.render` when passing a DOM node as the top component. As with refs, this change does not affect custom components.

  With this change, we’re deprecating `.getDOMNode()` and replacing it with `ReactDOM.findDOMNode` (see below). If your components are currently using `.getDOMNode()`, they will continue to work with a warning until 0.15.

* #### [](#stateless-function-components)Stateless function components

  In idiomatic React code, most of the components you write will be stateless, simply composing other components. We’re introducing a new, simpler syntax for these components where you can take `props` as an argument and return the element you want to render:

  ```
  // A function component using an ES2015 (ES6) arrow function:
  var Aquarium = (props) => {
    var fish = getFish(props.species);
    return <Tank>{fish}</Tank>;
  };

  // Or with destructuring and an implicit return, simply:
  var Aquarium = ({species}) => (
    <Tank>
      {getFish(species)}
    </Tank>
  );

  // Then use: <Aquarium species="rainbowfish" />
  ```

  These components behave just like a React class with only a `render` method defined. Since no component instance is created for a function component, any `ref` added to one will evaluate to `null`. Function components do not have lifecycle methods, but you can set `.propTypes` and `.defaultProps` as properties on the function.

  This pattern is designed to encourage the creation of these simple components that should comprise large portions of your apps. In the future, we’ll also be able to make performance optimizations specific to these components by avoiding unnecessary checks and memory allocations.

* #### [](#deprecation-of-react-tools)Deprecation of react-tools

  The `react-tools` package and `JSXTransformer.js` browser file [have been deprecated](/blog/2015/06/12/deprecating-jstransform-and-react-tools.html). You can continue using version `0.13.3` of both, but we no longer support them and recommend migrating to [Babel](http://babeljs.io/), which has built-in support for React and JSX.

* #### [](#compiler-optimizations)Compiler optimizations

  React now supports two compiler optimizations that can be enabled in Babel 5.8.24 and newer. Both of these transforms **should be enabled only in production** (e.g., just before minifying your code) because although they improve runtime performance, they make warning messages more cryptic and skip important checks that happen in development mode, including propTypes.

  **Inlining React elements:** The `optimisation.react.inlineElements` transform converts JSX elements to object literals like `{type: 'div', props: ...}` instead of calls to `React.createElement`.

  **Constant hoisting for React elements:** The `optimisation.react.constantElements` transform hoists element creation to the top level for subtrees that are fully static, which reduces calls to `React.createElement` and the resulting allocations. More importantly, it tells React that the subtree hasn’t changed so React can completely skip it when reconciling.

### [](#breaking-changes)Breaking changes

In almost all cases, we change our APIs gradually and warn for at least one release to give you time to clean up your code. These two breaking changes did not have a warning in 0.13 but should be easy to find and clean up:

* `React.initializeTouchEvents` is no longer necessary and has been removed completely. Touch events now work automatically.
* Add-Ons: Due to the DOM node refs change mentioned above, `TestUtils.findAllInRenderedTree` and related helpers are no longer able to take a DOM component, only a custom component.

These three breaking changes had a warning in 0.13, so you shouldn’t have to do anything if your code is already free of warnings:

* The `props` object is now frozen, so mutating props after creating a component element is no longer supported. In most cases, [`React.cloneElement`](/docs/top-level-api.html#react.cloneelement) should be used instead. This change makes your components easier to reason about and enables the compiler optimizations mentioned above.
* Plain objects are no longer supported as React children; arrays should be used instead. You can use the [`createFragment`](/docs/create-fragment.html) helper to migrate, which now returns an array.
* Add-Ons: `classSet` has been removed. Use [classnames](https://github.com/JedWatson/classnames) instead.

### [](#new-deprecations-introduced-with-a-warning)New deprecations, introduced with a warning

Each of these changes will continue to work as before with a new warning until the release of 0.15 so you can upgrade your code gradually.

* Due to the DOM node refs change mentioned above, `this.getDOMNode()` is now deprecated and `ReactDOM.findDOMNode(this)` can be used instead. Note that in most cases, calling `findDOMNode` is now unnecessary – see the example above in the “DOM node refs” section.

  With each returned DOM node, we’ve added a `getDOMNode` method for backwards compatibility that will work with a warning until 0.15. If you have a large codebase, you can use our [automated codemod script](https://github.com/reactjs/react-codemod/blob/master/README.md) to change your code automatically.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2015-10-07-react-v0.14.md)

----
url: https://react.dev/reference/react/Suspense
----

[API Reference](/reference/react)

[Components](/reference/react/components)

# \<Suspense>[](#undefined "Link for this heading")

`<Suspense>` lets you display a fallback until its children have finished loading.

```
<Suspense fallback={<Loading />}>

  <SomeComponent />

</Suspense>
```

***

***

## Usage[](#usage "Link for Usage ")

### Displaying a fallback while content is loading[](#displaying-a-fallback-while-content-is-loading "Link for Displaying a fallback while content is loading ")

You can wrap any part of your application with a Suspense boundary:

```
<Suspense fallback={<Loading />}>

  <Albums />

</Suspense>
```

React will display your loading fallback until all the code and data needed by the children has been loaded.

In the example below, the `Albums` component *suspends* while fetching the list of albums. Until it’s ready to render, React switches the closest Suspense boundary above to show the fallback—your `Loading` component. Then, when the data loads, React hides the `Loading` fallback and renders the `Albums` component with data.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { Suspense } from 'react';
import Albums from './Albums.js';

export default function ArtistPage({ artist }) {
  return (
    <>
      <h1>{artist.name}</h1>
      <Suspense fallback={<Loading />}>
        <Albums artistId={artist.id} />
      </Suspense>
    </>
  );
}

function Loading() {
  return <h2>🌀 Loading...</h2>;
}
```

### Note

**Only Suspense-enabled data sources will activate the Suspense component.** They include:

* Data fetching with Suspense-enabled frameworks like [Relay](https://relay.dev/docs/guided-tour/rendering/loading-states/) and [Next.js](https://nextjs.org/docs/app/building-your-application/routing/loading-ui-and-streaming#streaming-with-suspense)
* Lazy-loading component code with [`lazy`](/reference/react/lazy)
* Reading the value of a cached Promise with [`use`](/reference/react/use)

Suspense **does not** detect when data is fetched inside an Effect or event handler.

The exact way you would load data in the `Albums` component above depends on your framework. If you use a Suspense-enabled framework, you’ll find the details in its data fetching documentation.

Suspense-enabled data fetching without the use of an opinionated framework is not yet supported. The requirements for implementing a Suspense-enabled data source are unstable and undocumented. An official API for integrating data sources with Suspense will be released in a future version of React.

***

### Revealing content together at once[](#revealing-content-together-at-once "Link for Revealing content together at once ")

By default, the whole tree inside Suspense is treated as a single unit. For example, even if *only one* of these components suspends waiting for some data, *all* of them together will be replaced by the loading indicator:

```
<Suspense fallback={<Loading />}>

  <Biography />

  <Panel>

    <Albums />

  </Panel>

</Suspense>
```

Then, after all of them are ready to be displayed, they will all appear together at once.

In the example below, both `Biography` and `Albums` fetch some data. However, because they are grouped under a single Suspense boundary, these components always “pop in” together at the same time.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { Suspense } from 'react';
import Albums from './Albums.js';
import Biography from './Biography.js';
import Panel from './Panel.js';

export default function ArtistPage({ artist }) {
  return (
    <>
      <h1>{artist.name}</h1>
      <Suspense fallback={<Loading />}>
        <Biography artistId={artist.id} />
        <Panel>
          <Albums artistId={artist.id} />
        </Panel>
      </Suspense>
    </>
  );
}

function Loading() {
  return <h2>🌀 Loading...</h2>;
}
```

Components that load data don’t have to be direct children of the Suspense boundary. For example, you can move `Biography` and `Albums` into a new `Details` component. This doesn’t change the behavior. `Biography` and `Albums` share the same closest parent Suspense boundary, so their reveal is coordinated together.

```
<Suspense fallback={<Loading />}>

  <Details artistId={artist.id} />

</Suspense>



function Details({ artistId }) {

  return (

    <>

      <Biography artistId={artistId} />

      <Panel>

        <Albums artistId={artistId} />

      </Panel>

    </>

  );

}
```

***

### Revealing nested content as it loads[](#revealing-nested-content-as-it-loads "Link for Revealing nested content as it loads ")

When a component suspends, the closest parent Suspense component shows the fallback. This lets you nest multiple Suspense components to create a loading sequence. Each Suspense boundary’s fallback will be filled in as the next level of content becomes available. For example, you can give the album list its own fallback:

```
<Suspense fallback={<BigSpinner />}>

  <Biography />

  <Suspense fallback={<AlbumsGlimmer />}>

    <Panel>

      <Albums />

    </Panel>

  </Suspense>

</Suspense>
```

With this change, displaying the `Biography` doesn’t need to “wait” for the `Albums` to load.

The sequence will be:

1. If `Biography` hasn’t loaded yet, `BigSpinner` is shown in place of the entire content area.
2. Once `Biography` finishes loading, `BigSpinner` is replaced by the content.
3. If `Albums` hasn’t loaded yet, `AlbumsGlimmer` is shown in place of `Albums` and its parent `Panel`.
4. Finally, once `Albums` finishes loading, it replaces `AlbumsGlimmer`.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { Suspense } from 'react';
import Albums from './Albums.js';
import Biography from './Biography.js';
import Panel from './Panel.js';

export default function ArtistPage({ artist }) {
  return (
    <>
      <h1>{artist.name}</h1>
      <Suspense fallback={<BigSpinner />}>
        <Biography artistId={artist.id} />
        <Suspense fallback={<AlbumsGlimmer />}>
          <Panel>
            <Albums artistId={artist.id} />
          </Panel>
        </Suspense>
      </Suspense>
    </>
  );
}

function BigSpinner() {
  return <h2>🌀 Loading...</h2>;
}

function AlbumsGlimmer() {
  return (
    <div className="glimmer-panel">
      <div className="glimmer-line" />
      <div className="glimmer-line" />
      <div className="glimmer-line" />
    </div>
  );
}
```

Suspense boundaries let you coordinate which parts of your UI should always “pop in” together at the same time, and which parts should progressively reveal more content in a sequence of loading states. You can add, move, or delete Suspense boundaries in any place in the tree without affecting the rest of your app’s behavior.

Don’t put a Suspense boundary around every component. Suspense boundaries should not be more granular than the loading sequence that you want the user to experience. If you work with a designer, ask them where the loading states should be placed—it’s likely that they’ve already included them in their design wireframes.

***

### Showing stale content while fresh content is loading[](#showing-stale-content-while-fresh-content-is-loading "Link for Showing stale content while fresh content is loading ")

In this example, the `SearchResults` component suspends while fetching the search results. Type `"a"`, wait for the results, and then edit it to `"ab"`. The results for `"a"` will get replaced by the loading fallback.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { Suspense, useState } from 'react';
import SearchResults from './SearchResults.js';

export default function App() {
  const [query, setQuery] = useState('');
  return (
    <>
      <label>
        Search albums:
        <input value={query} onChange={e => setQuery(e.target.value)} />
      </label>
      <Suspense fallback={<h2>Loading...</h2>}>
        <SearchResults query={query} />
      </Suspense>
    </>
  );
}
```

A common alternative UI pattern is to *defer* updating the list and to keep showing the previous results until the new results are ready. The [`useDeferredValue`](/reference/react/useDeferredValue) Hook lets you pass a deferred version of the query down:

```
export default function App() {

  const [query, setQuery] = useState('');

  const deferredQuery = useDeferredValue(query);

  return (

    <>

      <label>

        Search albums:

        <input value={query} onChange={e => setQuery(e.target.value)} />

      </label>

      <Suspense fallback={<h2>Loading...</h2>}>

        <SearchResults query={deferredQuery} />

      </Suspense>

    </>

  );

}
```

The `query` will update immediately, so the input will display the new value. However, the `deferredQuery` will keep its previous value until the data has loaded, so `SearchResults` will show the stale results for a bit.

To make it more obvious to the user, you can add a visual indication when the stale result list is displayed:

```
<div style={{

  opacity: query !== deferredQuery ? 0.5 : 1

}}>

  <SearchResults query={deferredQuery} />

</div>
```

Enter `"a"` in the example below, wait for the results to load, and then edit the input to `"ab"`. Notice how instead of the Suspense fallback, you now see the dimmed stale result list until the new results have loaded:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { Suspense, useState, useDeferredValue } from 'react';
import SearchResults from './SearchResults.js';

export default function App() {
  const [query, setQuery] = useState('');
  const deferredQuery = useDeferredValue(query);
  const isStale = query !== deferredQuery;
  return (
    <>
      <label>
        Search albums:
        <input value={query} onChange={e => setQuery(e.target.value)} />
      </label>
      <Suspense fallback={<h2>Loading...</h2>}>
        <div style={{ opacity: isStale ? 0.5 : 1 }}>
          <SearchResults query={deferredQuery} />
        </div>
      </Suspense>
    </>
  );
}
```

### Note

Both deferred values and [Transitions](#preventing-already-revealed-content-from-hiding) let you avoid showing Suspense fallback in favor of inline indicators. Transitions mark the whole update as non-urgent so they are typically used by frameworks and router libraries for navigation. Deferred values, on the other hand, are mostly useful in application code where you want to mark a part of UI as non-urgent and let it “lag behind” the rest of the UI.

***

### Preventing already revealed content from hiding[](#preventing-already-revealed-content-from-hiding "Link for Preventing already revealed content from hiding ")

When a component suspends, the closest parent Suspense boundary switches to showing the fallback. This can lead to a jarring user experience if it was already displaying some content. Try pressing this button:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { Suspense, useState } from 'react';
import IndexPage from './IndexPage.js';
import ArtistPage from './ArtistPage.js';
import Layout from './Layout.js';

export default function App() {
  return (
    <Suspense fallback={<BigSpinner />}>
      <Router />
    </Suspense>
  );
}

function Router() {
  const [page, setPage] = useState('/');

  function navigate(url) {
    setPage(url);
  }

  let content;
  if (page === '/') {
    content = (
      <IndexPage navigate={navigate} />
    );
  } else if (page === '/the-beatles') {
    content = (
      <ArtistPage
        artist={{
          id: 'the-beatles',
          name: 'The Beatles',
        }}
      />
    );
  }
  return (
    <Layout>
      {content}
    </Layout>
  );
}

function BigSpinner() {
  return <h2>🌀 Loading...</h2>;
}
```

When you pressed the button, the `Router` component rendered `ArtistPage` instead of `IndexPage`. A component inside `ArtistPage` suspended, so the closest Suspense boundary started showing the fallback. The closest Suspense boundary was near the root, so the whole site layout got replaced by `BigSpinner`.

To prevent this, you can mark the navigation state update as a *Transition* with [`startTransition`:](/reference/react/startTransition)

```
function Router() {

  const [page, setPage] = useState('/');



  function navigate(url) {

    startTransition(() => {

      setPage(url);

    });

  }

  // ...
```

This tells React that the state transition is not urgent, and it’s better to keep showing the previous page instead of hiding any already revealed content. Now clicking the button “waits” for the `Biography` to load:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { Suspense, startTransition, useState } from 'react';
import IndexPage from './IndexPage.js';
import ArtistPage from './ArtistPage.js';
import Layout from './Layout.js';

export default function App() {
  return (
    <Suspense fallback={<BigSpinner />}>
      <Router />
    </Suspense>
  );
}

function Router() {
  const [page, setPage] = useState('/');

  function navigate(url) {
    startTransition(() => {
      setPage(url);
    });
  }

  let content;
  if (page === '/') {
    content = (
      <IndexPage navigate={navigate} />
    );
  } else if (page === '/the-beatles') {
    content = (
      <ArtistPage
        artist={{
          id: 'the-beatles',
          name: 'The Beatles',
        }}
      />
    );
  }
  return (
    <Layout>
      {content}
    </Layout>
  );
}

function BigSpinner() {
  return <h2>🌀 Loading...</h2>;
}
```

A Transition doesn’t wait for *all* content to load. It only waits long enough to avoid hiding already revealed content. For example, the website `Layout` was already revealed, so it would be bad to hide it behind a loading spinner. However, the nested `Suspense` boundary around `Albums` is new, so the Transition doesn’t wait for it.

### Note

Suspense-enabled routers are expected to wrap the navigation updates into Transitions by default.

***

### Indicating that a Transition is happening[](#indicating-that-a-transition-is-happening "Link for Indicating that a Transition is happening ")

In the above example, once you click the button, there is no visual indication that a navigation is in progress. To add an indicator, you can replace [`startTransition`](/reference/react/startTransition) with [`useTransition`](/reference/react/useTransition) which gives you a boolean `isPending` value. In the example below, it’s used to change the website header styling while a Transition is happening:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { Suspense, useState, useTransition } from 'react';
import IndexPage from './IndexPage.js';
import ArtistPage from './ArtistPage.js';
import Layout from './Layout.js';

export default function App() {
  return (
    <Suspense fallback={<BigSpinner />}>
      <Router />
    </Suspense>
  );
}

function Router() {
  const [page, setPage] = useState('/');
  const [isPending, startTransition] = useTransition();

  function navigate(url) {
    startTransition(() => {
      setPage(url);
    });
  }

  let content;
  if (page === '/') {
    content = (
      <IndexPage navigate={navigate} />
    );
  } else if (page === '/the-beatles') {
    content = (
      <ArtistPage
        artist={{
          id: 'the-beatles',
          name: 'The Beatles',
        }}
      />
    );
  }
  return (
    <Layout isPending={isPending}>
      {content}
    </Layout>
  );
}

function BigSpinner() {
  return <h2>🌀 Loading...</h2>;
}
```

***

### Resetting Suspense boundaries on navigation[](#resetting-suspense-boundaries-on-navigation "Link for Resetting Suspense boundaries on navigation ")

During a Transition, React will avoid hiding already revealed content. However, if you navigate to a route with different parameters, you might want to tell React it is *different* content. You can express this with a `key`:

```
<ProfilePage key={queryParams.id} />
```

Imagine you’re navigating within a user’s profile page, and something suspends. If that update is wrapped in a Transition, it will not trigger the fallback for already visible content. That’s the expected behavior.

However, now imagine you’re navigating between two different user profiles. In that case, it makes sense to show the fallback. For example, one user’s timeline is *different content* from another user’s timeline. By specifying a `key`, you ensure that React treats different users’ profiles as different components, and resets the Suspense boundaries during navigation. Suspense-integrated routers should do this automatically.

***

### Providing a fallback for server errors and client-only content[](#providing-a-fallback-for-server-errors-and-client-only-content "Link for Providing a fallback for server errors and client-only content ")

If you use one of the [streaming server rendering APIs](/reference/react-dom/server) (or a framework that relies on them), React will also use your `<Suspense>` boundaries to handle errors on the server. If a component throws an error on the server, React will not abort the server render. Instead, it will find the closest `<Suspense>` component above it and include its fallback (such as a spinner) into the generated server HTML. The user will see a spinner at first.

On the client, React will attempt to render the same component again. If it errors on the client too, React will throw the error and display the closest [Error Boundary.](/reference/react/Component#static-getderivedstatefromerror) However, if it does not error on the client, React will not display the error to the user since the content was eventually displayed successfully.

You can use this to opt out some components from rendering on the server. To do this, throw an error in the server environment and then wrap them in a `<Suspense>` boundary to replace their HTML with fallbacks:

```
<Suspense fallback={<Loading />}>

  <Chat />

</Suspense>



function Chat() {

  if (typeof window === 'undefined') {

    throw Error('Chat should only render on the client.');

  }

  // ...

}
```

The server HTML will include the loading indicator. It will be replaced by the `Chat` component on the client.

***

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### How do I prevent the UI from being replaced by a fallback during an update?[](#preventing-unwanted-fallbacks "Link for How do I prevent the UI from being replaced by a fallback during an update? ")

Replacing visible UI with a fallback creates a jarring user experience. This can happen when an update causes a component to suspend, and the nearest Suspense boundary is already showing content to the user.

To prevent this from happening, [mark the update as non-urgent using `startTransition`](#preventing-already-revealed-content-from-hiding). During a Transition, React will wait until enough data has loaded to prevent an unwanted fallback from appearing:

```
function handleNextPageClick() {

  // If this update suspends, don't hide the already displayed content

  startTransition(() => {

    setCurrentPage(currentPage + 1);

  });

}
```

This will avoid hiding existing content. However, any newly rendered `Suspense` boundaries will still immediately display fallbacks to avoid blocking the UI and let the user see the content as it becomes available.

**React will only prevent unwanted fallbacks during non-urgent updates**. It will not delay a render if it’s the result of an urgent update. You must opt in with an API like [`startTransition`](/reference/react/startTransition) or [`useDeferredValue`](/reference/react/useDeferredValue).

If your router is integrated with Suspense, it should wrap its updates into [`startTransition`](/reference/react/startTransition) automatically.

[Previous\<StrictMode>](/reference/react/StrictMode)

[Next\<Activity>](/reference/react/Activity)

***

----
url: https://18.react.dev/reference/react/useRef
----

[API Reference](/reference/react)

[Hooks](/reference/react/hooks)

# useRef[](#undefined "Link for this heading")

`useRef` is a React Hook that lets you reference a value that’s not needed for rendering.

```
const ref = useRef(initialValue)
```

***

## Reference[](#reference "Link for Reference ")

### `useRef(initialValue)`[](#useref "Link for this heading")

Call `useRef` at the top level of your component to declare a [ref.](/learn/referencing-values-with-refs)

```
import { useRef } from 'react';



function MyComponent() {

  const intervalRef = useRef(0);

  const inputRef = useRef(null);

  // ...
```

***

## Usage[](#usage "Link for Usage ")

### Referencing a value with a ref[](#referencing-a-value-with-a-ref "Link for Referencing a value with a ref ")

Call `useRef` at the top level of your component to declare one or more [refs.](/learn/referencing-values-with-refs)

```
import { useRef } from 'react';



function Stopwatch() {

  const intervalRef = useRef(0);

  // ...
```

`useRef` returns a ref object with a single `current` property initially set to the initial value you provided.

On the next renders, `useRef` will return the same object. You can change its `current` property to store information and read it later. This might remind you of [state](/reference/react/useState), but there is an important difference.

**Changing a ref does not trigger a re-render.** This means refs are perfect for storing information that doesn’t affect the visual output of your component. For example, if you need to store an [interval ID](https://developer.mozilla.org/en-US/docs/Web/API/setInterval) and retrieve it later, you can put it in a ref. To update the value inside the ref, you need to manually change its `current` property:

```
function handleStartClick() {

  const intervalId = setInterval(() => {

    // ...

  }, 1000);

  intervalRef.current = intervalId;

}
```

Later, you can read that interval ID from the ref so that you can call [clear that interval](https://developer.mozilla.org/en-US/docs/Web/API/clearInterval):

```
function handleStopClick() {

  const intervalId = intervalRef.current;

  clearInterval(intervalId);

}
```

```
import { useRef } from 'react';

export default function Counter() {
  let ref = useRef(0);

  function handleClick() {
    ref.current = ref.current + 1;
    alert('You clicked ' + ref.current + ' times!');
  }

  return (
    <button onClick={handleClick}>
      Click me!
    </button>
  );
}
```

```
function MyComponent() {

  // ...

  // 🚩 Don't write a ref during rendering

  myRef.current = 123;

  // ...

  // 🚩 Don't read a ref during rendering

  return <h1>{myOtherRef.current}</h1>;

}
```

You can read or write refs **from event handlers or effects instead**.

```
function MyComponent() {

  // ...

  useEffect(() => {

    // ✅ You can read or write refs in effects

    myRef.current = 123;

  });

  // ...

  function handleClick() {

    // ✅ You can read or write refs in event handlers

    doSomething(myOtherRef.current);

  }

  // ...

}
```

If you *have to* read [or write](/reference/react/useState#storing-information-from-previous-renders) something during rendering, [use state](/reference/react/useState) instead.

When you break these rules, your component might still work, but most of the newer features we’re adding to React will rely on these expectations. Read more about [keeping your components pure.](/learn/keeping-components-pure#where-you-_can_-cause-side-effects)

***

### Manipulating the DOM with a ref[](#manipulating-the-dom-with-a-ref "Link for Manipulating the DOM with a ref ")

It’s particularly common to use a ref to manipulate the [DOM.](https://developer.mozilla.org/en-US/docs/Web/API/HTML_DOM_API) React has built-in support for this.

First, declare a ref object with an initial value of `null`:

```
import { useRef } from 'react';



function MyComponent() {

  const inputRef = useRef(null);

  // ...
```

Then pass your ref object as the `ref` attribute to the JSX of the DOM node you want to manipulate:

```
  // ...

  return <input ref={inputRef} />;
```

After React creates the DOM node and puts it on the screen, React will set the `current` property of your ref object to that DOM node. Now you can access the `<input>`’s DOM node and call methods like [`focus()`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus):

```
  function handleClick() {

    inputRef.current.focus();

  }
```

React will set the `current` property back to `null` when the node is removed from the screen.

Read more about [manipulating the DOM with refs.](/learn/manipulating-the-dom-with-refs)

#### Examples of manipulating the DOM with useRef[](#examples-dom "Link for Examples of manipulating the DOM with useRef")

#### Example 1 of 4:Focusing a text input[](#focusing-a-text-input "Link for this heading")

In this example, clicking the button will focus the input:

```
import { useRef } from 'react';

export default function Form() {
  const inputRef = useRef(null);

  function handleClick() {
    inputRef.current.focus();
  }

  return (
    <>
      <input ref={inputRef} />
      <button onClick={handleClick}>
        Focus the input
      </button>
    </>
  );
}
```

***

### Avoiding recreating the ref contents[](#avoiding-recreating-the-ref-contents "Link for Avoiding recreating the ref contents ")

React saves the initial ref value once and ignores it on the next renders.

```
function Video() {

  const playerRef = useRef(new VideoPlayer());

  // ...
```

Although the result of `new VideoPlayer()` is only used for the initial render, you’re still calling this function on every render. This can be wasteful if it’s creating expensive objects.

To solve it, you may initialize the ref like this instead:

```
function Video() {

  const playerRef = useRef(null);

  if (playerRef.current === null) {

    playerRef.current = new VideoPlayer();

  }

  // ...
```

Normally, writing or reading `ref.current` during render is not allowed. However, it’s fine in this case because the result is always the same, and the condition only executes during initialization so it’s fully predictable.

##### Deep Dive#### How to avoid null checks when initializing useRef later[](#how-to-avoid-null-checks-when-initializing-use-ref-later "Link for How to avoid null checks when initializing useRef later ")

If you use a type checker and don’t want to always check for `null`, you can try a pattern like this instead:

```
function Video() {

  const playerRef = useRef(null);



  function getPlayer() {

    if (playerRef.current !== null) {

      return playerRef.current;

    }

    const player = new VideoPlayer();

    playerRef.current = player;

    return player;

  }



  // ...
```

Here, the `playerRef` itself is nullable. However, you should be able to convince your type checker that there is no case in which `getPlayer()` returns `null`. Then use `getPlayer()` in your event handlers.

***

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### I can’t get a ref to a custom component[](#i-cant-get-a-ref-to-a-custom-component "Link for I can’t get a ref to a custom component ")

If you try to pass a `ref` to your own component like this:

```
const inputRef = useRef(null);



return <MyInput ref={inputRef} />;
```

You might get an error in the console:

Console

Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?

By default, your own components don’t expose refs to the DOM nodes inside them.

To fix this, find the component that you want to get a ref to:

```
export default function MyInput({ value, onChange }) {

  return (

    <input

      value={value}

      onChange={onChange}

    />

  );

}
```

And then wrap it in [`forwardRef`](/reference/react/forwardRef) like this:

```
import { forwardRef } from 'react';



const MyInput = forwardRef(({ value, onChange }, ref) => {

  return (

    <input

      value={value}

      onChange={onChange}

      ref={ref}

    />

  );

});



export default MyInput;
```

Then the parent component can get a ref to it.

Read more about [accessing another component’s DOM nodes.](/learn/manipulating-the-dom-with-refs#accessing-another-components-dom-nodes)

[PrevioususeReducer](/reference/react/useReducer)

[NextuseState](/reference/react/useState)

***

----
url: https://18.react.dev/reference/react/useImperativeHandle
----

[API Reference](/reference/react)

[Hooks](/reference/react/hooks)

# useImperativeHandle[](#undefined "Link for this heading")

`useImperativeHandle` is a React Hook that lets you customize the handle exposed as a [ref.](/learn/manipulating-the-dom-with-refs)

```
useImperativeHandle(ref, createHandle, dependencies?)
```

* [Reference](#reference)
  * [`useImperativeHandle(ref, createHandle, dependencies?)`](#useimperativehandle)

* [Usage](#usage)

  * [Exposing a custom ref handle to the parent component](#exposing-a-custom-ref-handle-to-the-parent-component)
  * [Exposing your own imperative methods](#exposing-your-own-imperative-methods)

***

## Reference[](#reference "Link for Reference ")

### `useImperativeHandle(ref, createHandle, dependencies?)`[](#useimperativehandle "Link for this heading")

Call `useImperativeHandle` at the top level of your component to customize the ref handle it exposes:

```
import { forwardRef, useImperativeHandle } from 'react';



const MyInput = forwardRef(function MyInput(props, ref) {

  useImperativeHandle(ref, () => {

    return {

      // ... your methods ...

    };

  }, []);

  // ...
```

[See more examples below.](#usage)

#### Parameters[](#parameters "Link for Parameters ")

* `ref`: The `ref` you received as the second argument from the [`forwardRef` render function.](/reference/react/forwardRef#render-function)

* `createHandle`: A function that takes no arguments and returns the ref handle you want to expose. That ref handle can have any type. Usually, you will return an object with the methods you want to expose.

* **optional** `dependencies`: The list of all reactive values referenced inside of the `createHandle` code. Reactive values include props, state, and all the variables and functions declared directly inside your component body. If your linter is [configured for React](/learn/editor-setup#linting), it will verify that every reactive value is correctly specified as a dependency. The list of dependencies must have a constant number of items and be written inline like `[dep1, dep2, dep3]`. React will compare each dependency with its previous value using the [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) comparison. If a re-render resulted in a change to some dependency, or if you omitted this argument, your `createHandle` function will re-execute, and the newly created handle will be assigned to the ref.

#### Returns[](#returns "Link for Returns ")

`useImperativeHandle` returns `undefined`.

***

## Usage[](#usage "Link for Usage ")

### Exposing a custom ref handle to the parent component[](#exposing-a-custom-ref-handle-to-the-parent-component "Link for Exposing a custom ref handle to the parent component ")

By default, components don’t expose their DOM nodes to parent components. For example, if you want the parent component of `MyInput` to [have access](/learn/manipulating-the-dom-with-refs) to the `<input>` DOM node, you have to opt in with [`forwardRef`:](/reference/react/forwardRef)

```
import { forwardRef } from 'react';



const MyInput = forwardRef(function MyInput(props, ref) {

  return <input {...props} ref={ref} />;

});
```

With the code above, [a ref to `MyInput` will receive the `<input>` DOM node.](/reference/react/forwardRef#exposing-a-dom-node-to-the-parent-component) However, you can expose a custom value instead. To customize the exposed handle, call `useImperativeHandle` at the top level of your component:

```
import { forwardRef, useImperativeHandle } from 'react';



const MyInput = forwardRef(function MyInput(props, ref) {

  useImperativeHandle(ref, () => {

    return {

      // ... your methods ...

    };

  }, []);



  return <input {...props} />;

});
```

Note that in the code above, the `ref` is no longer forwarded to the `<input>`.

For example, suppose you don’t want to expose the entire `<input>` DOM node, but you want to expose two of its methods: `focus` and `scrollIntoView`. To do this, keep the real browser DOM in a separate ref. Then use `useImperativeHandle` to expose a handle with only the methods that you want the parent component to call:

```
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} />;

});
```

Now, if the parent component gets a ref to `MyInput`, it will be able to call the `focus` and `scrollIntoView` methods on it. However, it will not have full access to the underlying `<input>` DOM node.

```
import { useRef } from 'react';
import MyInput from './MyInput.js';

export default function Form() {
  const ref = useRef(null);

  function handleClick() {
    ref.current.focus();
    // This won't work because the DOM node isn't exposed:
    // ref.current.style.opacity = 0.5;
  }

  return (
    <form>
      <MyInput placeholder="Enter your name" ref={ref} />
      <button type="button" onClick={handleClick}>
        Edit
      </button>
    </form>
  );
}
```

***

### Exposing your own imperative methods[](#exposing-your-own-imperative-methods "Link for Exposing your own imperative methods ")

The methods you expose via an imperative handle don’t have to match the DOM methods exactly. For example, this `Post` component exposes a `scrollAndFocusAddComment` method via an imperative handle. This lets the parent `Page` scroll the list of comments *and* focus the input field when you click the button:

```
import { useRef } from 'react';
import Post from './Post.js';

export default function Page() {
  const postRef = useRef(null);

  function handleClick() {
    postRef.current.scrollAndFocusAddComment();
  }

  return (
    <>
      <button onClick={handleClick}>
        Write a comment
      </button>
      <Post ref={postRef} />
    </>
  );
}
```

### Pitfall

**Do not overuse refs.** You should only use refs for *imperative* behaviors that you can’t express as props: for example, scrolling to a node, focusing a node, triggering an animation, selecting text, and so on.

**If you can express something as a prop, you should not use a ref.** For example, instead of exposing an imperative handle like `{ open, close }` from a `Modal` component, it is better to take `isOpen` as a prop like `<Modal isOpen={isOpen} />`. [Effects](/learn/synchronizing-with-effects) can help you expose imperative behaviors via props.

[PrevioususeId](/reference/react/useId)

[NextuseInsertionEffect](/reference/react/useInsertionEffect)

***

----
url: https://legacy.reactjs.org/docs/render-props.html
----

> These docs are old and won’t be updated. Go to [react.dev](https://react.dev/) for the new React docs.
>
> Render props are used in modern React, but aren’t very common.\
> For many cases, they have been replaced by [custom Hooks](https://react.dev/learn/reusing-logic-with-custom-hooks).

The term [“render prop”](https://cdb.reacttraining.com/use-a-render-prop-50de598f11ce) refers to a technique for sharing code between React components using a prop whose value is a function.

A component with a render prop takes a function that returns a React element and calls it instead of implementing its own render logic.

```
<DataProvider render={data => (
  <h1>Hello {data.target}</h1>
)}/>
```

Libraries that use render props include [React Router](https://reacttraining.com/react-router/web/api/Route/render-func), [Downshift](https://github.com/paypal/downshift) and [Formik](https://github.com/jaredpalmer/formik).

In this document, we’ll discuss why render props are useful, and how to write your own.

## [](#use-render-props-for-cross-cutting-concerns)Use Render Props for Cross-Cutting Concerns

Components are the primary unit of code reuse in React, but it’s not always obvious how to share the state or behavior that one component encapsulates to other components that need that same state.

For example, the following component tracks the mouse position in a web app:

```
class MouseTracker extends React.Component {
  constructor(props) {
    super(props);
    this.handleMouseMove = this.handleMouseMove.bind(this);
    this.state = { x: 0, y: 0 };
  }

  handleMouseMove(event) {
    this.setState({
      x: event.clientX,
      y: event.clientY
    });
  }

  render() {
    return (
      <div style={{ height: '100vh' }} onMouseMove={this.handleMouseMove}>
        <h1>Move the mouse around!</h1>
        <p>The current mouse position is ({this.state.x}, {this.state.y})</p>
      </div>
    );
  }
}
```

As the cursor moves around the screen, the component displays its (x, y) coordinates in a `<p>`.

Now the question is: How can we reuse this behavior in another component? In other words, if another component needs to know about the cursor position, can we encapsulate that behavior so that we can easily share it with that component?

Since components are the basic unit of code reuse in React, let’s try refactoring the code a bit to use a `<Mouse>` component that encapsulates the behavior we need to reuse elsewhere.

```
// The <Mouse> component encapsulates the behavior we need...
class Mouse extends React.Component {
  constructor(props) {
    super(props);
    this.handleMouseMove = this.handleMouseMove.bind(this);
    this.state = { x: 0, y: 0 };
  }

  handleMouseMove(event) {
    this.setState({
      x: event.clientX,
      y: event.clientY
    });
  }

  render() {
    return (
      <div style={{ height: '100vh' }} onMouseMove={this.handleMouseMove}>

        {/* ...but how do we render something other than a <p>? */}
        <p>The current mouse position is ({this.state.x}, {this.state.y})</p>
      </div>
    );
  }
}

class MouseTracker extends React.Component {
  render() {
    return (
      <>
        <h1>Move the mouse around!</h1>
        <Mouse />
      </>
    );
  }
}
```

Now the `<Mouse>` component encapsulates all behavior associated with listening for `mousemove` events and storing the (x, y) position of the cursor, but it’s not yet truly reusable.

For example, let’s say we have a `<Cat>` component that renders the image of a cat chasing the mouse around the screen. We might use a `<Cat mouse={{ x, y }}>` prop to tell the component the coordinates of the mouse so it knows where to position the image on the screen.

As a first pass, you might try rendering the `<Cat>` *inside `<Mouse>`’s `render` method*, like this:

```
class Cat extends React.Component {
  render() {
    const mouse = this.props.mouse;
    return (
      <img src="/cat.jpg" style={{ position: 'absolute', left: mouse.x, top: mouse.y }} />
    );
  }
}

class MouseWithCat extends React.Component {
  constructor(props) {
    super(props);
    this.handleMouseMove = this.handleMouseMove.bind(this);
    this.state = { x: 0, y: 0 };
  }

  handleMouseMove(event) {
    this.setState({
      x: event.clientX,
      y: event.clientY
    });
  }

  render() {
    return (
      <div style={{ height: '100vh' }} onMouseMove={this.handleMouseMove}>

        {/*
          We could just swap out the <p> for a <Cat> here ... but then
          we would need to create a separate <MouseWithSomethingElse>
          component every time we need to use it, so <MouseWithCat>
          isn't really reusable yet.
        */}
        <Cat mouse={this.state} />
      </div>
    );
  }
}

class MouseTracker extends React.Component {
  render() {
    return (
      <div>
        <h1>Move the mouse around!</h1>
        <MouseWithCat />
      </div>
    );
  }
}
```

This approach will work for our specific use case, but we haven’t achieved the objective of truly encapsulating the behavior in a reusable way. Now, every time we want the mouse position for a different use case, we have to create a new component (i.e. essentially another `<MouseWithCat>`) that renders something specifically for that use case.

Here’s where the render prop comes in: Instead of hard-coding a `<Cat>` inside a `<Mouse>` component, and effectively changing its rendered output, we can provide `<Mouse>` with a function prop that it uses to dynamically determine what to render–a render prop.

```
class Cat extends React.Component {
  render() {
    const mouse = this.props.mouse;
    return (
      <img src="/cat.jpg" style={{ position: 'absolute', left: mouse.x, top: mouse.y }} />
    );
  }
}

class Mouse extends React.Component {
  constructor(props) {
    super(props);
    this.handleMouseMove = this.handleMouseMove.bind(this);
    this.state = { x: 0, y: 0 };
  }

  handleMouseMove(event) {
    this.setState({
      x: event.clientX,
      y: event.clientY
    });
  }

  render() {
    return (
      <div style={{ height: '100vh' }} onMouseMove={this.handleMouseMove}>

        {/*
          Instead of providing a static representation of what <Mouse> renders,
          use the `render` prop to dynamically determine what to render.
        */}
        {this.props.render(this.state)}
      </div>
    );
  }
}

class MouseTracker extends React.Component {
  render() {
    return (
      <div>
        <h1>Move the mouse around!</h1>
        <Mouse render={mouse => (
          <Cat mouse={mouse} />
        )}/>
      </div>
    );
  }
}
```

Now, instead of effectively cloning the `<Mouse>` component and hard-coding something else in its `render` method to solve for a specific use case, we provide a `render` prop that `<Mouse>` can use to dynamically determine what it renders.

More concretely, **a render prop is a function prop that a component uses to know what to render.**

This technique makes the behavior that we need to share extremely portable. To get that behavior, render a `<Mouse>` with a `render` prop that tells it what to render with the current (x, y) of the cursor.

One interesting thing to note about render props is that you can implement most [higher-order components](/docs/higher-order-components.html) (HOC) using a regular component with a render prop. For example, if you would prefer to have a `withMouse` HOC instead of a `<Mouse>` component, you could easily create one using a regular `<Mouse>` with a render prop:

```
// If you really want a HOC for some reason, you can easily
// create one using a regular component with a render prop!
function withMouse(Component) {
  return class extends React.Component {
    render() {
      return (
        <Mouse render={mouse => (
          <Component {...this.props} mouse={mouse} />
        )}/>
      );
    }
  }
}
```

So using a render prop makes it possible to use either pattern.

## [](#using-props-other-than-render)Using Props Other Than `render`

It’s important to remember that just because the pattern is called “render props” you don’t *have to use a prop named `render` to use this pattern*. In fact, [*any* prop that is a function that a component uses to know what to render is technically a “render prop”](https://cdb.reacttraining.com/use-a-render-prop-50de598f11ce).

Although the examples above use `render`, we could just as easily use the `children` prop!

```
<Mouse children={mouse => (
  <p>The mouse position is {mouse.x}, {mouse.y}</p>
)}/>
```

And remember, the `children` prop doesn’t actually need to be named in the list of “attributes” in your JSX element. Instead, you can put it directly *inside* the element!

```
<Mouse>
  {mouse => (
    <p>The mouse position is {mouse.x}, {mouse.y}</p>
  )}
</Mouse>
```

You’ll see this technique used in the [react-motion](https://github.com/chenglou/react-motion) API.

Since this technique is a little unusual, you’ll probably want to explicitly state that `children` should be a function in your `propTypes` when designing an API like this.

```
Mouse.propTypes = {
  children: PropTypes.func.isRequired
};
```

## [](#caveats)Caveats

### [](#be-careful-when-using-render-props-with-reactpurecomponent)Be careful when using Render Props with React.PureComponent

Using a render prop can negate the advantage that comes from using [`React.PureComponent`](/docs/react-api.html#reactpurecomponent) if you create the function inside a `render` method. This is because the shallow prop comparison will always return `false` for new props, and each `render` in this case will generate a new value for the render prop.

For example, continuing with our `<Mouse>` component from above, if `Mouse` were to extend `React.PureComponent` instead of `React.Component`, our example would look like this:

```
class Mouse extends React.PureComponent {
  // Same implementation as above...
}

class MouseTracker extends React.Component {
  render() {
    return (
      <div>
        <h1>Move the mouse around!</h1>

        {/*
          This is bad! The value of the `render` prop will
          be different on each render.
        */}
        <Mouse render={mouse => (
          <Cat mouse={mouse} />
        )}/>
      </div>
    );
  }
}
```

In this example, each time `<MouseTracker>` renders, it generates a new function as the value of the `<Mouse render>` prop, thus negating the effect of `<Mouse>` extending `React.PureComponent` in the first place!

To get around this problem, you can sometimes define the prop as an instance method, like so:

```
class MouseTracker extends React.Component {
  // Defined as an instance method, `this.renderTheCat` always
  // refers to *same* function when we use it in render
  renderTheCat(mouse) {
    return <Cat mouse={mouse} />;
  }

  render() {
    return (
      <div>
        <h1>Move the mouse around!</h1>
        <Mouse render={this.renderTheCat} />
      </div>
    );
  }
}
```

In cases where you cannot define the prop statically (e.g. because you need to close over the component’s props and/or state) `<Mouse>` should extend `React.Component` instead.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/render-props.md)

----
url: https://legacy.reactjs.org/blog/2015/12/16/ismounted-antipattern.html
----

December 16, 2015 by [Jim Sproch](http://www.jimsproch.com)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

As we move closer to officially deprecating isMounted, it’s worth understanding why the function is an antipattern, and how to write code without the isMounted function.

The primary use case for `isMounted()` is to avoid calling `setState()` after a component has unmounted, because calling `setState()` after a component has unmounted will emit a warning. The “setState warning” exists to help you catch bugs, because calling `setState()` on an unmounted component is an indication that your app/component has somehow failed to clean up properly. Specifically, calling `setState()` in an unmounted component means that your app is still holding a reference to the component after the component has been unmounted - which often indicates a memory leak!

To avoid the error message, people often add lines like this:

```
if (this.isMounted()) { // This is bad.
  this.setState({...});
}
```

Checking `isMounted` before calling `setState()` does eliminate the warning, but it also defeats the purpose of the warning, since now you will never get the warning (even when you should!)

Other uses of `isMounted()` are similarly erroneous; using `isMounted()` is a code smell because the only reason you would check is because you think you might be holding a reference after the component has unmounted.

An easy migration strategy for anyone upgrading their code to avoid `isMounted()` is to track the mounted status yourself. Just set a `_isMounted` property to true in `componentDidMount` and set it to false in `componentWillUnmount`, and use this variable to check your component’s status.

An optimal solution would be to find places where `setState()` might be called after a component has unmounted, and fix them. Such situations most commonly occur due to callbacks, when a component is waiting for some data and gets unmounted before the data arrives. Ideally, any callbacks should be canceled in `componentWillUnmount`, prior to unmounting.

For instance, if you are using a Flux store in your component, you must unsubscribe in `componentWillUnmount`:

```
class MyComponent extends React.Component {
  componentDidMount() {
    mydatastore.subscribe(this);
  }
  render() {
    ...
  }
  componentWillUnmount() {
    mydatastore.unsubscribe(this);  }
}
```

If you use ES6 promises, you may need to wrap your promise in order to make it cancelable.

```
const cancelablePromise = makeCancelable(
  new Promise(r => component.setState({...}))
);

cancelablePromise
  .promise
  .then(() => console.log('resolved'))
  .catch((reason) => console.log('isCanceled', reason.isCanceled));

cancelablePromise.cancel(); // Cancel the promise
```

Where `makeCancelable` was originally [defined by @istarkov](https://github.com/facebook/react/issues/5465#issuecomment-157888325) as:

```
const makeCancelable = (promise) => {
  let hasCanceled_ = false;

  const wrappedPromise = new Promise((resolve, reject) => {
    promise.then(
      val => hasCanceled_ ? reject({isCanceled: true}) : resolve(val),
      error => hasCanceled_ ? reject({isCanceled: true}) : reject(error)
    );
  });

  return {
    promise: wrappedPromise,
    cancel() {
      hasCanceled_ = true;
    },
  };
};
```

As an added bonus for getting your code cleaned up early, getting rid of `isMounted()` makes it one step easier for you to upgrade to ES6 classes, where using `isMounted()` is already prohibited. Happy coding!

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2015-12-16-ismounted-antipattern.md)

----
url: https://legacy.reactjs.org/docs/legacy-event-pooling.html
----

> Note
>
> This page is only relevant for React 16 and earlier, and for React Native.
>
> React 17 on the web **does not** use event pooling.
>
> [Read more](/blog/2020/08/10/react-v17-rc.html#no-event-pooling) about this change in React 17.

The [`SyntheticEvent`](/docs/events.html) objects are pooled. This means that the `SyntheticEvent` object will be reused and all properties will be nullified after the event handler has been called. For example, this won’t work:

```
function handleChange(e) {
  // This won't work because the event object gets reused.
  setTimeout(() => {
    console.log(e.target.value); // Too late!
  }, 100);
}
```

If you need to access event object’s properties after the event handler has run, you need to call `e.persist()`:

```
function handleChange(e) {
  // Prevents React from resetting its properties:
  e.persist();

  setTimeout(() => {
    console.log(e.target.value); // Works
  }, 100);
}
```

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/legacy-event-pooling.md)

----
url: https://legacy.reactjs.org/docs/perf.html
----

> Note:
>
> As of React 16, `react-addons-perf` is not supported. Please use [your browser’s profiling tools](/docs/optimizing-performance.html#profiling-components-with-the-chrome-performance-tab) to get insight into which components re-render.

**Importing**

```
import Perf from 'react-addons-perf'; // ES6
var Perf = require('react-addons-perf'); // ES5 with npm
```

## [](#overview)Overview

React is usually quite fast out of the box. However, in situations where you need to squeeze every ounce of performance out of your app, it provides a [shouldComponentUpdate()](/docs/react-component.html#shouldcomponentupdate) method where you can add optimization hints to React’s diff algorithm.

In addition to giving you an overview of your app’s overall performance, `Perf` is a profiling tool that tells you exactly where you need to put these methods.

See these articles for an introduction to React performance tooling:

* [“How to Benchmark React Components”](https://medium.com/code-life/how-to-benchmark-react-components-the-quick-and-dirty-guide-f595baf1014c)
* [“Performance Engineering with React”](https://benchling.engineering/performance-engineering-with-react-e03013e53285)
* [“A Deep Dive into React Perf Debugging”](https://benchling.engineering/a-deep-dive-into-react-perf-debugging-fd2063f5a667)

### [](#development-vs-production-builds)Development vs. Production Builds

If you’re benchmarking or seeing performance problems in your React apps, make sure you’re testing with the [minified production build](/downloads.html). The development build includes extra warnings that are helpful when building your apps, but it is slower due to the extra bookkeeping it does.

However, the perf tools described on this page only work when using the development build of React. Therefore, the profiler only serves to indicate the *relatively* expensive parts of your app.

### [](#using-perf)Using Perf

The `Perf` object can be used with React in development mode only. You should not include this bundle when building your app for production.

#### [](#getting-measurements)Getting Measurements

* [`start()`](#start)
* [`stop()`](#stop)
* [`getLastMeasurements()`](#getlastmeasurements)

#### [](#printing-results)Printing Results

The following methods use the measurements returned by [`Perf.getLastMeasurements()`](#getlastmeasurements) to pretty-print the result.

* [`printInclusive()`](#printinclusive)
* [`printExclusive()`](#printexclusive)
* [`printWasted()`](#printwasted)
* [`printOperations()`](#printoperations)
* [`printDOM()`](#printdom)

***

## [](#reference)Reference

### [](#start)`start()`

### [](#stop)`stop()`

```
Perf.start()
// ...
Perf.stop()
```

Start/stop the measurement. The React operations in-between are recorded for analyses below. Operations that took an insignificant amount of time are ignored.

After stopping, you will need [`Perf.getLastMeasurements()`](#getlastmeasurements) to get the measurements.

***

### [](#getlastmeasurements)`getLastMeasurements()`

```
Perf.getLastMeasurements()
```

Get the opaque data structure describing measurements from the last start-stop session. You can save it and pass it to the other print methods in [`Perf`](#printing-results) to analyze past measurements.

> Note
>
> Don’t rely on the exact format of the return value because it may change in minor releases. We will update the documentation if the return value format becomes a supported part of the public API.

***

### [](#printinclusive)`printInclusive()`

```
Perf.printInclusive(measurements)
```

Prints the overall time taken. When no arguments are passed, `printInclusive` defaults to all the measurements from the last recording. This prints a nicely formatted table in the console, like so:

[](/static/de71a97b6c44f7bd3a589a3f1d620525/aec65/perf-inclusive.png)

***

### [](#printexclusive)`printExclusive()`

```
Perf.printExclusive(measurements)
```

“Exclusive” times don’t include the times taken to mount the components: processing props, calling `componentWillMount` and `componentDidMount`, etc.

[](/static/741b84218e9be133eca2e0ab98c36e85/aec65/perf-exclusive.png)

***

### [](#printwasted)`printWasted()`

```
Perf.printWasted(measurements)
```

**The most useful part of the profiler**.

“Wasted” time is spent on components that didn’t actually render anything, e.g. the render stayed the same, so the DOM wasn’t touched.

[](/static/a241eb09d0fd90eb56f48666ce9be586/aec65/perf-wasted.png)

***

### [](#printoperations)`printOperations()`

```
Perf.printOperations(measurements)
```

Prints the underlying DOM manipulations, e.g. “set innerHTML” and “remove”.

[](/static/57140a9924782c02dc7aac20042cf00d/aec65/perf-dom.png)

***

### [](#printdom)`printDOM()`

```
Perf.printDOM(measurements)
```

This method has been renamed to [`printOperations()`](#printoperations). Currently `printDOM()` still exists as an alias but it prints a deprecation warning and will eventually be removed.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/addons-perf.md)

----
url: https://react.dev/learn/describing-the-ui
----

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
function Profile() {
  return (
    <img
      src="https://react.dev/images/docs/scientists/MK3eW3As.jpg"
      alt="Katherine Johnson"
    />
  );
}

export default function Gallery() {
  return (
    <section>
      <h1>Amazing scientists</h1>
      <Profile />
      <Profile />
      <Profile />
    </section>
  );
}
```

## Ready to learn this topic?

Read **[Your First Component](/learn/your-first-component)** to learn how to declare and use React components.

[Read More](/learn/your-first-component)

***

## Importing and exporting components[](#importing-and-exporting-components "Link for Importing and exporting components ")

You can declare many components in one file, but large files can get difficult to navigate. To solve this, you can *export* a component into its own file, and then *import* that component from another file:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import Profile from './Profile.js';

export default function Gallery() {
  return (
    <section>
      <h1>Amazing scientists</h1>
      <Profile />
      <Profile />
      <Profile />
    </section>
  );
}
```

## Ready to learn this topic?

Read **[Importing and Exporting Components](/learn/importing-and-exporting-components)** to learn how to split components into their own files.

[Read More](/learn/importing-and-exporting-components)

***

## Writing markup with JSX[](#writing-markup-with-jsx "Link for Writing markup with JSX ")

Each React component is a JavaScript function that may contain some markup that React renders into the browser. React components use a syntax extension called JSX to represent that markup. JSX looks a lot like HTML, but it is a bit stricter and can display dynamic information.

If we paste existing HTML markup into a React component, it won’t always work:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
export default function TodoList() {
  return (
    // This doesn't quite work!
    <h1>Hedy Lamarr's Todos</h1>
    <img
      src="https://react.dev/images/docs/scientists/yXOvdOSs.jpg"
      alt="Hedy Lamarr"
      class="photo"
    >
    <ul>
      <li>Invent new traffic lights
      <li>Rehearse a movie scene
      <li>Improve spectrum technology
    </ul>
```

If you have existing HTML like this, you can fix it using a [converter](https://transform.tools/html-to-jsx):

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
export default function TodoList() {
  return (
    <>
      <h1>Hedy Lamarr's Todos</h1>
      <img
        src="https://react.dev/images/docs/scientists/yXOvdOSs.jpg"
        alt="Hedy Lamarr"
        className="photo"
      />
      <ul>
        <li>Invent new traffic lights</li>
        <li>Rehearse a movie scene</li>
        <li>Improve spectrum technology</li>
      </ul>
    </>
  );
}
```

## Ready to learn this topic?

Read **[Writing Markup with JSX](/learn/writing-markup-with-jsx)** to learn how to write valid JSX.

[Read More](/learn/writing-markup-with-jsx)

***

## JavaScript in JSX with curly braces[](#javascript-in-jsx-with-curly-braces "Link for JavaScript in JSX with curly braces ")

JSX lets you write HTML-like markup inside a JavaScript file, keeping rendering logic and content in the same place. Sometimes you will want to add a little JavaScript logic or reference a dynamic property inside that markup. In this situation, you can use curly braces in your JSX to “open a window” to JavaScript:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
const person = {
  name: 'Gregorio Y. Zara',
  theme: {
    backgroundColor: 'black',
    color: 'pink'
  }
};

export default function TodoList() {
  return (
    <div style={person.theme}>
      <h1>{person.name}'s Todos</h1>
      <img
        className="avatar"
        src="https://react.dev/images/docs/scientists/7vQD0fPs.jpg"
        alt="Gregorio Y. Zara"
      />
      <ul>
        <li>Improve the videophone</li>
        <li>Prepare aeronautics lectures</li>
        <li>Work on the alcohol-fuelled engine</li>
      </ul>
    </div>
  );
}
```

## Ready to learn this topic?

Read **[JavaScript in JSX with Curly Braces](/learn/javascript-in-jsx-with-curly-braces)** to learn how to access JavaScript data from JSX.

[Read More](/learn/javascript-in-jsx-with-curly-braces)

***

## Passing props to a component[](#passing-props-to-a-component "Link for Passing props to a component ")

React components use *props* to communicate with each other. Every parent component can pass some information to its child components by giving them props. Props might remind you of HTML attributes, but you can pass any JavaScript value through them, including objects, arrays, functions, and even JSX!

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { getImageUrl } from './utils.js'

export default function Profile() {
  return (
    <Card>
      <Avatar
        size={100}
        person={{
          name: 'Katsuko Saruhashi',
          imageId: 'YfeOqp2'
        }}
      />
    </Card>
  );
}

function Avatar({ person, size }) {
  return (
    <img
      className="avatar"
      src={getImageUrl(person)}
      alt={person.name}
      width={size}
      height={size}
    />
  );
}

function Card({ children }) {
  return (
    <div className="card">
      {children}
    </div>
  );
}
```

## Ready to learn this topic?

Read **[Passing Props to a Component](/learn/passing-props-to-a-component)** to learn how to pass and read props.

[Read More](/learn/passing-props-to-a-component)

***

## Conditional rendering[](#conditional-rendering "Link for Conditional rendering ")

Your components will often need to display different things depending on different conditions. In React, you can conditionally render JSX using JavaScript syntax like `if` statements, `&&`, and `? :` operators.

In this example, the JavaScript `&&` operator is used to conditionally render a checkmark:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
function Item({ name, isPacked }) {
  return (
    <li className="item">
      {name} {isPacked && '✅'}
    </li>
  );
}

export default function PackingList() {
  return (
    <section>
      <h1>Sally Ride's Packing List</h1>
      <ul>
        <Item
          isPacked={true}
          name="Space suit"
        />
        <Item
          isPacked={true}
          name="Helmet with a golden leaf"
        />
        <Item
          isPacked={false}
          name="Photo of Tam"
        />
      </ul>
    </section>
  );
}
```

## Ready to learn this topic?

Read **[Conditional Rendering](/learn/conditional-rendering)** to learn the different ways to render content conditionally.

[Read More](/learn/conditional-rendering)

***

## Rendering lists[](#rendering-lists "Link for Rendering lists ")

You will often want to display multiple similar components from a collection of data. You can use JavaScript’s `filter()` and `map()` with React to filter and transform your array of data into an array of components.

For each array item, you will need to specify a `key`. Usually, you will want to use an ID from the database as a `key`. Keys let React keep track of each item’s place in the list even if the list changes.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { people } from './data.js';
import { getImageUrl } from './utils.js';

export default function List() {
  const listItems = people.map(person =>
    <li key={person.id}>
      <img
        src={getImageUrl(person)}
        alt={person.name}
      />
      <p>
        <b>{person.name}:</b>
        {' ' + person.profession + ' '}
        known for {person.accomplishment}
      </p>
    </li>
  );
  return (
    <article>
      <h1>Scientists</h1>
      <ul>{listItems}</ul>
    </article>
  );
}
```

## Ready to learn this topic?

Read **[Rendering Lists](/learn/rendering-lists)** to learn how to render a list of components, and how to choose a key.

[Read More](/learn/rendering-lists)

***

## Keeping components pure[](#keeping-components-pure "Link for Keeping components pure ")

Some JavaScript functions are *pure.* A pure function:

* **Minds its own business.** It does not change any objects or variables that existed before it was called.
* **Same inputs, same output.** Given the same inputs, a pure function should always return the same result.

By strictly only writing your components as pure functions, you can avoid an entire class of baffling bugs and unpredictable behavior as your codebase grows. Here is an example of an impure component:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
let guest = 0;

function Cup() {
  // Bad: changing a preexisting variable!
  guest = guest + 1;
  return <h2>Tea cup for guest #{guest}</h2>;
}

export default function TeaSet() {
  return (
    <>
      <Cup />
      <Cup />
      <Cup />
    </>
  );
}
```

You can make this component pure by passing a prop instead of modifying a preexisting variable:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
function Cup({ guest }) {
  return <h2>Tea cup for guest #{guest}</h2>;
}

export default function TeaSet() {
  return (
    <>
      <Cup guest={1} />
      <Cup guest={2} />
      <Cup guest={3} />
    </>
  );
}
```

## Ready to learn this topic?

Read **[Keeping Components Pure](/learn/keeping-components-pure)** to learn how to write components as pure, predictable functions.

[Read More](/learn/keeping-components-pure)

***

***

## What’s next?[](#whats-next "Link for What’s next? ")

Head over to [Your First Component](/learn/your-first-component) to start reading this chapter page by page!

Or, if you’re already familiar with these topics, why not read about [Adding Interactivity](/learn/adding-interactivity)?

[NextYour First Component](/learn/your-first-component)

***

----
url: https://18.react.dev/reference/react-dom/server/renderToNodeStream
----

[API Reference](/reference/react)

[Server APIs](/reference/react-dom/server)

# renderToNodeStream[](#undefined "Link for this heading")

### Deprecated

This API will be removed in a future major version of React. Use [`renderToPipeableStream`](/reference/react-dom/server/renderToPipeableStream) instead.

`renderToNodeStream` renders a React tree to a [Node.js Readable Stream.](https://nodejs.org/api/stream.html#readable-streams)

```
const stream = renderToNodeStream(reactNode, options?)
```

* [Reference](#reference)
  * [`renderToNodeStream(reactNode, options?)`](#rendertonodestream)
* [Usage](#usage)
  * [Rendering a React tree as HTML to a Node.js Readable Stream](#rendering-a-react-tree-as-html-to-a-nodejs-readable-stream)

***

## Reference[](#reference "Link for Reference ")

### `renderToNodeStream(reactNode, options?)`[](#rendertonodestream "Link for this heading")

On the server, call `renderToNodeStream` to get a [Node.js Readable Stream](https://nodejs.org/api/stream.html#readable-streams) which you can pipe into the response.

```
import { renderToNodeStream } from 'react-dom/server';



const stream = renderToNodeStream(<App />);

stream.pipe(response);
```

On the client, call [`hydrateRoot`](/reference/react-dom/client/hydrateRoot) to make the server-generated HTML interactive.

[See more examples below.](#usage)

#### Parameters[](#parameters "Link for Parameters ")

* `reactNode`: A React node you want to render to HTML. For example, a JSX element like `<App />`.

* **optional** `options`: An object for server render.

  * **optional** `identifierPrefix`: A string prefix React uses for IDs generated by [`useId`.](/reference/react/useId) Useful to avoid conflicts when using multiple roots on the same page. Must be the same prefix as passed to [`hydrateRoot`.](/reference/react-dom/client/hydrateRoot#parameters)

#### Returns[](#returns "Link for Returns ")

A [Node.js Readable Stream](https://nodejs.org/api/stream.html#readable-streams) that outputs an HTML string.

#### Caveats[](#caveats "Link for Caveats ")

* This method will wait for all [Suspense boundaries](/reference/react/Suspense) to complete before returning any output.

* As of React 18, this method buffers all of its output, so it doesn’t actually provide any streaming benefits. This is why it’s recommended that you migrate to [`renderToPipeableStream`](/reference/react-dom/server/renderToPipeableStream) instead.

* The returned stream is a byte stream encoded in utf-8. If you need a stream in another encoding, take a look at a project like [iconv-lite](https://www.npmjs.com/package/iconv-lite), which provides transform streams for transcoding text.

***

## Usage[](#usage "Link for Usage ")

### Rendering a React tree as HTML to a Node.js Readable Stream[](#rendering-a-react-tree-as-html-to-a-nodejs-readable-stream "Link for Rendering a React tree as HTML to a Node.js Readable Stream ")

Call `renderToNodeStream` to get a [Node.js Readable Stream](https://nodejs.org/api/stream.html#readable-streams) which you can pipe to your server response:

```
import { renderToNodeStream } from 'react-dom/server';



// The route handler syntax depends on your backend framework

app.use('/', (request, response) => {

  const stream = renderToNodeStream(<App />);

  stream.pipe(response);

});
```

The stream will produce the initial non-interactive HTML output of your React components. On the client, you will need to call [`hydrateRoot`](/reference/react-dom/client/hydrateRoot) to *hydrate* that server-generated HTML and make it interactive.

[PreviousServer APIs](/reference/react-dom/server)

[NextrenderToPipeableStream](/reference/react-dom/server/renderToPipeableStream)

***

----
url: https://legacy.reactjs.org/blog/2015/07/03/react-v0.14-beta-1.html
----

July 03, 2015 by [Sophie Alpert](https://sophiebits.com/)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

This week, many people in the React community are at [ReactEurope](https://www.react-europe.org/) in the beautiful (and very warm) city of Paris, the second React conference that’s been held to date. At our last conference, we released the first beta of React 0.13, and we figured we’d do the same today with our first beta of React 0.14, giving you something to play with if you’re not at the conference or you’re looking for something to do on the way home.

With React 0.14, we’re continuing to let React mature and to make minor changes as the APIs continue to settle down. I’ll talk only about the two largest changes in this blog post; when we publish the final release we’ll be sure to update all of our documentation and include a full changelog.

You can install the new beta with `npm install react@0.14.0-beta1` and `npm install react-dom@0.14.0-beta1`. As mentioned in [Deprecating react-tools](/blog/2015/06/12/deprecating-jstransform-and-react-tools.html), we’re no longer updating the react-tools package so this release doesn’t include a new version of it. Please try the new version out and let us know what you think, and please do file issues on our GitHub repo if you run into any problems.

## [](#two-packages)Two Packages

As we look at packages like [react-native](https://github.com/facebook/react-native), [react-art](https://github.com/reactjs/react-art), [react-canvas](https://github.com/Flipboard/react-canvas), and [react-three](https://github.com/Izzimach/react-three), it’s become clear that the beauty and essence of React has nothing to do with browsers or the DOM.

We think the true foundations of React are simply ideas of components and elements: being able to describe what you want to render in a declarative way. These are the pieces shared by all of these different packages. The parts of React specific to certain rendering targets aren’t usually what we think of when we think of React. As one example, DOM diffing currently enables us to build React for the browser and make it fast enough to be useful, but if the DOM didn’t have a stateful, imperative API, we might not need diffing at all.

To make this more clear and to make it easier to build more environments that React can render to, we’re splitting the main `react` package into two: `react` and `react-dom`.

The `react` package contains `React.createElement`, `React.createClass` and `React.Component`, `React.PropTypes`, `React.Children`, and the other helpers related to elements and component classes. We think of these as the [*isomorphic*](http://nerds.airbnb.com/isomorphic-javascript-future-web-apps/) or [*universal*](https://medium.com/@mjackson/universal-javascript-4761051b7ae9) helpers that you need to build components.

The `react-dom` package contains `ReactDOM.render`, `ReactDOM.unmountComponentAtNode`, and `ReactDOM.findDOMNode`, and in `react-dom/server` we have server-side rendering support with `ReactDOMServer.renderToString` and `ReactDOMServer.renderToStaticMarkup`.

```
var React = require('react');
var ReactDOM = require('react-dom');

var MyComponent = React.createClass({
  render: function() {
    return <div>Hello World</div>;
  }
});

ReactDOM.render(<MyComponent />, node);
```

We anticipate that most components will need to depend only on the `react` package, which is lightweight and doesn’t include any of the actual rendering logic. To start, we expect people to render DOM-based components with our `react-dom` package, but there’s nothing stopping someone from diving deep on performance and writing a `awesome-faster-react-dom` package which can render *the exact same DOM-based components*. By decoupling the component definitions from the rendering, this becomes possible.

More importantly, this paves the way to writing components that can be shared between the web version of React and React Native. This isn’t yet easily possible, but we intend to make this easy in a future version so you can share React code between your website and native apps.

The addons have moved to separate packages as well: `react-addons-clone-with-props`, `react-addons-create-fragment`, `react-addons-css-transition-group`, `react-addons-linked-state-mixin`, `react-addons-pure-render-mixin`, `react-addons-shallow-compare`, `react-addons-transition-group`, and `react-addons-update`, plus `ReactDOM.unstable_batchedUpdates` in `react-dom`.

For now, please use the same version of `react` and `react-dom` in your apps to avoid versioning problems — but we plan to remove this requirement later. (This release includes the old methods in the `react` package with a deprecation warning, but they’ll be removed completely in 0.15.)

## [](#dom-node-refs)DOM node refs

The other big change we’re making in this release is exposing refs to DOM components as the DOM node itself. That means: we looked at what you can do with a `ref` to a DOM component and realized that the only useful thing you can do with it is call `this.refs.giraffe.getDOMNode()` to get the underlying DOM node. In this release, `this.refs.giraffe` *is* the actual DOM node.

Refs to custom component classes work exactly as before.

```
var Zoo = React.createClass({
  render: function() {
    return (
      <div>
        Giraffe's name: <input ref="giraffe" />
      </div>
    );
  },

  showName: function() {
    // Previously:
    // var input = this.refs.giraffe.getDOMNode();
    var input = this.refs.giraffe;

    alert(input.value);
  }
});
```

This change also applies to the return result of `ReactDOM.render` when passing a DOM node as the top component. As with refs, this change does not affect custom components (eg. `<MyFancyMenu>` or `<MyContextProvider>`), which remain unaffected by this change.

Along with this change, we’re also replacing `component.getDOMNode()` with `ReactDOM.findDOMNode(component)`. The `findDOMNode` method drills down to find which DOM node was rendered by a component, but it returns its argument when passed a DOM node so it’s safe to call on a DOM component too. We introduced this function quietly in the last release, but now we’re deprecating `.getDOMNode()` completely: it should be easy to change all existing calls in your code to be `ReactDOM.findDOMNode`. We also have an [automated codemod script](https://www.npmjs.com/package/react-codemod) to help you with this transition. Note that the `findDOMNode` calls are unnecessary when you already have a DOM component ref (as in the example above), so you can (and should) skip them in most cases going forward.

We hope you’re as excited about this release as we are! Let us know what you think of it.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2015-07-03-react-v0.14-beta-1.md)

----
url: https://legacy.reactjs.org/blog/2013/11/06/community-roundup-10.html
----

November 06, 2013 by [Vjeux](https://twitter.com/vjeux)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

This is the 10th round-up already and React has come quite far since it was open sourced. Almost all new web projects at Khan Academy, Facebook, and Instagram are being developed using React. React has been deployed in a variety of contexts: a Chrome extension, a Windows 8 application, mobile websites, and desktop websites supporting Internet Explorer 8! Language-wise, React is not only being used within JavaScript but also CoffeeScript and ClojureScript.

The best part is that no drastic changes have been required to support all those use cases. Most of the efforts were targeted at polishing edge cases, performance improvements, and documentation.

## [](#khan-academy---officially-moving-to-react)Khan Academy - Officially moving to React

[Joel Burget](http://joelburget.com/) announced at Hack Reactor that new front-end code at Khan Academy should be written in React!

> How did we get the rest of the team to adopt React? Using interns as an attack vector! Most full-time devs had already been working on their existing projects for a while and weren’t looking to try something new at the time, but our class of summer interns was just arriving. For whatever reason, a lot of them decided to try React for their projects. Then mentors became exposed through code reviews or otherwise touching the new code. In this way React knowledge diffused to almost the whole team over the summer.
>
> Since the first React checkin on June 5, we’ve somehow managed to accumulate 23500 lines of jsx (React-flavored js) code. Which is terrifying in a way - that’s a lot of code - but also really exciting that it was picked up so quickly.
>
> We held three meetings about how we should proceed with React. At the first two we decided to continue experimenting with React and deferred a final decision on whether to adopt it. At the third we adopted the policy that new code should be written in React.
>
> I’m excited that we were able to start nudging code quality forward. However, we still have a lot of work to do! One of the selling points of this transition is adopting a uniform frontend style. We’re trying to upgrade all the code from (really old) pure jQuery and (regular old) Backbone views / Handlebars to shiny React. At the moment all we’ve done is introduce more fragmentation. We won’t be gratuitously updating working code (if it ain’t broke, don’t fix it), but are seeking out parts of the codebase where we can shoot two birds with one stone by rewriting in React while fixing bugs or adding functionality.
>
> [Read the full article](http://joelburget.com/backbone-to-react/)

## [](#react-rethinking-best-practices)React: Rethinking best practices

[Pete Hunt](http://www.petehunt.net/)’s talk at JSConf EU 2013 is now available in video.

## [](#server-side-react-with-php)Server-side React with PHP

[Stoyan Stefanov](http://www.phpied.com/)’s series of articles on React has two new entries on how to execute React on the server to generate the initial page load.

> This post is an initial hack to have React components render server-side in PHP.
>
> * Problem: Build web UIs
> * Solution: React
> * Problem: UI built in JS is anti-SEO (assuming search engines are still noscript) and bad for perceived performance (blank page till JS arrives)
> * Solution: [React page](https://github.com/facebook/react-page) to render the first view
> * Problem: Can’t host node.js apps / I have tons of PHP code
> * Solution: Use PHP then!
>
> [**Read part 1 …**](http://www.phpied.com/server-side-react-with-php/)
>
> [**Read part 2 …**](http://www.phpied.com/server-side-react-with-php-part-2/)
>
> Rendered markup on the server:
>
> [](http://www.phpied.com/server-side-react-with-php-part-2/)

## [](#todomvc-benchmarks)TodoMVC Benchmarks

Webkit has a [TodoMVC Benchmark](https://github.com/WebKit/webkit/tree/master/PerformanceTests/DoYouEvenBench) that compares different frameworks. They recently included React and here are the results (average of 10 runs in Chrome 30):

* **AngularJS:** 4043ms
* **AngularJSPerf:** 3227ms
* **BackboneJS:** 1874ms
* **EmberJS:** 6822ms
* **jQuery:** 14628ms
* **React:** 2864ms
* **VanillaJS:** 5567ms

[Try it yourself!](http://www.petehunt.net/react/tastejs/benchmark.html)

Please don’t take those numbers too seriously, they only reflect one very specific use case and are testing code that wasn’t written with performance in mind.

Even though React scores as one of the fastest frameworks in the benchmark, the React code is simple and idiomatic. The only performance tweak used is the following function:

```
/**
 * This is a completely optional performance enhancement that you can implement
 * on any React component. If you were to delete this method the app would still
 * work correctly (and still be very performant!), we just use it as an example
 * of how little code it takes to get an order of magnitude performance improvement.
 */
shouldComponentUpdate: function (nextProps, nextState) {
  return (
    nextProps.todo.id !== this.props.todo.id ||
    nextProps.todo !== this.props.todo ||
    nextProps.editing !== this.props.editing ||
    nextState.editText !== this.state.editText
  );
},
```

By default, React “re-renders” all the components when anything changes. This is usually fast enough that you don’t need to care. However, you can provide a function that can tell whether there will be any change based on the previous and next states and props. If it is faster than re-rendering the component, then you get a performance improvement.

The fact that you can control when components are rendered is a very important characteristic of React as it gives you control over its performance. We are going to talk more about performance in the future, stay tuned.

## [](#guess-the-filter)Guess the filter

[Connor McSheffrey](http://conr.me) implemented a small game using React. The goal is to guess which filter has been used to create the Instagram photo.

[](http://guessthefilter.com/)

## [](#react-vs-fruitmachine)React vs FruitMachine

[Andrew Betts](http://trib.tv/), director of the [Financial Times Labs](http://labs.ft.com/), posted an article comparing [FruitMachine](https://github.com/ftlabs/fruitmachine) and React.

> Eerily similar, no? Maybe Facebook was inspired by Fruit Machine (after all, we got there first), but more likely, it just shows that this is a pretty decent way to solve the problem, and great minds think alike. We’re graduating to a third phase in the evolution of web best practice - from intermingling of markup, style and behaviour, through a phase in which those concerns became ever more separated and encapsulated, and finally to a model where we can do that separation at a component level. Developments like Web Components show the direction the web community is moving, and frameworks like React and Fruit Machine are in fact not a lot more than polyfills for that promised behaviour to come.
>
> [Read the full article…](http://labs.ft.com/2013/10/client-side-layout-engines-react-vs-fruitmachine/)

Even though we weren’t inspired by FruitMachine (React has been used in production since before FruitMachine was open sourced), it’s great to see similar technologies emerging and becoming popular.

## [](#react-brunch)React Brunch

[Matthew McCray](http://elucidata.net/) implemented [react-brunch](https://npmjs.org/package/react-brunch), a JSX compilation step for [Brunch](http://brunch.io/).

> Adds React support to brunch by automatically compiling `*.jsx` files.
>
> You can configure react-brunch to automatically insert a react header (`/** @jsx React.DOM */`) into all `*.jsx` files. Disabled by default.
>
> Install the plugin via npm with `npm install --save react-brunch`.
>
> [Read more…](https://npmjs.org/package/react-brunch)

## [](#random-tweet)Random Tweet

I’m going to start adding a tweet at the end of each round-up. We’ll start with this one:

> This weekend [#angular](https://twitter.com/search?q=%23angular\&src=hash) died for me. Meet new king [#reactjs](https://twitter.com/search?q=%23reactjs\&src=hash)
>
> — Eldar Djafarov ッ (@edjafarov) [November 3, 2013](https://twitter.com/edjafarov/statuses/397033796710961152)

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2013-11-06-community-roundup-10.md)

----
url: https://react.dev/learn/choosing-the-state-structure
----

```
const [x, setX] = useState(0);

const [y, setY] = useState(0);
```

Or this?

```
const [position, setPosition] = useState({ x: 0, y: 0 });
```

Technically, you can use either of these approaches. But **if some two state variables always change together, it might be a good idea to unify them into a single state variable.** Then you won’t forget to always keep them in sync, like in this example where moving the cursor updates both coordinates of the red dot:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function MovingDot() {
  const [position, setPosition] = useState({
    x: 0,
    y: 0
  });
  return (
    <div
      onPointerMove={e => {
        setPosition({
          x: e.clientX,
          y: e.clientY
        });
      }}
      style={{
        position: 'relative',
        width: '100vw',
        height: '100vh',
      }}>
      <div style={{
        position: 'absolute',
        backgroundColor: 'red',
        borderRadius: '50%',
        transform: `translate(${position.x}px, ${position.y}px)`,
        left: -10,
        top: -10,
        width: 20,
        height: 20,
      }} />
    </div>
  )
}
```

Another case where you’ll group data into an object or an array is when you don’t know how many pieces of state you’ll need. For example, it’s helpful when you have a form where the user can add custom fields.

### Pitfall

If your state variable is an object, remember that [you can’t update only one field in it](/learn/updating-objects-in-state) without explicitly copying the other fields. For example, you can’t do `setPosition({ x: 100 })` in the above example because it would not have the `y` property at all! Instead, if you wanted to set `x` alone, you would either do `setPosition({ ...position, x: 100 })`, or split them into two state variables and do `setX(100)`.

## Avoid contradictions in state[](#avoid-contradictions-in-state "Link for Avoid contradictions in state ")

Here is a hotel feedback form with `isSending` and `isSent` state variables:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function FeedbackForm() {
  const [text, setText] = useState('');
  const [isSending, setIsSending] = useState(false);
  const [isSent, setIsSent] = useState(false);

  async function handleSubmit(e) {
    e.preventDefault();
    setIsSending(true);
    await sendMessage(text);
    setIsSending(false);
    setIsSent(true);
  }

  if (isSent) {
    return <h1>Thanks for feedback!</h1>
  }

  return (
    <form onSubmit={handleSubmit}>
      <p>How was your stay at The Prancing Pony?</p>
      <textarea
        disabled={isSending}
        value={text}
        onChange={e => setText(e.target.value)}
      />
      <br />
      <button
        disabled={isSending}
        type="submit"
      >
        Send
      </button>
      {isSending && <p>Sending...</p>}
    </form>
  );
}

// Pretend to send a message.
function sendMessage(text) {
  return new Promise(resolve => {
    setTimeout(resolve, 2000);
  });
}
```

While this code works, it leaves the door open for “impossible” states. For example, if you forget to call `setIsSent` and `setIsSending` together, you may end up in a situation where both `isSending` and `isSent` are `true` at the same time. The more complex your component is, the harder it is to understand what happened.

**Since `isSending` and `isSent` should never be `true` at the same time, it is better to replace them with one `status` state variable that may take one of *three* valid states:** `'typing'` (initial), `'sending'`, and `'sent'`:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function FeedbackForm() {
  const [text, setText] = useState('');
  const [status, setStatus] = useState('typing');

  async function handleSubmit(e) {
    e.preventDefault();
    setStatus('sending');
    await sendMessage(text);
    setStatus('sent');
  }

  const isSending = status === 'sending';
  const isSent = status === 'sent';

  if (isSent) {
    return <h1>Thanks for feedback!</h1>
  }

  return (
    <form onSubmit={handleSubmit}>
      <p>How was your stay at The Prancing Pony?</p>
      <textarea
        disabled={isSending}
        value={text}
        onChange={e => setText(e.target.value)}
      />
      <br />
      <button
        disabled={isSending}
        type="submit"
      >
        Send
      </button>
      {isSending && <p>Sending...</p>}
    </form>
  );
}

// Pretend to send a message.
function sendMessage(text) {
  return new Promise(resolve => {
    setTimeout(resolve, 2000);
  });
}
```

You can still declare some constants for readability:

```
const isSending = status === 'sending';

const isSent = status === 'sent';
```

But they’re not state variables, so you don’t need to worry about them getting out of sync with each other.

## Avoid redundant state[](#avoid-redundant-state "Link for Avoid redundant state ")

If you can calculate some information from the component’s props or its existing state variables during rendering, you **should not** put that information into that component’s state.

For example, take this form. It works, but can you find any redundant state in it?

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function Form() {
  const [firstName, setFirstName] = useState('');
  const [lastName, setLastName] = useState('');
  const [fullName, setFullName] = useState('');

  function handleFirstNameChange(e) {
    setFirstName(e.target.value);
    setFullName(e.target.value + ' ' + lastName);
  }

  function handleLastNameChange(e) {
    setLastName(e.target.value);
    setFullName(firstName + ' ' + e.target.value);
  }

  return (
    <>
      <h2>Let’s check you in</h2>
      <label>
        First name:{' '}
        <input
          value={firstName}
          onChange={handleFirstNameChange}
        />
      </label>
      <label>
        Last name:{' '}
        <input
          value={lastName}
          onChange={handleLastNameChange}
        />
      </label>
      <p>
        Your ticket will be issued to: <b>{fullName}</b>
      </p>
    </>
  );
}
```

This form has three state variables: `firstName`, `lastName`, and `fullName`. However, `fullName` is redundant. **You can always calculate `fullName` from `firstName` and `lastName` during render, so remove it from state.**

This is how you can do it:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function Form() {
  const [firstName, setFirstName] = useState('');
  const [lastName, setLastName] = useState('');

  const fullName = firstName + ' ' + lastName;

  function handleFirstNameChange(e) {
    setFirstName(e.target.value);
  }

  function handleLastNameChange(e) {
    setLastName(e.target.value);
  }

  return (
    <>
      <h2>Let’s check you in</h2>
      <label>
        First name:{' '}
        <input
          value={firstName}
          onChange={handleFirstNameChange}
        />
      </label>
      <label>
        Last name:{' '}
        <input
          value={lastName}
          onChange={handleLastNameChange}
        />
      </label>
      <p>
        Your ticket will be issued to: <b>{fullName}</b>
      </p>
    </>
  );
}
```

Here, `fullName` is *not* a state variable. Instead, it’s calculated during render:

```
const fullName = firstName + ' ' + lastName;
```

As a result, the change handlers don’t need to do anything special to update it. When you call `setFirstName` or `setLastName`, you trigger a re-render, and then the next `fullName` will be calculated from the fresh data.

##### Deep Dive#### Don’t mirror props in state[](#don-t-mirror-props-in-state "Link for Don’t mirror props in state ")

A common example of redundant state is code like this:

```
function Message({ messageColor }) {

  const [color, setColor] = useState(messageColor);
```

Here, a `color` state variable is initialized to the `messageColor` prop. The problem is that **if the parent component passes a different value of `messageColor` later (for example, `'red'` instead of `'blue'`), the `color` *state variable* would not be updated!** The state is only initialized during the first render.

This is why “mirroring” some prop in a state variable can lead to confusion. Instead, use the `messageColor` prop directly in your code. If you want to give it a shorter name, use a constant:

```
function Message({ messageColor }) {

  const color = messageColor;
```

This way it won’t get out of sync with the prop passed from the parent component.

”Mirroring” props into state only makes sense when you *want* to ignore all updates for a specific prop. By convention, start the prop name with `initial` or `default` to clarify that its new values are ignored:

```
function Message({ initialColor }) {

  // The `color` state variable holds the *first* value of `initialColor`.

  // Further changes to the `initialColor` prop are ignored.

  const [color, setColor] = useState(initialColor);
```

## Avoid duplication in state[](#avoid-duplication-in-state "Link for Avoid duplication in state ")

This menu list component lets you choose a single travel snack out of several:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

const initialItems = [
  { title: 'pretzels', id: 0 },
  { title: 'crispy seaweed', id: 1 },
  { title: 'granola bar', id: 2 },
];

export default function Menu() {
  const [items, setItems] = useState(initialItems);
  const [selectedItem, setSelectedItem] = useState(
    items[0]
  );

  return (
    <>
      <h2>What's your travel snack?</h2>
      <ul>
        {items.map(item => (
          <li key={item.id}>
            {item.title}
            {' '}
            <button onClick={() => {
              setSelectedItem(item);
            }}>Choose</button>
          </li>
        ))}
      </ul>
      <p>You picked {selectedItem.title}.</p>
    </>
  );
}
```

Currently, it stores the selected item as an object in the `selectedItem` state variable. However, this is not great: **the contents of the `selectedItem` is the same object as one of the items inside the `items` list.** This means that the information about the item itself is duplicated in two places.

Why is this a problem? Let’s make each item editable:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

const initialItems = [
  { title: 'pretzels', id: 0 },
  { title: 'crispy seaweed', id: 1 },
  { title: 'granola bar', id: 2 },
];

export default function Menu() {
  const [items, setItems] = useState(initialItems);
  const [selectedItem, setSelectedItem] = useState(
    items[0]
  );

  function handleItemChange(id, e) {
    setItems(items.map(item => {
      if (item.id === id) {
        return {
          ...item,
          title: e.target.value,
        };
      } else {
        return item;
      }
    }));
  }

  return (
    <>
      <h2>What's your travel snack?</h2>
      <ul>
        {items.map((item, index) => (
          <li key={item.id}>
            <input
              value={item.title}
              onChange={e => {
                handleItemChange(item.id, e)
              }}
            />
            {' '}
            <button onClick={() => {
              setSelectedItem(item);
            }}>Choose</button>
          </li>
        ))}
      </ul>
      <p>You picked {selectedItem.title}.</p>
    </>
  );
}
```

Notice how if you first click “Choose” on an item and *then* edit it, **the input updates but the label at the bottom does not reflect the edits.** This is because you have duplicated state, and you forgot to update `selectedItem`.

Although you could update `selectedItem` too, an easier fix is to remove duplication. In this example, instead of a `selectedItem` object (which creates a duplication with objects inside `items`), you hold the `selectedId` in state, and *then* get the `selectedItem` by searching the `items` array for an item with that ID:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

const initialItems = [
  { title: 'pretzels', id: 0 },
  { title: 'crispy seaweed', id: 1 },
  { title: 'granola bar', id: 2 },
];

export default function Menu() {
  const [items, setItems] = useState(initialItems);
  const [selectedId, setSelectedId] = useState(0);

  const selectedItem = items.find(item =>
    item.id === selectedId
  );

  function handleItemChange(id, e) {
    setItems(items.map(item => {
      if (item.id === id) {
        return {
          ...item,
          title: e.target.value,
        };
      } else {
        return item;
      }
    }));
  }

  return (
    <>
      <h2>What's your travel snack?</h2>
      <ul>
        {items.map((item, index) => (
          <li key={item.id}>
            <input
              value={item.title}
              onChange={e => {
                handleItemChange(item.id, e)
              }}
            />
            {' '}
            <button onClick={() => {
              setSelectedId(item.id);
            }}>Choose</button>
          </li>
        ))}
      </ul>
      <p>You picked {selectedItem.title}.</p>
    </>
  );
}
```

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
export const initialTravelPlan = {
  id: 0,
  title: '(Root)',
  childPlaces: [{
    id: 1,
    title: 'Earth',
    childPlaces: [{
      id: 2,
      title: 'Africa',
      childPlaces: [{
        id: 3,
        title: 'Botswana',
        childPlaces: []
      }, {
        id: 4,
        title: 'Egypt',
        childPlaces: []
      }, {
        id: 5,
        title: 'Kenya',
        childPlaces: []
      }, {
        id: 6,
        title: 'Madagascar',
        childPlaces: []
      }, {
        id: 7,
        title: 'Morocco',
        childPlaces: []
      }, {
        id: 8,
        title: 'Nigeria',
        childPlaces: []
      }, {
        id: 9,
        title: 'South Africa',
        childPlaces: []
      }]
    }, {
      id: 10,
      title: 'Americas',
      childPlaces: [{
        id: 11,
        title: 'Argentina',
        childPlaces: []
      }, {
        id: 12,
        title: 'Brazil',
        childPlaces: []
      }, {
        id: 13,
        title: 'Barbados',
        childPlaces: []
      }, {
        id: 14,
        title: 'Canada',
        childPlaces: []
      }, {
        id: 15,
        title: 'Jamaica',
        childPlaces: []
      }, {
        id: 16,
        title: 'Mexico',
        childPlaces: []
      }, {
        id: 17,
        title: 'Trinidad and Tobago',
        childPlaces: []
      }, {
        id: 18,
        title: 'Venezuela',
        childPlaces: []
      }]
    }, {
      id: 19,
      title: 'Asia',
      childPlaces: [{
        id: 20,
        title: 'China',
        childPlaces: []
      }, {
        id: 21,
        title: 'India',
        childPlaces: []
      }, {
        id: 22,
        title: 'Singapore',
        childPlaces: []
      }, {
        id: 23,
        title: 'South Korea',
        childPlaces: []
      }, {
        id: 24,
        title: 'Thailand',
        childPlaces: []
      }, {
        id: 25,
        title: 'Vietnam',
        childPlaces: []
      }]
    }, {
      id: 26,
      title: 'Europe',
      childPlaces: [{
        id: 27,
        title: 'Croatia',
        childPlaces: [],
      }, {
        id: 28,
        title: 'France',
        childPlaces: [],
      }, {
        id: 29,
        title: 'Germany',
        childPlaces: [],
      }, {
        id: 30,
        title: 'Italy',
        childPlaces: [],
      }, {
        id: 31,
        title: 'Portugal',
        childPlaces: [],
      }, {
        id: 32,
        title: 'Spain',
        childPlaces: [],
      }, {
        id: 33,
        title: 'Turkey',
        childPlaces: [],
      }]
    }, {
      id: 34,
      title: 'Oceania',
      childPlaces: [{
        id: 35,
        title: 'Australia',
        childPlaces: [],
      }, {
        id: 36,
        title: 'Bora Bora (French Polynesia)',
        childPlaces: [],
      }, {
        id: 37,
        title: 'Easter Island (Chile)',
        childPlaces: [],
      }, {
        id: 38,
        title: 'Fiji',
        childPlaces: [],
      }, {
        id: 39,
        title: 'Hawaii (the USA)',
        childPlaces: [],
      }, {
        id: 40,
        title: 'New Zealand',
        childPlaces: [],
      }, {
        id: 41,
        title: 'Vanuatu',
        childPlaces: [],
      }]
    }]
  }, {
    id: 42,
    title: 'Moon',
    childPlaces: [{
      id: 43,
      title: 'Rheita',
      childPlaces: []
    }, {
      id: 44,
      title: 'Piccolomini',
      childPlaces: []
    }, {
      id: 45,
      title: 'Tycho',
      childPlaces: []
    }]
  }, {
    id: 46,
    title: 'Mars',
    childPlaces: [{
      id: 47,
      title: 'Corn Town',
      childPlaces: []
    }, {
      id: 48,
      title: 'Green Hill',
      childPlaces: []
    }]
  }]
};
```

Now let’s say you want to add a button to delete a place you’ve already visited. How would you go about it? [Updating nested state](/learn/updating-objects-in-state#updating-a-nested-object) involves making copies of objects all the way up from the part that changed. Deleting a deeply nested place would involve copying its entire parent place chain. Such code can be very verbose.

**If the state is too nested to update easily, consider making it “flat”.** Here is one way you can restructure this data. Instead of a tree-like structure where each `place` has an array of *its child places*, you can have each place hold an array of *its child place IDs*. Then store a mapping from each place ID to the corresponding place.

This data restructuring might remind you of seeing a database table:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
export const initialTravelPlan = {
  0: {
    id: 0,
    title: '(Root)',
    childIds: [1, 42, 46],
  },
  1: {
    id: 1,
    title: 'Earth',
    childIds: [2, 10, 19, 26, 34]
  },
  2: {
    id: 2,
    title: 'Africa',
    childIds: [3, 4, 5, 6 , 7, 8, 9]
  },
  3: {
    id: 3,
    title: 'Botswana',
    childIds: []
  },
  4: {
    id: 4,
    title: 'Egypt',
    childIds: []
  },
  5: {
    id: 5,
    title: 'Kenya',
    childIds: []
  },
  6: {
    id: 6,
    title: 'Madagascar',
    childIds: []
  },
  7: {
    id: 7,
    title: 'Morocco',
    childIds: []
  },
  8: {
    id: 8,
    title: 'Nigeria',
    childIds: []
  },
  9: {
    id: 9,
    title: 'South Africa',
    childIds: []
  },
  10: {
    id: 10,
    title: 'Americas',
    childIds: [11, 12, 13, 14, 15, 16, 17, 18],
  },
  11: {
    id: 11,
    title: 'Argentina',
    childIds: []
  },
  12: {
    id: 12,
    title: 'Brazil',
    childIds: []
  },
  13: {
    id: 13,
    title: 'Barbados',
    childIds: []
  },
  14: {
    id: 14,
    title: 'Canada',
    childIds: []
  },
  15: {
    id: 15,
    title: 'Jamaica',
    childIds: []
  },
  16: {
    id: 16,
    title: 'Mexico',
    childIds: []
  },
  17: {
    id: 17,
    title: 'Trinidad and Tobago',
    childIds: []
  },
  18: {
    id: 18,
    title: 'Venezuela',
    childIds: []
  },
  19: {
    id: 19,
    title: 'Asia',
    childIds: [20, 21, 22, 23, 24, 25],
  },
  20: {
    id: 20,
    title: 'China',
    childIds: []
  },
  21: {
    id: 21,
    title: 'India',
    childIds: []
  },
  22: {
    id: 22,
    title: 'Singapore',
    childIds: []
  },
  23: {
    id: 23,
    title: 'South Korea',
    childIds: []
  },
  24: {
    id: 24,
    title: 'Thailand',
    childIds: []
  },
  25: {
    id: 25,
    title: 'Vietnam',
    childIds: []
  },
  26: {
    id: 26,
    title: 'Europe',
    childIds: [27, 28, 29, 30, 31, 32, 33],
  },
  27: {
    id: 27,
    title: 'Croatia',
    childIds: []
  },
  28: {
    id: 28,
    title: 'France',
    childIds: []
  },
  29: {
    id: 29,
    title: 'Germany',
    childIds: []
  },
  30: {
    id: 30,
    title: 'Italy',
    childIds: []
  },
  31: {
    id: 31,
    title: 'Portugal',
    childIds: []
  },
  32: {
    id: 32,
    title: 'Spain',
    childIds: []
  },
  33: {
    id: 33,
    title: 'Turkey',
    childIds: []
  },
  34: {
    id: 34,
    title: 'Oceania',
    childIds: [35, 36, 37, 38, 39, 40, 41],
  },
  35: {
    id: 35,
    title: 'Australia',
    childIds: []
  },
  36: {
    id: 36,
    title: 'Bora Bora (French Polynesia)',
    childIds: []
  },
  37: {
    id: 37,
    title: 'Easter Island (Chile)',
    childIds: []
  },
  38: {
    id: 38,
    title: 'Fiji',
    childIds: []
  },
  39: {
    id: 40,
    title: 'Hawaii (the USA)',
    childIds: []
  },
  40: {
    id: 40,
    title: 'New Zealand',
    childIds: []
  },
  41: {
    id: 41,
    title: 'Vanuatu',
    childIds: []
  },
  42: {
    id: 42,
    title: 'Moon',
    childIds: [43, 44, 45]
  },
  43: {
    id: 43,
    title: 'Rheita',
    childIds: []
  },
  44: {
    id: 44,
    title: 'Piccolomini',
    childIds: []
  },
  45: {
    id: 45,
    title: 'Tycho',
    childIds: []
  },
  46: {
    id: 46,
    title: 'Mars',
    childIds: [47, 48]
  },
  47: {
    id: 47,
    title: 'Corn Town',
    childIds: []
  },
  48: {
    id: 48,
    title: 'Green Hill',
    childIds: []
  }
};
```

**Now that the state is “flat” (also known as “normalized”), updating nested items becomes easier.**

In order to remove a place now, you only need to update two levels of state:

* The updated version of its *parent* place should exclude the removed ID from its `childIds` array.
* The updated version of the root “table” object should include the updated version of the parent place.

Here is an example of how you could go about it:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';
import { initialTravelPlan } from './places.js';

export default function TravelPlan() {
  const [plan, setPlan] = useState(initialTravelPlan);

  function handleComplete(parentId, childId) {
    const parent = plan[parentId];
    // Create a new version of the parent place
    // that doesn't include this child ID.
    const nextParent = {
      ...parent,
      childIds: parent.childIds
        .filter(id => id !== childId)
    };
    // Update the root state object...
    setPlan({
      ...plan,
      // ...so that it has the updated parent.
      [parentId]: nextParent
    });
  }

  const root = plan[0];
  const planetIds = root.childIds;
  return (
    <>
      <h2>Places to visit</h2>
      <ol>
        {planetIds.map(id => (
          <PlaceTree
            key={id}
            id={id}
            parentId={0}
            placesById={plan}
            onComplete={handleComplete}
          />
        ))}
      </ol>
    </>
  );
}

function PlaceTree({ id, parentId, placesById, onComplete }) {
  const place = placesById[id];
  const childIds = place.childIds;
  return (
    <li>
      {place.title}
      <button onClick={() => {
        onComplete(parentId, id);
      }}>
        Complete
      </button>
      {childIds.length > 0 &&
        <ol>
          {childIds.map(childId => (
            <PlaceTree
              key={childId}
              id={childId}
              parentId={id}
              placesById={placesById}
              onComplete={onComplete}
            />
          ))}
        </ol>
      }
    </li>
  );
}
```

You can nest state as much as you like, but making it “flat” can solve numerous problems. It makes state easier to update, and it helps ensure you don’t have duplication in different parts of a nested object.

##### Deep Dive#### Improving memory usage[](#improving-memory-usage "Link for Improving memory usage ")

Ideally, you would also remove the deleted items (and their children!) from the “table” object to improve memory usage. This version does that. It also [uses Immer](/learn/updating-objects-in-state#write-concise-update-logic-with-immer) to make the update logic more concise.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
{
  "dependencies": {
    "immer": "1.7.3",
    "react": "latest",
    "react-dom": "latest",
    "react-scripts": "latest",
    "use-immer": "0.5.1"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject"
  },
  "devDependencies": {}
}
```

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function Clock(props) {
  const [color, setColor] = useState(props.color);
  return (
    <h1 style={{ color: color }}>
      {props.time}
    </h1>
  );
}
```

[PreviousReacting to Input with State](/learn/reacting-to-input-with-state)

[NextSharing State Between Components](/learn/sharing-state-between-components)

***

----
url: https://react.dev/reference/react/useEffect
----

[API Reference](/reference/react)

[Hooks](/reference/react/hooks)

# useEffect[](#undefined "Link for this heading")

`useEffect` is a React Hook that lets you [synchronize a component with an external system.](/learn/synchronizing-with-effects)

```
useEffect(setup, dependencies?)
```

***

## Reference[](#reference "Link for Reference ")

### `useEffect(setup, dependencies?)`[](#useeffect "Link for this heading")

Call `useEffect` at the top level of your component to declare an Effect:

```
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]);

  // ...

}
```

[See more examples below.](#usage)

#### Parameters[](#parameters "Link for Parameters ")

* `setup`: The function with your Effect’s logic. Your setup function may also optionally return a *cleanup* function. When your [component commits](/learn/render-and-commit#step-3-react-commits-changes-to-the-dom), React will run your setup function. After every commit with changed dependencies, React will first run the cleanup function (if you provided it) with the old values, and then run your setup function with the new values. After your component is removed from the DOM, React will run your cleanup function.

* **optional** `dependencies`: The list of all reactive values referenced inside of the `setup` code. Reactive values include props, state, and all the variables and functions declared directly inside your component body. If your linter is [configured for React](/learn/editor-setup#linting), it will verify that every reactive value is correctly specified as a dependency. The list of dependencies must have a constant number of items and be written inline like `[dep1, dep2, dep3]`. React will compare each dependency with its previous value using the [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) comparison. If you omit this argument, your Effect will re-run after every commit of the component. [See the difference between passing an array of dependencies, an empty array, and no dependencies at all.](#examples-dependencies)

***

## Usage[](#usage "Link for Usage ")

### Connecting to an external system[](#connecting-to-an-external-system "Link for Connecting to an external system ")

Some components need to stay connected to the network, some browser API, or a third-party library, while they are displayed on the page. These systems aren’t controlled by React, so they are called *external.*

To [connect your component to some external system,](/learn/synchronizing-with-effects) call `useEffect` at the top level of your component:

```
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]);

  // ...

}
```

You need to pass two arguments to `useEffect`:

1. A *setup function* with setup code that connects to that system.
   * It should return a *cleanup function* with cleanup code that disconnects from that system.
2. A list of dependencies including every value from your component used inside of those functions.

**React calls your setup and cleanup functions whenever it’s necessary, which may happen multiple times:**

1. Your setup code runs when your component is added to the page *(mounts)*.

2. After every commit of your component where the dependencies have changed:

   * First, your cleanup code runs with the old props and state.
   * Then, your setup code runs with the new props and state.

3. Your cleanup code runs one final time after your component is removed from the page *(unmounts).*

**Let’s illustrate this sequence for the example above.**

When the `ChatRoom` component above gets added to the page, it will connect to the chat room with the initial `serverUrl` and `roomId`. If either `serverUrl` or `roomId` change as a result of a commit (say, if the user picks a different chat room in a dropdown), your Effect will *disconnect from the previous room, and connect to the next one.* When the `ChatRoom` component is removed from the page, your Effect will disconnect one last time.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
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();
    };
  }, [roomId, serverUrl]);

  return (
    <>
      <label>
        Server URL:{' '}
        <input
          value={serverUrl}
          onChange={e => setServerUrl(e.target.value)}
        />
      </label>
      <h1>Welcome to the {roomId} room!</h1>
    </>
  );
}

export default function App() {
  const [roomId, setRoomId] = useState('general');
  const [show, setShow] = useState(false);
  return (
    <>
      <label>
        Choose the chat room:{' '}
        <select
          value={roomId}
          onChange={e => setRoomId(e.target.value)}
        >
          <option value="general">general</option>
          <option value="travel">travel</option>
          <option value="music">music</option>
        </select>
      </label>
      <button onClick={() => setShow(!show)}>
        {show ? 'Close chat' : 'Open chat'}
      </button>
      {show && <hr />}
      {show && <ChatRoom roomId={roomId} />}
    </>
  );
}
```

***

### Wrapping Effects in custom Hooks[](#wrapping-effects-in-custom-hooks "Link for Wrapping Effects in custom Hooks ")

Effects are an [“escape hatch”:](/learn/escape-hatches) you use them when you need to “step outside React” and when there is no better built-in solution for your use case. If you find yourself often needing to manually write Effects, it’s usually a sign that you need to extract some [custom Hooks](/learn/reusing-logic-with-custom-hooks) for common behaviors your components rely on.

For example, this `useChatRoom` custom Hook “hides” the logic of your Effect behind a more declarative API:

```
function useChatRoom({ serverUrl, roomId }) {

  useEffect(() => {

    const options = {

      serverUrl: serverUrl,

      roomId: roomId

    };

    const connection = createConnection(options);

    connection.connect();

    return () => connection.disconnect();

  }, [roomId, serverUrl]);

}
```

Then you can use it from any component like this:

```
function ChatRoom({ roomId }) {

  const [serverUrl, setServerUrl] = useState('https://localhost:1234');



  useChatRoom({

    roomId: roomId,

    serverUrl: serverUrl

  });

  // ...
```

There are also many excellent custom Hooks for every purpose available in the React ecosystem.

[Learn more about wrapping Effects in custom Hooks.](/learn/reusing-logic-with-custom-hooks)

#### Examples of wrapping Effects in custom Hooks[](#examples-custom-hooks "Link for Examples of wrapping Effects in custom Hooks")

#### Example 1 of 3:Custom `useChatRoom` Hook[](#custom-usechatroom-hook "Link for this heading")

This example is identical to one of the [earlier examples,](#examples-connecting) but the logic is extracted to a custom Hook.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';
import { useChatRoom } from './useChatRoom.js';

function ChatRoom({ roomId }) {
  const [serverUrl, setServerUrl] = useState('https://localhost:1234');

  useChatRoom({
    roomId: roomId,
    serverUrl: serverUrl
  });

  return (
    <>
      <label>
        Server URL:{' '}
        <input
          value={serverUrl}
          onChange={e => setServerUrl(e.target.value)}
        />
      </label>
      <h1>Welcome to the {roomId} room!</h1>
    </>
  );
}

export default function App() {
  const [roomId, setRoomId] = useState('general');
  const [show, setShow] = useState(false);
  return (
    <>
      <label>
        Choose the chat room:{' '}
        <select
          value={roomId}
          onChange={e => setRoomId(e.target.value)}
        >
          <option value="general">general</option>
          <option value="travel">travel</option>
          <option value="music">music</option>
        </select>
      </label>
      <button onClick={() => setShow(!show)}>
        {show ? 'Close chat' : 'Open chat'}
      </button>
      {show && <hr />}
      {show && <ChatRoom roomId={roomId} />}
    </>
  );
}
```

***

### Controlling a non-React widget[](#controlling-a-non-react-widget "Link for Controlling a non-React widget ")

Sometimes, you want to keep an external system synchronized to some prop or state of your component.

For example, if you have a third-party map widget or a video player component written without React, you can use an Effect to call methods on it that make its state match the current state of your React component. This Effect creates an instance of a `MapWidget` class defined in `map-widget.js`. When you change the `zoomLevel` prop of the `Map` component, the Effect calls the `setZoom()` on the class instance to keep it synchronized:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useRef, useEffect } from 'react';
import { MapWidget } from './map-widget.js';

export default function Map({ zoomLevel }) {
  const containerRef = useRef(null);
  const mapRef = useRef(null);

  useEffect(() => {
    if (mapRef.current === null) {
      mapRef.current = new MapWidget(containerRef.current);
    }

    const map = mapRef.current;
    map.setZoom(zoomLevel);
  }, [zoomLevel]);

  return (
    <div
      style={{ width: 200, height: 200 }}
      ref={containerRef}
    />
  );
}
```

In this example, a cleanup function is not needed because the `MapWidget` class manages only the DOM node that was passed to it. After the `Map` React component is removed from the tree, both the DOM node and the `MapWidget` class instance will be automatically garbage-collected by the browser JavaScript engine.

***

### Fetching data with Effects[](#fetching-data-with-effects "Link for Fetching data with Effects ")

You can use an Effect to fetch data for your component. Note that [if you use a framework,](/learn/creating-a-react-app#full-stack-frameworks) using your framework’s data fetching mechanism will be a lot more efficient than writing Effects manually.

If you want to fetch data from an Effect manually, your code might look like this:

```
import { useState, useEffect } from 'react';

import { fetchBio } from './api.js';



export default function Page() {

  const [person, setPerson] = useState('Alice');

  const [bio, setBio] = useState(null);



  useEffect(() => {

    let ignore = false;

    setBio(null);

    fetchBio(person).then(result => {

      if (!ignore) {

        setBio(result);

      }

    });

    return () => {

      ignore = true;

    };

  }, [person]);



  // ...
```

Note the `ignore` variable which is initialized to `false`, and is set to `true` during cleanup. This ensures [your code doesn’t suffer from “race conditions”:](https://maxrozen.com/race-conditions-fetching-data-react-with-useeffect) network responses may arrive in a different order than you sent them.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useEffect } from 'react';
import { fetchBio } from './api.js';

export default function Page() {
  const [person, setPerson] = useState('Alice');
  const [bio, setBio] = useState(null);
  useEffect(() => {
    let ignore = false;
    setBio(null);
    fetchBio(person).then(result => {
      if (!ignore) {
        setBio(result);
      }
    });
    return () => {
      ignore = true;
    }
  }, [person]);

  return (
    <>
      <select value={person} onChange={e => {
        setPerson(e.target.value);
      }}>
        <option value="Alice">Alice</option>
        <option value="Bob">Bob</option>
        <option value="Taylor">Taylor</option>
      </select>
      <hr />
      <p><i>{bio ?? 'Loading...'}</i></p>
    </>
  );
}
```

You can also rewrite using the [`async` / `await`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function) syntax, but you still need to provide a cleanup function:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useEffect } from 'react';
import { fetchBio } from './api.js';

export default function Page() {
  const [person, setPerson] = useState('Alice');
  const [bio, setBio] = useState(null);
  useEffect(() => {
    async function startFetching() {
      setBio(null);
      const result = await fetchBio(person);
      if (!ignore) {
        setBio(result);
      }
    }

    let ignore = false;
    startFetching();
    return () => {
      ignore = true;
    }
  }, [person]);

  return (
    <>
      <select value={person} onChange={e => {
        setPerson(e.target.value);
      }}>
        <option value="Alice">Alice</option>
        <option value="Bob">Bob</option>
        <option value="Taylor">Taylor</option>
      </select>
      <hr />
      <p><i>{bio ?? 'Loading...'}</i></p>
    </>
  );
}
```

* **If you use a [framework](/learn/creating-a-react-app#full-stack-frameworks), use its built-in data fetching mechanism.** Modern React frameworks have integrated data fetching mechanisms that are efficient and don’t suffer from the above pitfalls.
* **Otherwise, consider using or building a client-side cache.** Popular open source solutions include [TanStack Query](https://tanstack.com/query/latest/), [useSWR](https://swr.vercel.app/), and [React Router 6.4+.](https://beta.reactrouter.com/en/main/start/overview) You can build your own solution too, in which case you would use Effects under the hood but also add logic for deduplicating requests, caching responses, and avoiding network waterfalls (by preloading data or hoisting data requirements to routes).

You can continue fetching data directly in Effects if neither of these approaches suit you.

***

### Specifying reactive dependencies[](#specifying-reactive-dependencies "Link for Specifying reactive dependencies ")

**Notice that you can’t “choose” the dependencies of your Effect.** Every reactive value used by your Effect’s code must be declared as a dependency. Your Effect’s dependency list is determined by the surrounding code:

```
function ChatRoom({ roomId }) { // This is a reactive value

  const [serverUrl, setServerUrl] = useState('https://localhost:1234'); // This is a reactive value too



  useEffect(() => {

    const connection = createConnection(serverUrl, roomId); // This Effect reads these reactive values

    connection.connect();

    return () => connection.disconnect();

  }, [serverUrl, roomId]); // ✅ So you must specify them as dependencies of your Effect

  // ...

}
```

If either `serverUrl` or `roomId` change, your Effect will reconnect to the chat using the new values.

**[Reactive values](/learn/lifecycle-of-reactive-effects#effects-react-to-reactive-values) include props and all variables and functions declared directly inside of your component.** Since `roomId` and `serverUrl` are reactive values, you can’t remove them from the dependencies. If you try to omit them and [your linter is correctly configured for React,](/learn/editor-setup#linting) the linter will flag this as a mistake you need to fix:

```
function ChatRoom({ roomId }) {

  const [serverUrl, setServerUrl] = useState('https://localhost:1234');



  useEffect(() => {

    const connection = createConnection(serverUrl, roomId);

    connection.connect();

    return () => connection.disconnect();

  }, []); // 🔴 React Hook useEffect has missing dependencies: 'roomId' and 'serverUrl'

  // ...

}
```

**To remove a dependency, you need to [“prove” to the linter that it *doesn’t need* to be a dependency.](/learn/removing-effect-dependencies#removing-unnecessary-dependencies)** For example, you can move `serverUrl` out of your component to prove that it’s not reactive and won’t change on re-renders:

```
const serverUrl = 'https://localhost:1234'; // Not a reactive value anymore



function ChatRoom({ roomId }) {

  useEffect(() => {

    const connection = createConnection(serverUrl, roomId);

    connection.connect();

    return () => connection.disconnect();

  }, [roomId]); // ✅ All dependencies declared

  // ...

}
```

Now that `serverUrl` is not a reactive value (and can’t change on a re-render), it doesn’t need to be a dependency. **If your Effect’s code doesn’t use any reactive values, its dependency list should be empty (`[]`):**

```
const serverUrl = 'https://localhost:1234'; // Not a reactive value anymore

const roomId = 'music'; // Not a reactive value anymore



function ChatRoom() {

  useEffect(() => {

    const connection = createConnection(serverUrl, roomId);

    connection.connect();

    return () => connection.disconnect();

  }, []); // ✅ All dependencies declared

  // ...

}
```

[An Effect with empty dependencies](/learn/lifecycle-of-reactive-effects#what-an-effect-with-empty-dependencies-means) doesn’t re-run when any of your component’s props or state change.

### Pitfall

If you have an existing codebase, you might have some Effects that suppress the linter like this:

```
useEffect(() => {

  // ...

  // 🔴 Avoid suppressing the linter like this:

  // eslint-ignore-next-line react-hooks/exhaustive-deps

}, []);
```

**When dependencies don’t match the code, there is a high risk of introducing bugs.** By suppressing the linter, you “lie” to React about the values your Effect depends on. [Instead, prove they’re unnecessary.](/learn/removing-effect-dependencies#removing-unnecessary-dependencies)

#### Examples of passing reactive dependencies[](#examples-dependencies "Link for Examples of passing reactive dependencies")

#### Example 1 of 3:Passing a dependency array[](#passing-a-dependency-array "Link for this heading")

If you specify the dependencies, your Effect runs **after the initial commit *and* after commits with changed dependencies.**

```
useEffect(() => {

  // ...

}, [a, b]); // Runs again if a or b are different
```

In the below example, `serverUrl` and `roomId` are [reactive values,](/learn/lifecycle-of-reactive-effects#effects-react-to-reactive-values) so they both must be specified as dependencies. As a result, selecting a different room in the dropdown or editing the server URL input causes the chat to re-connect. However, since `message` isn’t used in the Effect (and so it isn’t a dependency), editing the message doesn’t re-connect to the chat.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useEffect } from 'react';
import { createConnection } from './chat.js';

function ChatRoom({ roomId }) {
  const [serverUrl, setServerUrl] = useState('https://localhost:1234');
  const [message, setMessage] = useState('');

  useEffect(() => {
    const connection = createConnection(serverUrl, roomId);
    connection.connect();
    return () => {
      connection.disconnect();
    };
  }, [serverUrl, roomId]);

  return (
    <>
      <label>
        Server URL:{' '}
        <input
          value={serverUrl}
          onChange={e => setServerUrl(e.target.value)}
        />
      </label>
      <h1>Welcome to the {roomId} room!</h1>
      <label>
        Your message:{' '}
        <input value={message} onChange={e => setMessage(e.target.value)} />
      </label>
    </>
  );
}

export default function App() {
  const [show, setShow] = useState(false);
  const [roomId, setRoomId] = useState('general');
  return (
    <>
      <label>
        Choose the chat room:{' '}
        <select
          value={roomId}
          onChange={e => setRoomId(e.target.value)}
        >
          <option value="general">general</option>
          <option value="travel">travel</option>
          <option value="music">music</option>
        </select>
        <button onClick={() => setShow(!show)}>
          {show ? 'Close chat' : 'Open chat'}
        </button>
      </label>
      {show && <hr />}
      {show && <ChatRoom roomId={roomId}/>}
    </>
  );
}
```

***

### Updating state based on previous state from an Effect[](#updating-state-based-on-previous-state-from-an-effect "Link for Updating state based on previous state from an Effect ")

When you want to update state based on previous state from an Effect, you might run into a problem:

```
function Counter() {

  const [count, setCount] = useState(0);



  useEffect(() => {

    const intervalId = setInterval(() => {

      setCount(count + 1); // You want to increment the counter every second...

    }, 1000)

    return () => clearInterval(intervalId);

  }, [count]); // 🚩 ... but specifying `count` as a dependency always resets the interval.

  // ...

}
```

Since `count` is a reactive value, it must be specified in the list of dependencies. However, that causes the Effect to cleanup and setup again every time the `count` changes. This is not ideal.

To fix this, [pass the `c => c + 1` state updater](/reference/react/useState#updating-state-based-on-the-previous-state) to `setCount`:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useEffect } from 'react';

export default function Counter() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    const intervalId = setInterval(() => {
      setCount(c => c + 1); // ✅ Pass a state updater
    }, 1000);
    return () => clearInterval(intervalId);
  }, []); // ✅ Now count is not a dependency

  return <h1>{count}</h1>;
}
```

Now that you’re passing `c => c + 1` instead of `count + 1`, [your Effect no longer needs to depend on `count`.](/learn/removing-effect-dependencies#are-you-reading-some-state-to-calculate-the-next-state) As a result of this fix, it won’t need to cleanup and setup the interval again every time the `count` changes.

***

### Removing unnecessary object dependencies[](#removing-unnecessary-object-dependencies "Link for Removing unnecessary object dependencies ")

If your Effect depends on an object or a function created during rendering, it might run too often. For example, this Effect re-connects after every commit because the `options` object is [different for every render:](/learn/removing-effect-dependencies#does-some-reactive-value-change-unintentionally)

```
const serverUrl = 'https://localhost:1234';



function ChatRoom({ roomId }) {

  const [message, setMessage] = useState('');



  const options = { // 🚩 This object is created from scratch on every re-render

    serverUrl: serverUrl,

    roomId: roomId

  };



  useEffect(() => {

    const connection = createConnection(options); // It's used inside the Effect

    connection.connect();

    return () => connection.disconnect();

  }, [options]); // 🚩 As a result, these dependencies are always different on a commit

  // ...
```

Avoid using an object created during rendering as a dependency. Instead, create the object inside the Effect:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useEffect } from 'react';
import { createConnection } from './chat.js';

const serverUrl = 'https://localhost:1234';

function ChatRoom({ roomId }) {
  const [message, setMessage] = useState('');

  useEffect(() => {
    const options = {
      serverUrl: serverUrl,
      roomId: roomId
    };
    const connection = createConnection(options);
    connection.connect();
    return () => connection.disconnect();
  }, [roomId]);

  return (
    <>
      <h1>Welcome to the {roomId} room!</h1>
      <input value={message} onChange={e => setMessage(e.target.value)} />
    </>
  );
}

export default function App() {
  const [roomId, setRoomId] = useState('general');
  return (
    <>
      <label>
        Choose the chat room:{' '}
        <select
          value={roomId}
          onChange={e => setRoomId(e.target.value)}
        >
          <option value="general">general</option>
          <option value="travel">travel</option>
          <option value="music">music</option>
        </select>
      </label>
      <hr />
      <ChatRoom roomId={roomId} />
    </>
  );
}
```

Now that you create the `options` object inside the Effect, the Effect itself only depends on the `roomId` string.

With this fix, typing into the input doesn’t reconnect the chat. Unlike an object which gets re-created, a string like `roomId` doesn’t change unless you set it to another value. [Read more about removing dependencies.](/learn/removing-effect-dependencies)

***

### Removing unnecessary function dependencies[](#removing-unnecessary-function-dependencies "Link for Removing unnecessary function dependencies ")

If your Effect depends on an object or a function created during rendering, it might run too often. For example, this Effect re-connects after every commit because the `createOptions` function is [different for every render:](/learn/removing-effect-dependencies#does-some-reactive-value-change-unintentionally)

```
function ChatRoom({ roomId }) {

  const [message, setMessage] = useState('');



  function createOptions() { // 🚩 This function is created from scratch on every re-render

    return {

      serverUrl: serverUrl,

      roomId: roomId

    };

  }



  useEffect(() => {

    const options = createOptions(); // It's used inside the Effect

    const connection = createConnection();

    connection.connect();

    return () => connection.disconnect();

  }, [createOptions]); // 🚩 As a result, these dependencies are always different on a commit

  // ...
```

By itself, creating a function from scratch on every re-render is not a problem. You don’t need to optimize that. However, if you use it as a dependency of your Effect, it will cause your Effect to re-run after every commit.

Avoid using a function created during rendering as a dependency. Instead, declare it inside the Effect:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useEffect } from 'react';
import { createConnection } from './chat.js';

const serverUrl = 'https://localhost:1234';

function ChatRoom({ roomId }) {
  const [message, setMessage] = useState('');

  useEffect(() => {
    function createOptions() {
      return {
        serverUrl: serverUrl,
        roomId: roomId
      };
    }

    const options = createOptions();
    const connection = createConnection(options);
    connection.connect();
    return () => connection.disconnect();
  }, [roomId]);

  return (
    <>
      <h1>Welcome to the {roomId} room!</h1>
      <input value={message} onChange={e => setMessage(e.target.value)} />
    </>
  );
}

export default function App() {
  const [roomId, setRoomId] = useState('general');
  return (
    <>
      <label>
        Choose the chat room:{' '}
        <select
          value={roomId}
          onChange={e => setRoomId(e.target.value)}
        >
          <option value="general">general</option>
          <option value="travel">travel</option>
          <option value="music">music</option>
        </select>
      </label>
      <hr />
      <ChatRoom roomId={roomId} />
    </>
  );
}
```

Now that you define the `createOptions` function inside the Effect, the Effect itself only depends on the `roomId` string. With this fix, typing into the input doesn’t reconnect the chat. Unlike a function which gets re-created, a string like `roomId` doesn’t change unless you set it to another value. [Read more about removing dependencies.](/learn/removing-effect-dependencies)

***

### Reading the latest props and state from an Effect[](#reading-the-latest-props-and-state-from-an-effect "Link for Reading the latest props and state from an Effect ")

By default, when you read a reactive value from an Effect, you have to add it as a dependency. This ensures that your Effect “reacts” to every change of that value. For most dependencies, that’s the behavior you want.

**However, sometimes you’ll want to read the *latest* props and state from an Effect without “reacting” to them.** For example, imagine you want to log the number of the items in the shopping cart for every page visit:

```
function Page({ url, shoppingCart }) {

  useEffect(() => {

    logVisit(url, shoppingCart.length);

  }, [url, shoppingCart]); // ✅ All dependencies declared

  // ...

}
```

**What if you want to log a new page visit after every `url` change, but *not* if only the `shoppingCart` changes?** You can’t exclude `shoppingCart` from dependencies without breaking the [reactivity rules.](#specifying-reactive-dependencies) However, you can express that you *don’t want* a piece of code to “react” to changes even though it is called from inside an Effect. [Declare an *Effect Event*](/learn/separating-events-from-effects#declaring-an-effect-event) with the [`useEffectEvent`](/reference/react/useEffectEvent) Hook, and move the code reading `shoppingCart` inside of it:

```
function Page({ url, shoppingCart }) {

  const onVisit = useEffectEvent(visitedUrl => {

    logVisit(visitedUrl, shoppingCart.length)

  });



  useEffect(() => {

    onVisit(url);

  }, [url]); // ✅ All dependencies declared

  // ...

}
```

**Effect Events are not reactive and must always be omitted from dependencies of your Effect.** This is what lets you put non-reactive code (where you can read the latest value of some props and state) inside of them. By reading `shoppingCart` inside of `onVisit`, you ensure that `shoppingCart` won’t re-run your Effect.

[Read more about how Effect Events let you separate reactive and non-reactive code.](/learn/separating-events-from-effects#reading-latest-props-and-state-with-effect-events)

***

### Displaying different content on the server and the client[](#displaying-different-content-on-the-server-and-the-client "Link for Displaying different content on the server and the client ")

If your app uses server rendering (either [directly](/reference/react-dom/server) or via a [framework](/learn/creating-a-react-app#full-stack-frameworks)), your component will render in two different environments. On the server, it will render to produce the initial HTML. On the client, React will run the rendering code again so that it can attach your event handlers to that HTML. This is why, for [hydration](/reference/react-dom/client/hydrateRoot#hydrating-server-rendered-html) to work, your initial render output must be identical on the client and the server.

In rare cases, you might need to display different content on the client. For example, if your app reads some data from [`localStorage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage), it can’t possibly do that on the server. Here is how you could implement this:

```
function MyComponent() {

  const [didMount, setDidMount] = useState(false);



  useEffect(() => {

    setDidMount(true);

  }, []);



  if (didMount) {

    // ... return client-only JSX ...

  }  else {

    // ... return initial JSX ...

  }

}
```

While the app is loading, the user will see the initial render output. Then, when it’s loaded and hydrated, your Effect will run and set `didMount` to `true`, triggering a re-render. This will switch to the client-only render output. Effects don’t run on the server, so this is why `didMount` was `false` during the initial server render.

Use this pattern sparingly. Keep in mind that users with a slow connection will see the initial content for quite a bit of time—potentially, many seconds—so you don’t want to make jarring changes to your component’s appearance. In many cases, you can avoid the need for this by conditionally showing different things with CSS.

***

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### My Effect runs twice when the component mounts[](#my-effect-runs-twice-when-the-component-mounts "Link for My Effect runs twice when the component mounts ")

When Strict Mode is on, in development, React runs setup and cleanup one extra time before the actual setup.

This is a stress-test that verifies your Effect’s logic is implemented correctly. If this causes visible issues, your cleanup function is missing some logic. The cleanup function should stop or undo whatever the setup function was doing. The rule of thumb is that the user shouldn’t be able to distinguish between the setup being called once (as in production) and a setup → cleanup → setup sequence (as in development).

Read more about [how this helps find bugs](/learn/synchronizing-with-effects#step-3-add-cleanup-if-needed) and [how to fix your logic.](/learn/synchronizing-with-effects#how-to-handle-the-effect-firing-twice-in-development)

***

### My Effect runs after every re-render[](#my-effect-runs-after-every-re-render "Link for My Effect runs after every re-render ")

First, check that you haven’t forgotten to specify the dependency array:

```
useEffect(() => {

  // ...

}); // 🚩 No dependency array: re-runs after every commit!
```

If you’ve specified the dependency array but your Effect still re-runs in a loop, it’s because one of your dependencies is different on every re-render.

You can debug this problem by manually logging your dependencies to the console:

```
  useEffect(() => {

    // ..

  }, [serverUrl, roomId]);



  console.log([serverUrl, roomId]);
```

You can then right-click on the arrays from different re-renders in the console and select “Store as a global variable” for both of them. Assuming the first one got saved as `temp1` and the second one got saved as `temp2`, you can then use the browser console to check whether each dependency in both arrays is the same:

```
Object.is(temp1[0], temp2[0]); // Is the first dependency the same between the arrays?

Object.is(temp1[1], temp2[1]); // Is the second dependency the same between the arrays?

Object.is(temp1[2], temp2[2]); // ... and so on for every dependency ...
```

When you find the dependency that is different on every re-render, you can usually fix it in one of these ways:

* [Updating state based on previous state from an Effect](#updating-state-based-on-previous-state-from-an-effect)
* [Removing unnecessary object dependencies](#removing-unnecessary-object-dependencies)
* [Removing unnecessary function dependencies](#removing-unnecessary-function-dependencies)
* [Reading the latest props and state from an Effect](#reading-the-latest-props-and-state-from-an-effect)

As a last resort (if these methods didn’t help), wrap its creation with [`useMemo`](/reference/react/useMemo#memoizing-a-dependency-of-another-hook) or [`useCallback`](/reference/react/useCallback#preventing-an-effect-from-firing-too-often) (for functions).

***

***

### My cleanup logic runs even though my component didn’t unmount[](#my-cleanup-logic-runs-even-though-my-component-didnt-unmount "Link for My cleanup logic runs even though my component didn’t unmount ")

The cleanup function runs not only during unmount, but before every re-render with changed dependencies. Additionally, in development, React [runs setup+cleanup one extra time immediately after component mounts.](#my-effect-runs-twice-when-the-component-mounts)

If you have cleanup code without corresponding setup code, it’s usually a code smell:

```
useEffect(() => {

  // 🔴 Avoid: Cleanup logic without corresponding setup logic

  return () => {

    doSomething();

  };

}, []);
```

Your cleanup logic should be “symmetrical” to the setup logic, and should stop or undo whatever setup did:

```
  useEffect(() => {

    const connection = createConnection(serverUrl, roomId);

    connection.connect();

    return () => {

      connection.disconnect();

    };

  }, [serverUrl, roomId]);
```

[Learn how the Effect lifecycle is different from the component’s lifecycle.](/learn/lifecycle-of-reactive-effects#the-lifecycle-of-an-effect)

***

### My Effect does something visual, and I see a flicker before it runs[](#my-effect-does-something-visual-and-i-see-a-flicker-before-it-runs "Link for My Effect does something visual, and I see a flicker before it runs ")

If your Effect must block the browser from [painting the screen,](/learn/render-and-commit#epilogue-browser-paint) replace `useEffect` with [`useLayoutEffect`](/reference/react/useLayoutEffect). Note that **this shouldn’t be needed for the vast majority of Effects.** You’ll only need this if it’s crucial to run your Effect before the browser paint: for example, to measure and position a tooltip before the user sees it.

[PrevioususeDeferredValue](/reference/react/useDeferredValue)

[NextuseEffectEvent](/reference/react/useEffectEvent)

***

----
url: https://react.dev/reference/react/ViewTransition
----

[API Reference](/reference/react)

[Components](/reference/react/components)

# \<ViewTransition>[](#undefined "Link for this heading")

### Canary

**The `<ViewTransition />` API is currently only available in React’s Canary and Experimental channels.**

[Learn more about React’s release channels here.](/community/versioning-policy#all-release-channels)

`<ViewTransition>` lets you animate a component tree with Transitions and Suspense.

```
import {ViewTransition} from 'react';



<ViewTransition>

  <div>...</div>

</ViewTransition>
```

* [Reference](#reference)

  * [`<ViewTransition>`](#viewtransition)
  * [View Transition Class](#view-transition-class)
  * [View Transition Event](#view-transition-event)

* [Styling View Transitions](#styling-view-transitions)

* [Usage](#usage)

  * [Animating an element on enter/exit](#animating-an-element-on-enter)
  * [Animating enter/exit with Activity](#animating-enter-exit-with-activity)
  * [Animating a shared element](#animating-a-shared-element)
  * [Animating reorder of items in a list](#animating-reorder-of-items-in-a-list)
  * [Animating from Suspense content](#animating-from-suspense-content)
  * [Opting-out of an animation](#opting-out-of-an-animation)
  * [Customizing animations](#customizing-animations)
  * [Customizing animations with types](#customizing-animations-with-types)
  * [Animating with JavaScript](#animating-with-javascript)
  * [Animating transition types with JavaScript](#animating-transition-types-with-javascript)
  * [Building View Transition enabled routers](#building-view-transition-enabled-routers)

* [Troubleshooting](#troubleshooting)

  * [My `<ViewTransition>` is not activating](#my-viewtransition-is-not-activating)
  * [I’m getting an error “There are two `<ViewTransition name=%s>` components with the same name mounted at the same time.”](#two-viewtransition-with-same-name)

***

## Reference[](#reference "Link for Reference ")

### `<ViewTransition>`[](#viewtransition "Link for this heading")

Wrap a component tree in `<ViewTransition>` to animate it:

```
<ViewTransition>

  <Page />

</ViewTransition>
```

[See more examples below.](#usage)

##### Deep Dive#### How does `<ViewTransition>` work?[](#how-does-viewtransition-work "Link for this heading")

Under the hood, React applies `view-transition-name` to inline styles of the nearest DOM node nested inside the `<ViewTransition>` component. If there are multiple sibling DOM nodes like `<ViewTransition><div /><div /></ViewTransition>` then React adds a suffix to the name to make each unique but conceptually they’re part of the same one. React doesn’t apply these eagerly but only at the time that boundary should participate in an animation.

React automatically calls `startViewTransition` itself behind the scenes so you should never do that yourself. In fact, if you have something else on the page running a ViewTransition React will interrupt it. So it’s recommended that you use React itself to coordinate these. If you had other ways to trigger ViewTransitions in the past, we recommend that you migrate to the built-in way.

If there are other React ViewTransitions already running then React will wait for them to finish before starting the next one. However, importantly if there are multiple updates happening while the first one is running, those will all be batched into one. If you start A->B. Then in the meantime you get an update to go to C and then D. When the first A->B animation finishes the next one will animate from B->D.

The `getSnapshotBeforeUpdate` lifecycle will be called before `startViewTransition` and some `view-transition-name` will update at the same time.

Then React calls `startViewTransition`. Inside the `updateCallback`, React will:

* Apply its mutations to the DOM and invoke `useInsertionEffect`.
* Wait for fonts to load.
* Call `componentDidMount`, `componentDidUpdate`, `useLayoutEffect` and refs.
* Wait for any pending Navigation to finish.
* Then React will measure any changes to the layout to see which boundaries will need to animate.

After the ready Promise of the `startViewTransition` is resolved, React will then revert the `view-transition-name`. Then React will invoke the `onEnter`, `onExit`, `onUpdate` and `onShare` callbacks to allow for manual programmatic control over the animations. This will be after the built-in default ones have already been computed.

If a `flushSync` happens to get in the middle of this sequence, then React will skip the Transition since it relies on being able to complete synchronously.

After the finished Promise of the `startViewTransition` is resolved, React will then invoke `useEffect`. This prevents those from interfering with the performance of the animation. However, this is not a guarantee because if another `setState` happens while the animation is running it’ll still have to invoke the `useEffect` earlier to preserve the sequential guarantees.

#### Props[](#props "Link for Props ")

* **optional** `name`: A string or object. The name of the View Transition used for shared element transitions. If not provided, React will use a unique name for each View Transition to prevent unexpected animations.
* [View Transition Class](#view-transition-class) props.
* [View Transition Event](#view-transition-event) props.

#### Caveats[](#caveats "Link for Caveats ")

* Only use `name` for [shared element transitions](#animating-a-shared-element). For all other animations, React automatically generates a unique name to prevent unexpected animations.
* By default, `setState` updates immediately and does not activate `<ViewTransition>`, only updates wrapped in a [Transition](/reference/react/useTransition), [`<Suspense>`](/reference/react/Suspense), or `useDeferredValue` activate ViewTransition.
* `<ViewTransition>` creates an image that can be moved around, scaled and cross-faded. Unlike Layout Animations you may have seen in React Native or Motion, this means that not every individual Element inside of it animates its position. This can lead to better performance and a more continuous feeling, smooth animation compared to animating every individual piece. However, it can also lose continuity in things that should be moving by themselves. So you might have to add more `<ViewTransition>` boundaries manually as a result.
* Currently, `<ViewTransition>` only works in the DOM. We’re working on adding support for React Native and other platforms.

#### Animation triggers[](#animation-triggers "Link for Animation triggers ")

React automatically decides the type of View Transition animation to trigger:

* `enter`: If a `ViewTransition` is the first component inserted in this Transition, then this will activate.
* `exit`: If a `ViewTransition` is the first component deleted in this Transition, then this will activate.
* `update`: If a `ViewTransition` has any DOM mutations inside it that React is doing (such as a prop changing) or if the `ViewTransition` boundary itself changes size or position due to an immediate sibling. If there are nested `ViewTransition` then the mutation applies to them and not the parent.
* `share`: If a named `ViewTransition` is inside a deleted subtree and another named `ViewTransition` with the same name is part of an inserted subtree in the same Transition, they form a Shared Element Transition, and it animates from the deleted one to the inserted one.

By default, `<ViewTransition>` animates with a smooth cross-fade (the browser default view transition).

You can customize the animation by providing a [View Transition Class](#view-transition-class) to the `<ViewTransition>` component for each kind of trigger (see [Styling View Transitions](#styling-view-transitions)), or by using [ViewTransition Events](#view-transition-events) to control the animation with JavaScript using the [Web Animations API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Animations_API).

### Note

#### Always check `prefers-reduced-motion`[](#always-check-prefers-reduced-motion "Link for this heading")

Many users may prefer not having animations on the page. React doesn’t automatically disable animations for this case.

We recommend always using the `@media (prefers-reduced-motion)` media query to disable animations or tone them down based on user preference.

In the future, CSS libraries may have this built-in to their presets.

### View Transition Class[](#view-transition-class "Link for View Transition Class ")

`<ViewTransition>` provides props to define what animations trigger:

```
<ViewTransition

  default="none"

  enter="slide-up"

  exit="slide-down"

/>
```

#### Props[](#view-transition-class-props "Link for Props ")

* **optional** `enter`: `"auto"`, `"none"`, a string, or an object.
* **optional** `exit`: `"auto"`, `"none"`, a string, or an object.
* **optional** `update`: `"auto"`, `"none"`, a string, or an object.
* **optional** `share`: `"auto"`, `"none"`, a string, or an object.
* **optional** `default`: `"auto"`, `"none"`, a string, or an object.

#### Caveats[](#view-transition-class-caveats "Link for Caveats ")

* If `default` is `"none"` then all other triggers are turned off unless explicitly listed.

#### Values[](#view-transition-values "Link for Values ")

View Transition class values can be:

* `auto`: the default. Uses the browser default animation.
* `none`: disable animations for this type.
* `<classname>`: a custom CSS class name to use for [customizing View Transitions](#styling-view-transitions).

Object values can be an object with string keys and a value of `auto`, `none` or a custom className:

* `{[type]: value}`: applies `value` if the animation matches the [Transition Type](/reference/react/addTransitionType).
* `{default: value}`: the default value to apply if no [Transition Type](/reference/react/addTransitionType) is matched.

For example, you can define a ViewTransition as:

```
<ViewTransition

  /* turn off any animation not defined below */

  default="none"

  enter={{

    /* apply slide-in for Transition Type `forward` */

    "forward": 'slide-in',

    /* otherwise use the browser default animation */

    "default": 'auto'

  }}

  /* use the browser default for exit animations*/

  exit="auto"

  /* apply a custom `cross-fade` class for updates */

  update="cross-fade"

>
```

See [Styling View Transitions](#styling-view-transitions) for how to define CSS classes for custom animations.

***

### View Transition Event[](#view-transition-event "Link for View Transition Event ")

View Transition Events allow you to control the animation with JavaScript using the [Web Animations API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Animations_API):

```
<ViewTransition

  onEnter={instance => {/* ... */}}

  onExit={instance => {/* ... */}}

/>
```

#### Props[](#view-transition-event-props "Link for Props ")

* **optional** `onEnter`: Called when an “enter” animation is triggered.
* **optional** `onExit`: Called when an “exit” animation is triggered.
* **optional** `onShare`: Called when a “share” animation is triggered.
* **optional** `onUpdate`: Called when an “update” animation is triggered.

#### Caveats[](#view-transition-event-caveats "Link for Caveats ")

* Only one event fires per `<ViewTransition>` per Transition. `onShare` takes precedence over `onEnter` and `onExit`.
* Each event should return a **cleanup function**. The cleanup function is called when the View Transition finishes, allowing you to cancel or cleanup any animations.

#### Arguments[](#view-transition-event-arguments "Link for Arguments ")

Each event receives two arguments:

* `instance`: A View Transition instance that provides access to the view transition [pseudo-elements](https://developer.mozilla.org/en-US/docs/Web/API/View_Transition_API/Using#the_view_transition_process)

  * `old`: The `::view-transition-old` pseudo-element.
  * `new`: The `::view-transition-new` pseudo-element.
  * `name`: The `view-transition-name` string for this boundary.
  * `group`: The `::view-transition-group` pseudo-element.
  * `imagePair`: The `::view-transition-image-pair` pseudo-element.

* `types`: An `Array<string>` of [Transition Types](/reference/react/addTransitionType) included in the animation. Empty array if no types were specified.

For example, you can define a `onEnter` event that drives the animation using JavaScript:

```
<ViewTransition

  onEnter={(instance, types) => {

    const anim = instance.new.animate([{opacity: 0}, {opacity: 1}], {

      duration: 500,

    });

    return () => anim.cancel();

  }}>

  <div>...</div>

</ViewTransition>
```

See [Animating with JavaScript](#animating-with-javascript) for more examples.

***

## Styling View Transitions[](#styling-view-transitions "Link for Styling View Transitions ")

### Note

In many early examples of View Transitions around the web, you’ll have seen using a [`view-transition-name`](https://developer.mozilla.org/en-US/docs/Web/CSS/view-transition-name) and then style it using `::view-transition-...(my-name)` selectors. We don’t recommend that for styling. Instead, we normally recommend using a View Transition Class instead.

To customize the animation for a `<ViewTransition>` you can provide a View Transition Class to one of the activation props. The View Transition Class is a CSS class name that React applies to the child elements when the ViewTransition activates.

For example, to customize an “enter” animation, provide a class name to the `enter` prop:

```
<ViewTransition enter="slide-in">
```

When the `<ViewTransition>` activates an “enter” animation, React will add the class name `slide-in`. Then you can refer to this class using [view transition pseudo selectors](https://developer.mozilla.org/en-US/docs/Web/API/View_Transition_API#pseudo-elements) to build reusable animations:

```
::view-transition-group(.slide-in) {

}

::view-transition-old(.slide-in) {

}

::view-transition-new(.slide-in) {

}
```

In the future, CSS libraries may add built-in animations using View Transition Classes to make this easier to use.

***

## Usage[](#usage "Link for Usage ")

### Animating an element on enter/exit[](#animating-an-element-on-enter "Link for Animating an element on enter/exit ")

Enter/Exit Transitions trigger when a `<ViewTransition>` is added or removed by a component in a transition:

```
function Child() {

  return (

    <ViewTransition enter="auto" exit="auto" default="none">

      <div>Hi</div>

    </ViewTransition>

  );

}



function Parent() {

  const [show, setShow] = useState();

  if (show) {

    return <Child />;

  }

  return null;

}
```

When `setShow` is called, `show` switches to `true` and the `Child` component is rendered. When `setShow` is called inside `startTransition`, and `Child` renders a `ViewTransition` before any other DOM nodes, an `enter` animation is triggered.

When `show` switches back to `false`, an `exit` animation is triggered.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import {ViewTransition, useState, startTransition} from 'react';
import {Video} from './Video';
import videos from './data';

function Item() {
  return (
    <ViewTransition enter="auto" exit="auto" default="none">
      <Video video={videos[0]} />
    </ViewTransition>
  );
}

export default function Component() {
  const [showItem, setShowItem] = useState(false);
  return (
    <>
      <button
        onClick={() => {
          startTransition(() => {
            setShowItem((prev) => !prev);
          });
        }}>
        {showItem ? '➖' : '➕'}
      </button>

      {showItem ? <Item /> : null}
    </>
  );
}
```

### Pitfall

#### Only top-level ViewTransitions animate on exit/enter[](#only-top-level-viewtransition-animates-on-exit-enter "Link for Only top-level ViewTransitions animate on exit/enter ")

`<ViewTransition>` only activates exit/enter if it is placed *before* any DOM nodes.

If there’s a `<div>` above `<ViewTransition>`, no exit/enter animations trigger:

```
function Item() {

  return (

    <div> {/* 🚩<div> above <ViewTransition> breaks exit/enter */}

      <ViewTransition enter="auto" exit="auto" default="none">

        <Video video={videos[0]} />

      </ViewTransition>

    </div>

  );

}
```

This constraint prevents subtle bugs where too much or too little animates.

***

### Animating enter/exit with Activity[](#animating-enter-exit-with-activity "Link for Animating enter/exit with Activity ")

If you want to animate a component in and out while preserving its state, or pre-rendering content for an animation, you can use [`<Activity>`](/reference/react/Activity). When a `<ViewTransition>` inside an `<Activity>` becomes visible, the `enter` animation activates. When it becomes hidden, the `exit` animation activates:

```
<Activity mode={isVisible ? 'visible' : 'hidden'}>

  <ViewTransition enter="auto" exit="auto">

    <Counter />

  </ViewTransition>

</Activity>
```

In this example, `Counter` has a counter with internal state. Try incrementing the counter, hiding it, then showing it again. The counter’s value is preserved while the sidebar animates in and out:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { Activity, ViewTransition, useState, startTransition } from 'react';

export default function App() {
  const [show, setShow] = useState(true);
  return (
    <div className="layout">
      <Toggle show={show} setShow={setShow} />
      <Activity mode={show ? 'visible' : 'hidden'}>
        <ViewTransition enter="auto" exit="auto" default="none">
          <Counter />
        </ViewTransition>
      </Activity>
    </div>
  );
}
function Toggle({show, setShow}) {
  return (
    <button
      className="toggle"
      onClick={() => {
        startTransition(() => {
          setShow(s => !s);
        });
      }}>
      {show ? 'Hide' : 'Show'}
    </button>
  )
}
function Counter() {
  const [count, setCount] = useState(0);
  return (
    <div className="counter">
      <h2>Counter</h2>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>
        Increment
      </button>
    </div>
  );
}
```

Without `<Activity>`, the counter would reset to `0` every time the sidebar reappears.

***

### Animating a shared element[](#animating-a-shared-element "Link for Animating a shared element ")

Normally, we don’t recommend assigning a name to a `<ViewTransition>` and instead let React assign it an automatic name. The reason you might want to assign a name is to animate between completely different components when one tree unmounts and another tree mounts at the same time, to preserve continuity.

```
<ViewTransition name={UNIQUE_NAME}>

  <Child />

</ViewTransition>
```

When one tree unmounts and another mounts, if there’s a pair where the same name exists in the unmounting tree and the mounting tree, they trigger the “share” animation on both. It animates from the unmounting side to the mounting side.

Unlike an exit/enter animation this can be deeply inside the deleted/mounted tree. If a `<ViewTransition>` would also be eligible for exit/enter, then the “share” animation takes precedence.

If Transition first unmounts one side and then leads to a `<Suspense>` fallback being shown before eventually the new name being mounted, then no shared element transition happens.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import {ViewTransition, useState, startTransition} from 'react';
import {Video, Thumbnail, FullscreenVideo} from './Video';
import videos from './data';

export default function Component() {
  const [fullscreen, setFullscreen] = useState(false);
  if (fullscreen) {
    return (
      <FullscreenVideo
        video={videos[0]}
        onExit={() => startTransition(() => setFullscreen(false))}
      />
    );
  }
  return (
    <Video
      video={videos[0]}
      onClick={() => startTransition(() => setFullscreen(true))}
    />
  );
}
```

### Note

If either the mounted or unmounted side of a pair is outside the viewport, then no pair is formed. This ensures that it doesn’t fly in or out of the viewport when something is scrolled. Instead it’s treated as a regular enter/exit by itself.

This does not happen if the same Component instance changes position, which triggers an “update”. Those animate regardless of whether one position is outside the viewport.

There is a known case where if a deeply nested unmounted `<ViewTransition>` is inside the viewport but the mounted side is not within the viewport, then the unmounted side animates as its own “exit” animation even if it’s deeply nested instead of as part of the parent animation.

### Pitfall

It’s important that there’s only one thing with the same name mounted at a time in the entire app. Therefore it’s important to use unique namespaces for the name to avoid conflicts. To ensure you can do this you might want to add a constant in a separate module that you import.

```
export const MY_NAME = "my-globally-unique-name";

import {MY_NAME} from './shared-name';

...

<ViewTransition name={MY_NAME}>
```

***

### Animating reorder of items in a list[](#animating-reorder-of-items-in-a-list "Link for Animating reorder of items in a list ")

```
items.map((item) => <Component key={item.id} item={item} />);
```

When reordering a list, without updating the content, the “update” animation triggers on each `<ViewTransition>` in the list if they’re outside a DOM node. Similar to enter/exit animations.

This means that this will trigger the animation on this `<ViewTransition>`:

```
function Component() {

  return (

    <ViewTransition>

      <div>...</div>

    </ViewTransition>

  );

}
```

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import {ViewTransition, useState, startTransition} from 'react';
import {Video} from './Video';
import videos from './data';

export default function Component() {
  const [orderedVideos, setOrderedVideos] = useState(videos);
  const reorder = () => {
    startTransition(() => {
      setOrderedVideos((prev) => {
        return [...prev.sort(() => Math.random() - 0.5)];
      });
    });
  };
  return (
    <>
      <button onClick={reorder}>🎲</button>
      <div className="listContainer">
        {orderedVideos.map((video, i) => {
          return (
            <ViewTransition key={video.title}>
              <Video video={video} />
            </ViewTransition>
          );
        })}
      </div>
    </>
  );
}
```

However, this wouldn’t animate each individual item:

```
function Component() {

  return (

    <div>

      <ViewTransition>...</ViewTransition>

    </div>

  );

}
```

Instead, any parent `<ViewTransition>` would cross-fade. If there is no parent `<ViewTransition>` then there’s no animation in that case.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import {ViewTransition, useState, startTransition} from 'react';
import {Video} from './Video';
import videos from './data';

export default function Component() {
  const [orderedVideos, setOrderedVideos] = useState(videos);
  const reorder = () => {
    startTransition(() => {
      setOrderedVideos((prev) => {
        return [...prev.sort(() => Math.random() - 0.5)];
      });
    });
  };
  return (
    <>
      <button onClick={reorder}>🎲</button>
      <ViewTransition>
        <div className="listContainer">
          {orderedVideos.map((video, i) => {
            return <Video video={video} key={video.title} />;
          })}
        </div>
      </ViewTransition>
    </>
  );
}
```

This means you might want to avoid wrapper elements in lists where you want to allow the Component to control its own reorder animation:

```
items.map(item => <div><Component key={item.id} item={item} /></div>)
```

The above rule also applies if one of the items updates to resize, which then causes the siblings to resize, it’ll also animate its sibling `<ViewTransition>` but only if they’re immediate siblings.

This means that during an update, which causes a lot of re-layout, it doesn’t individually animate every `<ViewTransition>` on the page. That would lead to a lot of noisy animations which distracts from the actual change. Therefore React is more conservative about when an individual animation triggers.

### Pitfall

It’s important to properly use keys to preserve identity when reordering lists. It might seem like you could use “name”, shared element transitions, to animate reorders but that would not trigger if one side was outside the viewport. To animate a reorder you often want to show that it went to a position outside the viewport.

***

### Animating from Suspense content[](#animating-from-suspense-content "Link for Animating from Suspense content ")

Like any Transition, React waits for data and new CSS (`<link rel="stylesheet" precedence="...">`) before running the animation. In addition to this, ViewTransitions also wait up to 500ms for new fonts to load before starting the animation to avoid them flickering in later. For the same reason, an image wrapped in ViewTransition will wait for the image to load.

If it’s inside a new Suspense boundary instance, then the fallback is shown first. After the Suspense boundary fully loads, it triggers the `<ViewTransition>` to animate the reveal to the content.

There are two ways to animate Suspense boundaries depending on where you place the `<ViewTransition>`:

**Update:**

```
<ViewTransition>

  <Suspense fallback={<A />}>

    <B />

  </Suspense>

</ViewTransition>
```

In this scenario when the content goes from A to B, it’ll be treated as an “update” and apply that class if appropriate. Both A and B will get the same view-transition-name and therefore they’re acting as a cross-fade by default.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import {ViewTransition, useState, startTransition, Suspense} from 'react';
import {Video, VideoPlaceholder} from './Video';
import {useLazyVideoData} from './data';

function LazyVideo() {
  const video = useLazyVideoData();
  return <Video video={video} />;
}

export default function Component() {
  const [showItem, setShowItem] = useState(false);
  return (
    <>
      <button
        onClick={() => {
          startTransition(() => {
            setShowItem((prev) => !prev);
          });
        }}>
        {showItem ? '➖' : '➕'}
      </button>
      {showItem ? (
        <ViewTransition>
          <Suspense fallback={<VideoPlaceholder />}>
            <LazyVideo />
          </Suspense>
        </ViewTransition>
      ) : null}
    </>
  );
}
```

**Enter/Exit:**

```
<Suspense fallback={<ViewTransition><A /></ViewTransition>}>

  <ViewTransition><B /></ViewTransition>

</Suspense>
```

In this scenario, these are two separate ViewTransition instances each with their own `view-transition-name`. This will be treated as an “exit” of the `<A>` and an “enter” of the `<B>`.

You can achieve different effects depending on where you choose to place the `<ViewTransition>` boundary.

***

### Opting-out of an animation[](#opting-out-of-an-animation "Link for Opting-out of an animation ")

Sometimes you’re wrapping a large existing component, like a whole page, and you want to animate some updates, such as changing the theme. However, you don’t want it to opt-in all updates inside the whole page to cross-fade when they’re updating. Especially if you’re incrementally adding more animations.

You can use the class “none” to opt-out of an animation. By wrapping your children in a “none” you can disable animations for updates to them while the parent still triggers.

```
<ViewTransition>

  <div className={theme}>

    <ViewTransition update="none">{children}</ViewTransition>

  </div>

</ViewTransition>
```

This will only animate if the theme changes and not if only the children update. The children can still opt-in again with their own `<ViewTransition>` but at least it’s manual again.

***

### Customizing animations[](#customizing-animations "Link for Customizing animations ")

By default, `<ViewTransition>` includes the default cross-fade from the browser.

To customize animations, you can provide props to the `<ViewTransition>` component to specify which animations to use, based on how the `<ViewTransition>` activates.

For example, we can slow down the default cross fade animation:

```
<ViewTransition default="slow-fade">

  <Video />

</ViewTransition>
```

And define slow-fade in CSS using view transition classes:

```
::view-transition-old(.slow-fade) {

  animation-duration: 500ms;

}



::view-transition-new(.slow-fade) {

  animation-duration: 500ms;

}
```

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import {ViewTransition, useState, startTransition} from 'react';
import {Video} from './Video';
import videos from './data';

function Item() {
  return (
    <ViewTransition default="slow-fade">
      <Video video={videos[0]} />
    </ViewTransition>
  );
}

export default function Component() {
  const [showItem, setShowItem] = useState(false);
  return (
    <>
      <button
        onClick={() => {
          startTransition(() => {
            setShowItem((prev) => !prev);
          });
        }}>
        {showItem ? '➖' : '➕'}
      </button>

      {showItem ? <Item /> : null}
    </>
  );
}
```

In addition to setting the `default`, you can also provide configurations for `enter`, `exit`, `update`, and `share` animations.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import {ViewTransition, useState, startTransition} from 'react';
import {Video} from './Video';
import videos from './data';

function Item() {
  return (
    <ViewTransition enter="slide-in" exit="slide-out">
      <Video video={videos[0]} />
    </ViewTransition>
  );
}

export default function Component() {
  const [showItem, setShowItem] = useState(false);
  return (
    <>
      <button
        onClick={() => {
          startTransition(() => {
            setShowItem((prev) => !prev);
          });
        }}>
        {showItem ? '➖' : '➕'}
      </button>

      {showItem ? <Item /> : null}
    </>
  );
}
```

***

### Customizing animations with types[](#customizing-animations-with-types "Link for Customizing animations with types ")

You can use the [`addTransitionType`](/reference/react/addTransitionType) API to add a class name to the child elements when a specific transition type is activated for a specific activation trigger. This allows you to customize the animation for each type of transition.

For example, to customize the animation for all forward and backward navigations:

```
<ViewTransition

  default={{

    'navigation-back': 'slide-right',

    'navigation-forward': 'slide-left',

  }}>

  <div>...</div>

</ViewTransition>;



// in your router:

startTransition(() => {

  addTransitionType('navigation-' + navigationType);

});
```

When the ViewTransition activates a “navigation-back” animation, React will add the class name “slide-right”. When the ViewTransition activates a “navigation-forward” animation, React will add the class name “slide-left”.

In the future, routers and other libraries may add support for standard view-transition types and styles.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import {
  ViewTransition,
  addTransitionType,
  useState,
  startTransition,
} from 'react';
import {Video} from './Video';
import videos from './data';

function Item() {
  return (
    <ViewTransition
      enter={{
        'add-video-back': 'slide-in-back',
        'add-video-forward': 'slide-in-forward',
      }}
      exit={{
        'remove-video-back': 'slide-in-forward',
        'remove-video-forward': 'slide-in-back',
      }}>
      <Video video={videos[0]} />
    </ViewTransition>
  );
}

export default function Component() {
  const [showItem, setShowItem] = useState(false);
  return (
    <>
      <div className="button-container">
        <button
          onClick={() => {
            startTransition(() => {
              if (showItem) {
                addTransitionType('remove-video-back');
              } else {
                addTransitionType('add-video-back');
              }
              setShowItem((prev) => !prev);
            });
          }}>
          ⬅️
        </button>
        <button
          onClick={() => {
            startTransition(() => {
              if (showItem) {
                addTransitionType('remove-video-forward');
              } else {
                addTransitionType('add-video-forward');
              }
              setShowItem((prev) => !prev);
            });
          }}>
          ➡️
        </button>
      </div>
      {showItem ? <Item /> : null}
    </>
  );
}
```

***

### Animating with JavaScript[](#animating-with-javascript "Link for Animating with JavaScript ")

While [View Transition Classes](#view-transition-class) let you define animations with CSS, sometimes you need imperative control over the animation. The `onEnter`, `onExit`, `onUpdate`, and `onShare` callbacks give you direct access to the view transition pseudo-elements so you can animate them using the [Web Animations API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Animations_API).

Each callback receives an `instance` with `.old` and `.new` properties representing the view transition pseudo-elements. You can call `.animate()` on them just like you would on a DOM element:

```
<ViewTransition

  onEnter={(instance) => {

    const anim = instance.new.animate(

      [

        {transform: 'scale(0.8)'},

        {transform: 'scale(1)'},

      ],

      {duration: 300, easing: 'ease-out'}

    );

    return () => anim.cancel();

  }}>

  <div>...</div>

</ViewTransition>
```

This allows you to combine CSS-driven animations and JavaScript-driven animations.

In the following example, the default cross-fade is handled by CSS, and the slide animations are driven by JavaScript in the `onEnter` and `onExit` animations:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import {ViewTransition, useState, startTransition} from 'react';
import {Video} from './Video';
import videos from './data';
import {SLIDE_IN, SLIDE_OUT} from './animations';

function Item() {
  return (
    <ViewTransition
      default="none"
      /* CSS driven cross fade defaults */
      enter="auto"
      exit="auto"
      /* JS driven slide animations */
      onEnter={(instance) => {
        const anim = instance.new.animate(
          SLIDE_IN,
          {duration: 500, easing: 'ease-out'}
        );
        return () => anim.cancel();
      }}
      onExit={(instance) => {
        const anim = instance.old.animate(
          SLIDE_OUT,
          {duration: 300, easing: 'ease-in'}
        );
        return () => anim.cancel();
      }}>
      <Video video={videos[0]} />
    </ViewTransition>
  );
}

export default function Component() {
  const [showItem, setShowItem] = useState(false);
  return (
    <>
      <button
        onClick={() => {
          startTransition(() => {
            setShowItem((prev) => !prev);
          });
        }}>
        {showItem ? '➖' : '➕'}
      </button>

      {showItem ? <Item /> : null}
    </>
  );
}
```

### Note

#### Always clean up View Transition Events[](#always-clean-up-view-transition-events "Link for Always clean up View Transition Events ")

View Transition Events should always return a cleanup function:

```
<ViewTransition

  onEnter={(instance) => {

    const anim = instance.new.animate(

      SLIDE_IN,

      {duration: 500, easing: 'ease-out'}

    );

    return () => anim.cancel();

  }}

>
```

This allows the browser to cancel the animation when the View Transition is interrupted.

***

### Animating transition types with JavaScript[](#animating-transition-types-with-javascript "Link for Animating transition types with JavaScript ")

You can use `types` passed to `ViewTransition` events to conditionally apply different animations based on how the Transition was triggered.

```
 <ViewTransition

  onEnter={(instance, types) => {

    const duration = types.includes('fast') ? 150 : 2000;

    const anim = instance.new.animate(

      SLIDE_IN,

      {duration: duration, easing: 'ease-out'}

    );

    return () => anim.cancel();

  }}

>
```

This example calls [`addTransitionType`](/reference/react/addTransitionType) to mark a Transition as “fast” and then adjust the animation duration:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import {ViewTransition, useState, startTransition, addTransitionType} from 'react';
import {Video} from './Video';
import videos from './data';
import {SLIDE_IN, SLIDE_OUT} from './animations';

function Item() {
  return (
    <ViewTransition
      onEnter={(instance, types) => {
        const duration = types.includes('fast') ? 150 : 2000;
        const anim = instance.new.animate(
          SLIDE_IN,
          {duration: duration, easing: 'ease-out'}
        );
        return () => anim.cancel();
      }}
      onExit={(instance, types) => {
        const duration = types.includes('fast') ? 150 : 500;
        const anim = instance.old.animate(
          SLIDE_OUT,
          {duration: duration, easing: 'ease-in'}
        );
        return () => anim.cancel();
      }}>
      <Video video={videos[0]} />
    </ViewTransition>
  );
}

export default function Component() {
  const [showItem, setShowItem] = useState(false);
  const [isFast, setIsFast] = useState(false);
  return (
    <>
      <div>
        Fast: <input type="checkbox" onChange={() => {setIsFast(f => !f)}} value={isFast}></input>
      </div><br />
      <button
        onClick={() => {
          startTransition(() => {
            if (isFast) {
              addTransitionType('fast');
            }
            setShowItem((prev) => !prev);
          });
        }}>
        {showItem ? '➖' : '➕'}
      </button>

      {showItem ? <Item /> : null}
    </>
  );
}
```

***

### Building View Transition enabled routers[](#building-view-transition-enabled-routers "Link for Building View Transition enabled routers ")

React waits for any pending Navigation to finish to ensure that scroll restoration happens within the animation. If the Navigation is blocked on React, your router must unblock in `useLayoutEffect` since `useEffect` would lead to a deadlock.

If a `startTransition` is started from the legacy popstate event, such as during a “back”-navigation then it must finish synchronously to ensure scroll and form restoration works correctly. This is in conflict with running a View Transition animation. Therefore, React will skip animations from popstate and animations won’t run for the back button. You can fix this by upgrading your router to use the Navigation API.

***

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### My `<ViewTransition>` is not activating[](#my-viewtransition-is-not-activating "Link for this heading")

`<ViewTransition>` only activates if it is placed before any DOM node:

```
function Component() {

  return (

    <div>

      <ViewTransition>Hi</ViewTransition>

    </div>

  );

}
```

To fix, ensure that the `<ViewTransition>` comes before any other DOM nodes:

```
function Component() {

  return (

    <ViewTransition>

      <div>Hi</div>

    </ViewTransition>

  );

}
```

### I’m getting an error “There are two `<ViewTransition name=%s>` components with the same name mounted at the same time.”[](#two-viewtransition-with-same-name "Link for this heading")

This error occurs when two `<ViewTransition>` components with the same `name` are mounted at the same time:

```
function Item() {

  // 🚩 All items will get the same "name".

  return <ViewTransition name="item">...</ViewTransition>;

}



function ItemList({items}) {

  return (

    <>

      {items.map((item) => (

        <Item key={item.id} />

      ))}

    </>

  );

}
```

This will cause the View Transition to error. In development, React detects this issue to surface it and logs two errors:

Console

There are two `<ViewTransition name=%s>` components with the same name mounted at the same time. This is not supported and will cause View Transitions to error. Try to use a more unique name e.g. by using a namespace prefix and adding the id of an item to the name. at Item at ItemList

The existing `<ViewTransition name=%s>` duplicate has this stack trace. at Item at ItemList

To fix, ensure that there’s only one `<ViewTransition>` with the same name mounted at a time in the entire app by ensuring the `name` is unique, or adding an `id` to the name:

```
function Item({id}) {

  // ✅ All items will get a unique name.

  return <ViewTransition name={`item-${id}`}>...</ViewTransition>;

}



function ItemList({items}) {

  return (

    <>

      {items.map((item) => (

        <Item key={item.id} item={item} />

      ))}

    </>

  );

}
```

[Previous\<Activity>](/reference/react/Activity)

[NextAPIs](/reference/react/apis)

***

----
url: https://18.react.dev/learn/conditional-rendering
----

23

24

25

26

function Item({ name, isPacked }) {

return \<li className="item">{name}\</li>;

}



export default function PackingList() {

return (

\<section>

\<h1>Sally Ride's Packing List\</h1>

\<ul>

\<Item

isPacked={true}

name="Space suit"

/>

\<Item

isPacked={true}

name="Helmet with a golden leaf"

/>

\<Item

isPacked={false}

name="Photo of Tam"

/>

\</ul>

\</section>

);

}



Notice that some of the `Item` components have their `isPacked` prop set to `true` instead of `false`. You want to add a checkmark (✅) to packed items if `isPacked={true}`.

You can write this as an [`if`/`else` statement](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/if...else) like so:

```
if (isPacked) {

  return <li className="item">{name} ✅</li>;

}

return <li className="item">{name}</li>;
```

If the `isPacked` prop is `true`, this code **returns a different JSX tree.** With this change, some of the items get a checkmark at the end:

```
function Item({ name, isPacked }) {
  if (isPacked) {
    return <li className="item">{name} ✅</li>;
  }
  return <li className="item">{name}</li>;
}

export default function PackingList() {
  return (
    <section>
      <h1>Sally Ride's Packing List</h1>
      <ul>
        <Item 
          isPacked={true} 
          name="Space suit" 
        />
        <Item 
          isPacked={true} 
          name="Helmet with a golden leaf" 
        />
        <Item 
          isPacked={false} 
          name="Photo of Tam" 
        />
      </ul>
    </section>
  );
}
```

Try editing what gets returned in either case, and see how the result changes!

Notice how you’re creating branching logic with JavaScript’s `if` and `return` statements. In React, control flow (like conditions) is handled by JavaScript.

### Conditionally returning nothing with `null`[](#conditionally-returning-nothing-with-null "Link for this heading")

In some situations, you won’t want to render anything at all. For example, say you don’t want to show packed items at all. A component must return something. In this case, you can return `null`:

```
if (isPacked) {

  return null;

}

return <li className="item">{name}</li>;
```

If `isPacked` is true, the component will return nothing, `null`. Otherwise, it will return JSX to render.

```
function Item({ name, isPacked }) {
  if (isPacked) {
    return null;
  }
  return <li className="item">{name}</li>;
}

export default function PackingList() {
  return (
    <section>
      <h1>Sally Ride's Packing List</h1>
      <ul>
        <Item 
          isPacked={true} 
          name="Space suit" 
        />
        <Item 
          isPacked={true} 
          name="Helmet with a golden leaf" 
        />
        <Item 
          isPacked={false} 
          name="Photo of Tam" 
        />
      </ul>
    </section>
  );
}
```

In practice, returning `null` from a component isn’t common because it might surprise a developer trying to render it. More often, you would conditionally include or exclude the component in the parent component’s JSX. Here’s how to do that!

## Conditionally including JSX[](#conditionally-including-jsx "Link for Conditionally including JSX ")

In the previous example, you controlled which (if any!) JSX tree would be returned by the component. You may already have noticed some duplication in the render output:

```
<li className="item">{name} ✅</li>
```

is very similar to

```
<li className="item">{name}</li>
```

Both of the conditional branches return `<li className="item">...</li>`:

```
if (isPacked) {

  return <li className="item">{name} ✅</li>;

}

return <li className="item">{name}</li>;
```

While this duplication isn’t harmful, it could make your code harder to maintain. What if you want to change the `className`? You’d have to do it in two places in your code! In such a situation, you could conditionally include a little JSX to make your code more [DRY.](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself)

### Conditional (ternary) operator (`? :`)[](#conditional-ternary-operator-- "Link for this heading")

JavaScript has a compact syntax for writing a conditional expression — the [conditional operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator) or “ternary operator”.

Instead of this:

```
if (isPacked) {

  return <li className="item">{name} ✅</li>;

}

return <li className="item">{name}</li>;
```

You can write this:

```
return (

  <li className="item">

    {isPacked ? name + ' ✅' : name}

  </li>

);
```

You can read it as *“if `isPacked` is true, then (`?`) render `name + ' ✅'`, otherwise (`:`) render `name`”*.

##### Deep Dive#### Are these two examples fully equivalent?[](#are-these-two-examples-fully-equivalent "Link for Are these two examples fully equivalent? ")

If you’re coming from an object-oriented programming background, you might assume that the two examples above are subtly different because one of them may create two different “instances” of `<li>`. But JSX elements aren’t “instances” because they don’t hold any internal state and aren’t real DOM nodes. They’re lightweight descriptions, like blueprints. So these two examples, in fact, *are* completely equivalent. [Preserving and Resetting State](/learn/preserving-and-resetting-state) goes into detail about how this works.

Now let’s say you want to wrap the completed item’s text into another HTML tag, like `<del>` to strike it out. You can add even more newlines and parentheses so that it’s easier to nest more JSX in each of the cases:

```
function Item({ name, isPacked }) {
  return (
    <li className="item">
      {isPacked ? (
        <del>
          {name + ' ✅'}
        </del>
      ) : (
        name
      )}
    </li>
  );
}

export default function PackingList() {
  return (
    <section>
      <h1>Sally Ride's Packing List</h1>
      <ul>
        <Item 
          isPacked={true} 
          name="Space suit" 
        />
        <Item 
          isPacked={true} 
          name="Helmet with a golden leaf" 
        />
        <Item 
          isPacked={false} 
          name="Photo of Tam" 
        />
      </ul>
    </section>
  );
}
```

This style works well for simple conditions, but use it in moderation. If your components get messy with too much nested conditional markup, consider extracting child components to clean things up. In React, markup is a part of your code, so you can use tools like variables and functions to tidy up complex expressions.

### Logical AND operator (`&&`)[](#logical-and-operator- "Link for this heading")

Another common shortcut you’ll encounter is the [JavaScript logical AND (`&&`) operator.](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_AND#:~:text=The%20logical%20AND%20\(%20%26%26%20\)%20operator,it%20returns%20a%20Boolean%20value.) Inside React components, it often comes up when you want to render some JSX when the condition is true, **or render nothing otherwise.** With `&&`, you could conditionally render the checkmark only if `isPacked` is `true`:

```
return (

  <li className="item">

    {name} {isPacked && '✅'}

  </li>

);
```

You can read this as *“if `isPacked`, then (`&&`) render the checkmark, otherwise, render nothing”*.

Here it is in action:

```
function Item({ name, isPacked }) {
  return (
    <li className="item">
      {name} {isPacked && '✅'}
    </li>
  );
}

export default function PackingList() {
  return (
    <section>
      <h1>Sally Ride's Packing List</h1>
      <ul>
        <Item 
          isPacked={true} 
          name="Space suit" 
        />
        <Item 
          isPacked={true} 
          name="Helmet with a golden leaf" 
        />
        <Item 
          isPacked={false} 
          name="Photo of Tam" 
        />
      </ul>
    </section>
  );
}
```

```
let itemContent = name;
```

Use an `if` statement to reassign a JSX expression to `itemContent` if `isPacked` is `true`:

```
if (isPacked) {

  itemContent = name + " ✅";

}
```

[Curly braces open the “window into JavaScript”.](/learn/javascript-in-jsx-with-curly-braces#using-curly-braces-a-window-into-the-javascript-world) Embed the variable with curly braces in the returned JSX tree, nesting the previously calculated expression inside of JSX:

```
<li className="item">

  {itemContent}

</li>
```

This style is the most verbose, but it’s also the most flexible. Here it is in action:

```
function Item({ name, isPacked }) {
  let itemContent = name;
  if (isPacked) {
    itemContent = name + " ✅";
  }
  return (
    <li className="item">
      {itemContent}
    </li>
  );
}

export default function PackingList() {
  return (
    <section>
      <h1>Sally Ride's Packing List</h1>
      <ul>
        <Item 
          isPacked={true} 
          name="Space suit" 
        />
        <Item 
          isPacked={true} 
          name="Helmet with a golden leaf" 
        />
        <Item 
          isPacked={false} 
          name="Photo of Tam" 
        />
      </ul>
    </section>
  );
}
```

Like before, this works not only for text, but for arbitrary JSX too:

```
function Item({ name, isPacked }) {
  let itemContent = name;
  if (isPacked) {
    itemContent = (
      <del>
        {name + " ✅"}
      </del>
    );
  }
  return (
    <li className="item">
      {itemContent}
    </li>
  );
}

export default function PackingList() {
  return (
    <section>
      <h1>Sally Ride's Packing List</h1>
      <ul>
        <Item 
          isPacked={true} 
          name="Space suit" 
        />
        <Item 
          isPacked={true} 
          name="Helmet with a golden leaf" 
        />
        <Item 
          isPacked={false} 
          name="Photo of Tam" 
        />
      </ul>
    </section>
  );
}
```

```
function Item({ name, isPacked }) {
  return (
    <li className="item">
      {name} {isPacked && '✅'}
    </li>
  );
}

export default function PackingList() {
  return (
    <section>
      <h1>Sally Ride's Packing List</h1>
      <ul>
        <Item 
          isPacked={true} 
          name="Space suit" 
        />
        <Item 
          isPacked={true} 
          name="Helmet with a golden leaf" 
        />
        <Item 
          isPacked={false} 
          name="Photo of Tam" 
        />
      </ul>
    </section>
  );
}
```

[PreviousPassing Props to a Component](/learn/passing-props-to-a-component)

[NextRendering Lists](/learn/rendering-lists)

***

----
url: https://legacy.reactjs.org/blog/2015/11/18/react-v0.14.3.html
----

November 18, 2015 by [Paul O’Shannessy](https://twitter.com/zpao)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

It’s time for another installment of React patch releases! We didn’t break anything in v0.14.2 but we do have a couple of other bugs we’re fixing. The biggest change in this release is actually an addition of a new built file. We heard from a number of people that they still need the ability to use React to render to a string on the client. While the use cases are not common and there are other ways to achieve this, we decided that it’s still valuable to support. So we’re now building `react-dom-server.js`, which will be shipped to Bower and in the `dist/` directory of the `react-dom` package on npm. This file works the same way as `react-dom.js` and therefore requires that the primary React build has already been included on the page.

The release is now available for download:

* **React**\
  Dev build with warnings: <https://fb.me/react-0.14.3.js>\
  Minified build for production: <https://fb.me/react-0.14.3.min.js>
* **React with Add-Ons**\
  Dev build with warnings: <https://fb.me/react-with-addons-0.14.3.js>\
  Minified build for production: <https://fb.me/react-with-addons-0.14.3.min.js>
* **React DOM** (include React in the page before React DOM)\
  Dev build with warnings: <https://fb.me/react-dom-0.14.3.js>\
  Minified build for production: <https://fb.me/react-dom-0.14.3.min.js>
* **React DOM Server** (include React in the page before React DOM Server)\
  Dev build with warnings: <https://fb.me/react-dom-server-0.14.3.js>\
  Minified build for production: <https://fb.me/react-dom-server-0.14.3.min.js>

We’ve also published version `0.14.3` of the `react`, `react-dom`, and addons packages on npm and the `react` package on bower.

***

## [](#changelog)Changelog

### [](#react-dom)React DOM

* Added support for `nonce` attribute for `<script>` and `<style>` elements
* Added support for `reversed` attribute for `<ol>` elements

### [](#react-testutils-add-on)React TestUtils Add-on

* Fixed bug with shallow rendering and function refs

### [](#react-csstransitiongroup-add-on)React CSSTransitionGroup Add-on

* Fixed bug resulting in timeouts firing incorrectly when mounting and unmounting rapidly

### [](#react-on-bower)React on Bower

* Added `react-dom-server.js` to expose `renderToString` and `renderToStaticMarkup` for usage in the browser

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2015-11-18-react-v0.14.3.md)

----
url: https://react.dev/community/conferences
----

[Community](/community)

# React Conferences[](#undefined "Link for this heading")

Do you know of a local React.js conference? Add it here! (Please keep the list chronological)

## Upcoming Conferences[](#upcoming-conferences "Link for Upcoming Conferences ")

### React Paris 2026[](#react-paris-2026 "Link for React Paris 2026 ")

March 26 - 27, 2026. In-person in Paris, France (hybrid event)

[Website](https://react.paris/) - [Twitter](https://x.com/BeJS_)

### CityJS London 2026[](#cityjs-london-2026 "Link for CityJS London 2026 ")

April 14-17, 2026. In-person in London

[Website](https://india.cityjsconf.org/) - [Twitter](https://x.com/cityjsconf) - [Bluesky](https://bsky.app/profile/cityjsconf.bsky.social)

### ZurichJS Conf 2026[](#zurichjs-conf-2026 "Link for ZurichJS Conf 2026 ")

September 10-11, 2026. In-person in Zurich, Switzerland

[Website](https://conf.zurichjs.com?utm_campaign=ZurichJS_Conf\&utm_source=referral\&utm_content=reactjs_community_conferences) - [Twitter](https://x.com/zurichjs) - [LinkedIn](https://www.linkedin.com/company/zurichjs/)

### React Conf Japan 2027[](#react-conf-japan-2027 "Link for React Conf Japan 2027 ")

April 24, 2027. In-person in Tokyo, Japan

[Website](https://reactconf.jp/) - [Twitter](https://x.com/reactconfjp)

## Past Conferences[](#past-conferences "Link for Past Conferences ")

### CityJS New Delhi 2026[](#cityjs-newdelhi-2026 "Link for CityJS New Delhi 2026 ")

February 12-13, 2026. In-person in New Delhi, India

[Website](https://india.cityjsconf.org/) - [Twitter](https://x.com/cityjsconf) - [Bluesky](https://bsky.app/profile/cityjsconf.bsky.social)

### CityJS Singapore 2026[](#cityjs-singapore-2026 "Link for CityJS Singapore 2026 ")

February 4-6, 2026. In-person in Singapore

[Website](https://india.cityjsconf.org/) - [Twitter](https://x.com/cityjsconf) - [Bluesky](https://bsky.app/profile/cityjsconf.bsky.social)

### React Advanced London 2025[](#react-advanced-london-2025 "Link for React Advanced London 2025 ")

November 28 & December 1, 2025. In-person in London, UK + online (hybrid event)

[Website](https://reactadvanced.com/) - [Twitter](https://x.com/reactadvanced)

### React Summit US 2025[](#react-summit-us-2025 "Link for React Summit US 2025 ")

November 18 - 21, 2025. In-person in New York, USA + remote (hybrid event)

[Website](https://reactsummit.us/) - [Twitter](https://x.com/reactsummit)

### React India 2025[](#react-india-2025 "Link for React India 2025 ")

October 31 - November 01, 2025. In-person in Goa, India (hybrid event) + Oct 15 2025 - remote day

[Website](https://www.reactindia.io) - [Twitter](https://twitter.com/react_india) - [Facebook](https://www.facebook.com/ReactJSIndia) - [Youtube](https://www.youtube.com/channel/UCaFbHCBkPvVv1bWs_jwYt3w)

### React Conf 2025[](#react-conf-2025 "Link for React Conf 2025 ")

October 7-8, 2025. Henderson, Nevada, USA and free livestream

[Website](https://conf.react.dev/) - [Twitter](https://x.com/reactjs) - [Bluesky](https://bsky.app/profile/react.dev)

### RenderCon Kenya 2025[](#rendercon-kenya-2025 "Link for RenderCon Kenya 2025 ")

October 04, 2025. Nairobi, Kenya

[Website](https://rendercon.org/) - [Twitter](https://twitter.com/renderconke) - [LinkedIn](https://www.linkedin.com/company/renderconke/) - [YouTube](https://www.youtube.com/channel/UC0bCcG8gHUL4njDOpQGcMIA)

### React Alicante 2025[](#react-alicante-2025 "Link for React Alicante 2025 ")

October 2-4, 2025. Alicante, Spain.

[Website](https://reactalicante.es/) - [Twitter](https://x.com/ReactAlicante) - [Bluesky](https://bsky.app/profile/reactalicante.es) - [YouTube](https://www.youtube.com/channel/UCaSdUaITU1Cz6PvC97A7e0w)

### React Universe Conf 2025[](#react-universe-conf-2025 "Link for React Universe Conf 2025 ")

September 2-4, 2025. Wrocław, Poland.

[Website](https://www.reactuniverseconf.com/) - [Twitter](https://twitter.com/react_native_eu) - [LinkedIn](https://www.linkedin.com/events/reactuniverseconf7163919537074118657/)

### React Nexus 2025[](#react-nexus-2025 "Link for React Nexus 2025 ")

July 03 - 05, 2025. In-person in Bangalore, India

[Website](https://reactnexus.com/) - [Twitter](https://x.com/ReactNexus) - [Bluesky](https://bsky.app/profile/reactnexus.com) - [Linkedin](https://www.linkedin.com/company/react-nexus) - [YouTube](https://www.youtube.com/reactify_in)

### React Summit 2025[](#react-summit-2025 "Link for React Summit 2025 ")

June 13 - 17, 2025. In-person in Amsterdam, Netherlands + remote (hybrid event)

[Website](https://reactsummit.com/) - [Twitter](https://x.com/reactsummit)

### React Norway 2025[](#react-norway-2025 "Link for React Norway 2025 ")

June 13, 2025. In-person in Oslo, Norway + remote (virtual event)

[Website](https://reactnorway.com/) - [Twitter](https://x.com/ReactNorway)

### CityJS Athens 2025[](#cityjs-athens "Link for CityJS Athens 2025 ")

May 27 - 31, 2025. In-person in Athens, Greece

[Website](https://athens.cityjsconf.org/) - [Twitter](https://x.com/cityjsconf) - [Bluesky](https://bsky.app/profile/cityjsconf.bsky.social)

### App.js Conf 2025[](#appjs-conf-2025 "Link for App.js Conf 2025 ")

May 28 - 30, 2025. In-person in Kraków, Poland + remote

[Website](https://appjs.co) - [Twitter](https://twitter.com/appjsconf)

### CityJS London 2025[](#cityjs-london "Link for CityJS London 2025 ")

April 23 - 25, 2025. In-person in London, UK

[Website](https://london.cityjsconf.org/) - [Twitter](https://x.com/cityjsconf) - [Bluesky](https://bsky.app/profile/cityjsconf.bsky.social)

### React Paris 2025[](#react-paris-2025 "Link for React Paris 2025 ")

March 20 - 21, 2025. In-person in Paris, France (hybrid event)

[Website](https://react.paris/) - [Twitter](https://x.com/BeJS_) - [YouTube](https://www.youtube.com/playlist?list=PL53Z0yyYnpWitP8Zv01TSEQmKLvuRh_Dj)

### React Native Connection 2025[](#react-native-connection-2025 "Link for React Native Connection 2025 ")

April 3 (Reanimated Training) + April 4 (Conference), 2025. Paris, France.

[Website](https://reactnativeconnection.io/) - [X](https://x.com/reactnativeconn) - [Bluesky](https://bsky.app/profile/reactnativeconnect.bsky.social)

### React Day Berlin 2024[](#react-day-berlin-2024 "Link for React Day Berlin 2024 ")

December 13 & 16, 2024. In-person in Berlin, Germany + remote (hybrid event)

[Website](https://reactday.berlin/) - [Twitter](https://x.com/reactdayberlin)

### React Africa 2024[](#react-africa-2024 "Link for React Africa 2024 ")

November 29, 2024. In-person in Casablanca, Morocco (hybrid event)

[Website](https://react-africa.com/) - [Twitter](https://x.com/BeJS_)

### React Summit US 2024[](#react-summit-us-2024 "Link for React Summit US 2024 ")

November 19 & 22, 2024. In-person in New York, USA + online (hybrid event)

[Website](https://reactsummit.us/) - [Twitter](https://twitter.com/reactsummit) - [Videos](https://portal.gitnation.org/)

### React Native London Conf 2024[](#react-native-london-2024 "Link for React Native London Conf 2024 ")

November 14 & 15, 2024. In-person in London, UK

[Website](https://reactnativelondon.co.uk/) - [Twitter](https://x.com/RNLConf)

### React Advanced London 2024[](#react-advanced-london-2024 "Link for React Advanced London 2024 ")

October 25 & 28, 2024. In-person in London, UK + online (hybrid event)

[Website](https://reactadvanced.com/) - [Twitter](https://x.com/reactadvanced)

### reactjsday 2024[](#reactjsday-2024 "Link for reactjsday 2024 ")

October 25, 2024. In-person in Verona, Italy + online (hybrid event)

[Website](https://2024.reactjsday.it/) - [Twitter](https://x.com/reactjsday) - [Facebook](https://www.facebook.com/GrUSP/) - [YouTube](https://www.youtube.com/c/grusp)

### React Brussels 2024[](#react-brussels-2024 "Link for React Brussels 2024 ")

October 18, 2024. In-person in Brussels, Belgium (hybrid event)

[Website](https://www.react.brussels/) - [Twitter](https://x.com/BrusselsReact) - [YouTube](https://www.youtube.com/playlist?list=PL53Z0yyYnpWimQ0U75woee2zNUIFsiDC3)

### React India 2024[](#react-india-2024 "Link for React India 2024 ")

October 17 - 19, 2024. In-person in Goa, India (hybrid event) + Oct 15 2024 - remote day

[Website](https://www.reactindia.io) - [Twitter](https://twitter.com/react_india) - [Facebook](https://www.facebook.com/ReactJSIndia) - [Youtube](https://www.youtube.com/channel/UCaFbHCBkPvVv1bWs_jwYt3w)

### RenderCon Kenya 2024[](#rendercon-kenya-2024 "Link for RenderCon Kenya 2024 ")

October 04 - 05, 2024. Nairobi, Kenya

[Website](https://rendercon.org/) - [Twitter](https://twitter.com/renderconke) - [LinkedIn](https://www.linkedin.com/company/renderconke/) - [YouTube](https://www.youtube.com/channel/UC0bCcG8gHUL4njDOpQGcMIA)

### React Alicante 2024[](#react-alicante-2024 "Link for React Alicante 2024 ")

September 19-21, 2024. Alicante, Spain.

[Website](https://reactalicante.es/) - [Twitter](https://twitter.com/ReactAlicante) - [YouTube](https://www.youtube.com/channel/UCaSdUaITU1Cz6PvC97A7e0w)

### React Universe Conf 2024[](#react-universe-conf-2024 "Link for React Universe Conf 2024 ")

September 5-6, 2024. Wrocław, Poland.

[Website](https://www.reactuniverseconf.com/) - [Twitter](https://twitter.com/react_native_eu) - [LinkedIn](https://www.linkedin.com/events/reactuniverseconf7163919537074118657/)

***

----
url: https://18.react.dev/reference/react/Profiler
----

[API Reference](/reference/react)

[Components](/reference/react/components)

# \<Profiler>[](#undefined "Link for this heading")

`<Profiler>` lets you measure rendering performance of a React tree programmatically.

```
<Profiler id="App" onRender={onRender}>

  <App />

</Profiler>
```

* [Reference](#reference)

  * [`<Profiler>`](#profiler)
  * [`onRender` callback](#onrender-callback)

* [Usage](#usage)

  * [Measuring rendering performance programmatically](#measuring-rendering-performance-programmatically)
  * [Measuring different parts of the application](#measuring-different-parts-of-the-application)

***

## Reference[](#reference "Link for Reference ")

### `<Profiler>`[](#profiler "Link for this heading")

Wrap a component tree in a `<Profiler>` to measure its rendering performance.

```
<Profiler id="App" onRender={onRender}>

  <App />

</Profiler>
```

#### Props[](#props "Link for Props ")

* `id`: A string identifying the part of the UI you are measuring.
* `onRender`: An [`onRender` callback](#onrender-callback) that React calls every time components within the profiled tree update. It receives information about what was rendered and how much time it took.

#### Caveats[](#caveats "Link for Caveats ")

* Profiling adds some additional overhead, so **it is disabled in the production build by default.** To opt into production profiling, you need to enable a [special production build with profiling enabled.](https://fb.me/react-profiling)

***

### `onRender` callback[](#onrender-callback "Link for this heading")

React will call your `onRender` callback with information about what was rendered.

```
function onRender(id, phase, actualDuration, baseDuration, startTime, commitTime) {

  // Aggregate or log render timings...

}
```

***

## Usage[](#usage "Link for Usage ")

### Measuring rendering performance programmatically[](#measuring-rendering-performance-programmatically "Link for Measuring rendering performance programmatically ")

Wrap the `<Profiler>` component around a React tree to measure its rendering performance.

```
<App>

  <Profiler id="Sidebar" onRender={onRender}>

    <Sidebar />

  </Profiler>

  <PageContent />

</App>
```

It requires two props: an `id` (string) and an `onRender` callback (function) which React calls any time a component within the tree “commits” an update.

### Pitfall

Profiling adds some additional overhead, so **it is disabled in the production build by default.** To opt into production profiling, you need to enable a [special production build with profiling enabled.](https://fb.me/react-profiling)

### Note

`<Profiler>` lets you gather measurements programmatically. If you’re looking for an interactive profiler, try the Profiler tab in [React Developer Tools](/learn/react-developer-tools). It exposes similar functionality as a browser extension.

***

### Measuring different parts of the application[](#measuring-different-parts-of-the-application "Link for Measuring different parts of the application ")

You can use multiple `<Profiler>` components to measure different parts of your application:

```
<App>

  <Profiler id="Sidebar" onRender={onRender}>

    <Sidebar />

  </Profiler>

  <Profiler id="Content" onRender={onRender}>

    <Content />

  </Profiler>

</App>
```

You can also nest `<Profiler>` components:

```
<App>

  <Profiler id="Sidebar" onRender={onRender}>

    <Sidebar />

  </Profiler>

  <Profiler id="Content" onRender={onRender}>

    <Content>

      <Profiler id="Editor" onRender={onRender}>

        <Editor />

      </Profiler>

      <Preview />

    </Content>

  </Profiler>

</App>
```

Although `<Profiler>` is a lightweight component, it should be used only when necessary. Each use adds some CPU and memory overhead to an application.

***

[Previous\<Fragment> (<>)](/reference/react/Fragment)

[Next\<StrictMode>](/reference/react/StrictMode)

***

----
url: https://18.react.dev/learn/referencing-values-with-refs
----

```
import { useRef } from 'react';
```

Inside your component, call the `useRef` Hook and pass the initial value that you want to reference as the only argument. For example, here is a ref to the value `0`:

```
const ref = useRef(0);
```

`useRef` returns an object like this:

```
{ 

  current: 0 // The value you passed to useRef

}
```

Illustrated by [Rachel Lee Nabors](https://nearestnabors.com/)

You can access the current value of that ref through the `ref.current` property. This value is intentionally mutable, meaning you can both read and write to it. It’s like a secret pocket of your component that React doesn’t track. (This is what makes it an “escape hatch” from React’s one-way data flow—more on that below!)

Here, a button will increment `ref.current` on every click:

```
import { useRef } from 'react';

export default function Counter() {
  let ref = useRef(0);

  function handleClick() {
    ref.current = ref.current + 1;
    alert('You clicked ' + ref.current + ' times!');
  }

  return (
    <button onClick={handleClick}>
      Click me!
    </button>
  );
}
```

The ref points to a number, but, like [state](/learn/state-a-components-memory), you could point to anything: a string, an object, or even a function. Unlike state, ref is a plain JavaScript object with the `current` property that you can read and modify.

Note that **the component doesn’t re-render with every increment.** Like state, refs are retained by React between re-renders. However, setting state re-renders a component. Changing a ref does not!

## Example: building a stopwatch[](#example-building-a-stopwatch "Link for Example: building a stopwatch ")

You can combine refs and state in a single component. For example, let’s make a stopwatch that the user can start or stop by pressing a button. In order to display how much time has passed since the user pressed “Start”, you will need to keep track of when the Start button was pressed and what the current time is. **This information is used for rendering, so you’ll keep it in state:**

```
const [startTime, setStartTime] = useState(null);

const [now, setNow] = useState(null);
```

When the user presses “Start”, you’ll use [`setInterval`](https://developer.mozilla.org/docs/Web/API/setInterval) in order to update the time every 10 milliseconds:

```
import { useState } from 'react';

export default function Stopwatch() {
  const [startTime, setStartTime] = useState(null);
  const [now, setNow] = useState(null);

  function handleStart() {
    // Start counting.
    setStartTime(Date.now());
    setNow(Date.now());

    setInterval(() => {
      // Update the current time every 10ms.
      setNow(Date.now());
    }, 10);
  }

  let secondsPassed = 0;
  if (startTime != null && now != null) {
    secondsPassed = (now - startTime) / 1000;
  }

  return (
    <>
      <h1>Time passed: {secondsPassed.toFixed(3)}</h1>
      <button onClick={handleStart}>
        Start
      </button>
    </>
  );
}
```

When the “Stop” button is pressed, you need to cancel the existing interval so that it stops updating the `now` state variable. You can do this by calling [`clearInterval`](https://developer.mozilla.org/en-US/docs/Web/API/clearInterval), but you need to give it the interval ID that was previously returned by the `setInterval` call when the user pressed Start. You need to keep the interval ID somewhere. **Since the interval ID is not used for rendering, you can keep it in a ref:**

```
import { useState, useRef } from 'react';

export default function Stopwatch() {
  const [startTime, setStartTime] = useState(null);
  const [now, setNow] = useState(null);
  const intervalRef = useRef(null);

  function handleStart() {
    setStartTime(Date.now());
    setNow(Date.now());

    clearInterval(intervalRef.current);
    intervalRef.current = setInterval(() => {
      setNow(Date.now());
    }, 10);
  }

  function handleStop() {
    clearInterval(intervalRef.current);
  }

  let secondsPassed = 0;
  if (startTime != null && now != null) {
    secondsPassed = (now - startTime) / 1000;
  }

  return (
    <>
      <h1>Time passed: {secondsPassed.toFixed(3)}</h1>
      <button onClick={handleStart}>
        Start
      </button>
      <button onClick={handleStop}>
        Stop
      </button>
    </>
  );
}
```

When a piece of information is used for rendering, keep it in state. When a piece of information is only needed by event handlers and changing it doesn’t require a re-render, using a ref may be more efficient.

## Differences between refs and state[](#differences-between-refs-and-state "Link for Differences between refs and state ")

Perhaps you’re thinking refs seem less “strict” than state—you can mutate them instead of always having to use a state setting function, for instance. But in most cases, you’ll want to use state. Refs are an “escape hatch” you won’t need often. Here’s how state and refs compare:

| refs                                                                                  | state                                                                                                                                   |
| ------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| `useRef(initialValue)` returns `{ current: initialValue }`                            | `useState(initialValue)` returns the current value of a state variable and a state setter function ( `[value, setValue]`)               |
| Doesn’t trigger re-render when you change it.                                         | Triggers re-render when you change it.                                                                                                  |
| Mutable—you can modify and update `current`’s value outside of the rendering process. | ”Immutable”—you must use the state setting function to modify state variables to queue a re-render.                                     |
| You shouldn’t read (or write) the `current` value during rendering.                   | You can read state at any time. However, each render has its own [snapshot](/learn/state-as-a-snapshot) of state which does not change. |

Here is a counter button that’s implemented with state:

```
import { useState } from 'react';

export default function Counter() {
  const [count, setCount] = useState(0);

  function handleClick() {
    setCount(count + 1);
  }

  return (
    <button onClick={handleClick}>
      You clicked {count} times
    </button>
  );
}
```

Because the `count` value is displayed, it makes sense to use a state value for it. When the counter’s value is set with `setCount()`, React re-renders the component and the screen updates to reflect the new count.

If you tried to implement this with a ref, React would never re-render the component, so you’d never see the count change! See how clicking this button **does not update its text**:

```
import { useRef } from 'react';

export default function Counter() {
  let countRef = useRef(0);

  function handleClick() {
    // This doesn't re-render the component!
    countRef.current = countRef.current + 1;
  }

  return (
    <button onClick={handleClick}>
      You clicked {countRef.current} times
    </button>
  );
}
```

This is why reading `ref.current` during render leads to unreliable code. If you need that, use state instead.

##### Deep Dive#### How does useRef work inside?[](#how-does-use-ref-work-inside "Link for How does useRef work inside? ")

Although both `useState` and `useRef` are provided by React, in principle `useRef` could be implemented *on top of* `useState`. You can imagine that inside of React, `useRef` is implemented like this:

```
// Inside of React

function useRef(initialValue) {

  const [ref, unused] = useState({ current: initialValue });

  return ref;

}
```

```
ref.current = 5;

console.log(ref.current); // 5
```

```
import { useState } from 'react';

export default function Chat() {
  const [text, setText] = useState('');
  const [isSending, setIsSending] = useState(false);
  let timeoutID = null;

  function handleSend() {
    setIsSending(true);
    timeoutID = setTimeout(() => {
      alert('Sent!');
      setIsSending(false);
    }, 3000);
  }

  function handleUndo() {
    setIsSending(false);
    clearTimeout(timeoutID);
  }

  return (
    <>
      <input
        disabled={isSending}
        value={text}
        onChange={e => setText(e.target.value)}
      />
      <button
        disabled={isSending}
        onClick={handleSend}>
        {isSending ? 'Sending...' : 'Send'}
      </button>
      {isSending &&
        <button onClick={handleUndo}>
          Undo
        </button>
      }
    </>
  );
}
```

[PreviousEscape Hatches](/learn/escape-hatches)

[NextManipulating the DOM with Refs](/learn/manipulating-the-dom-with-refs)

***

----
url: https://18.react.dev/learn/editor-setup
----

[Learn React](/learn)

[Installation](/learn/installation)

> If your ESLint preset has formatting rules, they may conflict with Prettier. We recommend disabling all formatting rules in your ESLint preset using [`eslint-config-prettier`](https://github.com/prettier/eslint-config-prettier) so that ESLint is *only* used for catching logical mistakes. If you want to enforce that files are formatted before a pull request is merged, use [`prettier --check`](https://prettier.io/docs/en/cli.html#--check) for your continuous integration.

[PreviousAdd React to an Existing Project](/learn/add-react-to-an-existing-project)

[NextUsing TypeScript](/learn/typescript)

***

----
url: https://legacy.reactjs.org/docs/hooks-rules.html
----

> These docs are old and won’t be updated. Go to [react.dev](https://react.dev/) for the new React docs.
>
> These new documentation pages teach modern React and include live examples:
>
> * [Rules of Hooks](https://react.dev/reference/rules/rules-of-hooks)
> * [Components and Hooks must be pure](https://react.dev/reference/rules/components-and-hooks-must-be-pure)
> * [React calls Components and Hooks](https://react.dev/reference/rules/react-calls-components-and-hooks)

*Hooks* are a new addition in React 16.8. They let you use state and other React features without writing a class.

Hooks are JavaScript functions, but you need to follow two rules when using them. We provide a [linter plugin](https://www.npmjs.com/package/eslint-plugin-react-hooks) to enforce these rules automatically:

### [](#only-call-hooks-at-the-top-level)Only Call Hooks at the Top Level

**Don’t call Hooks inside loops, conditions, or nested functions.** Instead, always use Hooks at the top level of your React function, before any early returns. By following this rule, you ensure that Hooks are called in the same order each time a component renders. That’s what allows React to correctly preserve the state of Hooks between multiple `useState` and `useEffect` calls. (If you’re curious, we’ll explain this in depth [below](#explanation).)

### [](#only-call-hooks-from-react-functions)Only Call Hooks from React Functions

**Don’t call Hooks from regular JavaScript functions.** Instead, you can:

* ✅ Call Hooks from React function components.
* ✅ Call Hooks from custom Hooks (we’ll learn about them [on the next page](/docs/hooks-custom.html)).

By following this rule, you ensure that all stateful logic in a component is clearly visible from its source code.

## [](#eslint-plugin)ESLint Plugin

We released an ESLint plugin called [`eslint-plugin-react-hooks`](https://www.npmjs.com/package/eslint-plugin-react-hooks) that enforces these two rules. You can add this plugin to your project if you’d like to try it:

This plugin is included by default in [Create React App](/docs/create-a-new-react-app.html#create-react-app).

```
npm install eslint-plugin-react-hooks --save-dev
```

```
// Your ESLint configuration
{
  "plugins": [
    // ...
    "react-hooks"
  ],
  "rules": {
    // ...
    "react-hooks/rules-of-hooks": "error", // Checks rules of Hooks
    "react-hooks/exhaustive-deps": "warn" // Checks effect dependencies
  }
}
```

**You can skip to the next page explaining how to write [your own Hooks](/docs/hooks-custom.html) now.** On this page, we’ll continue by explaining the reasoning behind these rules.

## [](#explanation)Explanation

As we [learned earlier](/docs/hooks-state.html#tip-using-multiple-state-variables), we can use multiple State or Effect Hooks in a single component:

```
function Form() {
  // 1. Use the name state variable
  const [name, setName] = useState('Mary');

  // 2. Use an effect for persisting the form
  useEffect(function persistForm() {
    localStorage.setItem('formData', name);
  });

  // 3. Use the surname state variable
  const [surname, setSurname] = useState('Poppins');

  // 4. Use an effect for updating the title
  useEffect(function updateTitle() {
    document.title = name + ' ' + surname;
  });

  // ...
}
```

So how does React know which state corresponds to which `useState` call? The answer is that **React relies on the order in which Hooks are called**. Our example works because the order of the Hook calls is the same on every render:

```
// ------------
// First render
// ------------
useState('Mary')           // 1. Initialize the name state variable with 'Mary'
useEffect(persistForm)     // 2. Add an effect for persisting the form
useState('Poppins')        // 3. Initialize the surname state variable with 'Poppins'
useEffect(updateTitle)     // 4. Add an effect for updating the title

// -------------
// Second render
// -------------
useState('Mary')           // 1. Read the name state variable (argument is ignored)
useEffect(persistForm)     // 2. Replace the effect for persisting the form
useState('Poppins')        // 3. Read the surname state variable (argument is ignored)
useEffect(updateTitle)     // 4. Replace the effect for updating the title

// ...
```

As long as the order of the Hook calls is the same between renders, React can associate some local state with each of them. But what happens if we put a Hook call (for example, the `persistForm` effect) inside a condition?

```
  // 🔴 We're breaking the first rule by using a Hook in a condition
  if (name !== '') {
    useEffect(function persistForm() {
      localStorage.setItem('formData', name);
    });
  }
```

The `name !== ''` condition is `true` on the first render, so we run this Hook. However, on the next render the user might clear the form, making the condition `false`. Now that we skip this Hook during rendering, the order of the Hook calls becomes different:

```
useState('Mary')           // 1. Read the name state variable (argument is ignored)
// useEffect(persistForm)  // 🔴 This Hook was skipped!
useState('Poppins')        // 🔴 2 (but was 3). Fail to read the surname state variable
useEffect(updateTitle)     // 🔴 3 (but was 4). Fail to replace the effect
```

React wouldn’t know what to return for the second `useState` Hook call. React expected that the second Hook call in this component corresponds to the `persistForm` effect, just like during the previous render, but it doesn’t anymore. From that point, every next Hook call after the one we skipped would also shift by one, leading to bugs.

**This is why Hooks must be called on the top level of our components.** If we want to run an effect conditionally, we can put that condition *inside* our Hook:

```
  useEffect(function persistForm() {
    // 👍 We're not breaking the first rule anymore
    if (name !== '') {
      localStorage.setItem('formData', name);
    }
  });
```

**Note that you don’t need to worry about this problem if you use the [provided lint rule](https://www.npmjs.com/package/eslint-plugin-react-hooks).** But now you also know *why* Hooks work this way, and which issues the rule is preventing.

## [](#next-steps)Next Steps

Finally, we’re ready to learn about [writing your own Hooks](/docs/hooks-custom.html)! Custom Hooks let you combine Hooks provided by React into your own abstractions, and reuse common stateful logic between different components.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/hooks-rules.md)

* Previous article

  [Using the Effect Hook](/docs/hooks-effect.html)

* Next article

  [Building Your Own Hooks](/docs/hooks-custom.html)

----
url: https://legacy.reactjs.org/blog/2015/09/14/community-roundup-27.html
----

September 14, 2015 by [Steven Luscher](https://twitter.com/steveluscher)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

In the weeks following the [open-source release](/blog/2015/08/11/relay-technical-preview.html) of the Relay technical preview, the community has been abuzz with activity. We are honored to have been able to enjoy a steady stream of ideas and contributions from such a talented group of individuals. Let’s take a look at some of the things we’ve achieved, together!

## [](#teaching-servers-to-speak-graphql)Teaching servers to speak GraphQL

Every great Relay app starts by finding a GraphQL server to talk to. The community has spent the past few weeks teaching GraphQL to a few backend systems.

Bryan Goldstein ([brysgo](https://github.com/brysgo)) has built a tool to help you define a GraphQL schema that wraps a set of [Bookshelf.JS](http://bookshelfjs.org/) models. Check out [graphql-bookshelf](https://github.com/brysgo/graphql-bookshelf).

RisingStack ([risingstack](https://github.com/risingstack)) created a GraphQL ORM called [graffiti](https://github.com/RisingStack/graffiti) that you can plug into [mongoose](http://mongoosejs.com/) and serve using Express, Hapi, or Koa.

David Mongeau-Petitpas ([dmongeau](https://github.com/dmongeau)) is working on a way to vend your Laravel models through a GraphQL endpoint, [laravel-graphql](https://github.com/Folkloreatelier/laravel-graphql).

Gerald Monaco ([devknoll](https://github.com/devknoll)) created [graphql-schema](https://github.com/devknoll/graphql-schema) to allow the creation of JavaScript GraphQL schemas using a fluent/chainable interface.

Jason Dusek ([solidsnack](https://github.com/solidsnack)) dove deep into PostgreSQL to teach it how to respond to GraphQL query strings as though they were SQL queries. Check out [GraphpostgresQL](https://github.com/solidsnack/GraphpostgresQL).

Espen Hovlandsdal ([rexxars](https://github.com/rexxars)) built a [sql-to-graphql](https://github.com/vaffel/sql-to-graphql) tool that can perform introspection on the tables of a MySQL or PostgreSQL database, and produce a queryable HTTP GraphQL endpoint out of it.

Mick Hansen ([mickhansen](https://github.com/mickhansen)) offers a set of [schema-building helpers](https://github.com/mickhansen/graphql-sequelize) for use with the [Sequelize ORM](http://docs.sequelizejs.com/en/latest/) for MySQL, PostgreSQL, SQLite, and MSSQL.

## [](#graphql-beyond-javascript)GraphQL beyond JavaScript

Robert Mosolgo ([rmosolgo](https://github.com/rmosolgo)) brought the full set of schema-building and query execution tools to Ruby, in the form of [graphql-ruby](https://github.com/rmosolgo/graphql-ruby) and [graphql-relay-ruby](https://github.com/rmosolgo/graphql-relay-ruby). Check out his [Rails-based demo](https://github.com/rmosolgo/graphql-ruby-demo).

Andreas Marek ([andimarek](https://github.com/andimarek)) has brewed up a Java implementation of GraphQL, [graphql-java](https://github.com/andimarek/graphql-java).

[vladar](https://github.com/vladar) is hard at work on a PHP port of the GraphQL reference implementation, [graphql-php](https://github.com/webonyx/graphql-php).

Taeho Kim ([dittos](https://github.com/dittos)) is bringing GraphQL to Python, with [graphql-py](https://github.com/dittos/graphql-py).

Oleg Ilyenko ([OlegIlyenko](https://github.com/OlegIlyenko)) made a beautiful and [delicious-looking website](http://sangria-graphql.org/) for a Scala implementation of GraphQL, [sangria](https://github.com/sangria-graphql/sangria).

Joe McBride ([joemcbride](https://github.com/joemcbride)) has an up-and-running example of GraphQL for .NET, [graphql-dotnet](https://github.com/joemcbride/graphql-dotnet).

## [](#show-me-dont-tell-me)Show me, don’t tell me

Interact with this [visual tour of Relay’s architecture](http://sgwilym.github.io/relay-visual-learners/) by Sam Gwilym ([sgwilym](https://github.com/sgwilym)).

[](http://sgwilym.github.io/relay-visual-learners/)

Sam has already launched a product that leverages Relay’s data-fetching, optimistic responses, pagination, and mutations – all atop a Ruby GraphQL server: [new.comique.co](http://new.comique.co/)

## [](#skeletons-in-the-closet)Skeletons in the closet

Joseph Rollins ([fortruce](https://github.com/fortruce)) created a hot-reloading, auto schema-regenerating, [Relay skeleton](https://github.com/fortruce/relay-skeleton) that you can use to get up and running quickly.

Michael Hart ([mhart](https://mhart)) built a [simple-relay-starter](https://github.com/mhart/simple-relay-starter) kit using Browserify.

## [](#routing-around)Routing around

Jimmy Jia ([taion](@taion)) and Gerald Monaco ([devknoll](@devknoll)) have been helping lost URLs find their way to Relay apps through their work on [react-router-relay](relay-tools/react-router-relay). Check out Christoph Nakazawa’s ([cpojer](@cpojer)) [blog post](medium.com/@cpojer/relay-and-routing-36b5439bad9) on the topic. Jimmy completed the Relay TodoMVC example with routing, which you can check out at [taion/relay-todomvc](taion/relay-todomvc).

Chen Hung-Tu ([transedward](https://github.com/transedward)) built a chat app atop the above mentioned router, with threaded conversations and pagination. Check it out at [transedward/relay-chat](https://github.com/transedward/relay-chat).

## [](#in-your-words)In your words

> Relay making good on its promise to be the "React.js of data fetching". Rebuilding small app with it. Spectacular how fast/easy building is.
>
> — Kyle Mathews (@kylemathews) [September 5, 2015](https://twitter.com/kylemathews/status/640289107122368513)

```
<blockquote class="twitter-tweet" lang="en"><p lang="en" dir="ltr"><a href="https://twitter.com/hashtag/RainySundayHackathon?src=hash">#RainySundayHackathon</a> exploring <a href="https://twitter.com/hashtag/GraphQL?src=hash">#GraphQL</a> <a href="https://twitter.com/hashtag/RelayJS?src=hash">#RelayJS</a> <a href="http://t.co/Mm3HlqMejJ">pic.twitter.com/Mm3HlqMejJ</a></p>&mdash; Bastian Kistner (@passionkind) <a href="https://twitter.com/passionkind/status/632846601447411712">August 16, 2015</a></blockquote>

<blockquote class="twitter-tweet" lang="en"><p lang="en" dir="ltr">Friday. Time to GraphQL a MySQL database. <a href="https://twitter.com/hashtag/graphql?src=hash">#graphql</a> <a href="https://twitter.com/hashtag/relayjs?src=hash">#relayjs</a> <a href="https://twitter.com/hashtag/reactjs?src=hash">#reactjs</a> <a href="https://twitter.com/hashtag/webapp?src=hash">#webapp</a></p>&mdash; xador (@xadorfr) <a href="https://twitter.com/xadorfr/status/632108552765751296">August 14, 2015</a></blockquote>
```

> Started a new [#RelayJS](https://twitter.com/hashtag/RelayJS?src=hash) and [#GraphQL](https://twitter.com/hashtag/GraphQL?src=hash) meet up group! <http://t.co/Vt6Cv4nNH4> If you're in the Bay Area, I'd love to have you join! [#ReactJS](https://twitter.com/hashtag/ReactJS?src=hash)
>
> — Gerald Monaco (@devknoll) [August 27, 2015](https://twitter.com/devknoll/status/636723716123000832)

```
<blockquote class="twitter-tweet" lang="en"><p lang="en" dir="ltr">.<a href="https://twitter.com/reactjs">@reactjs</a> <a href="https://twitter.com/laneykuenzel">@laneykuenzel</a> <a href="https://twitter.com/BhuwanKhattar">@BhuwanKhattar</a> these <a href="https://twitter.com/hashtag/relayjs?src=hash">#relayjs</a> mutations. they&#39;re mind-blowingly awesome. they make so much damn sense. thank you!</p>&mdash; Jimmy Jia (@jimmy_jia) <a href="https://twitter.com/jimmy_jia/status/634204563709526016">August 20, 2015</a></blockquote>

<blockquote class="twitter-tweet" lang="en"><p lang="en" dir="ltr">REST is dead, long live REST! <a href="https://twitter.com/hashtag/graphql?src=hash">#graphql</a> <a href="https://twitter.com/hashtag/relayjs?src=hash">#relayjs</a></p>&mdash; Syrus Akbary (@syrusakbary) <a href="https://twitter.com/syrusakbary/status/631531666113060864">August 12, 2015</a></blockquote>
```

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2015-09-14-community-roundup-27.md)

----
url: https://legacy.reactjs.org/blog/2014/10/28/react-v0.12.html
----

October 28, 2014 by [Paul O’Shannessy](https://twitter.com/zpao)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

We’re happy to announce the availability of React v0.12! After over a week of baking as the release candidate, we uncovered and fixed a few small issues. Thanks to all of you who upgraded and gave us feedback!

We have talked a lot about some of the bigger changes in this release. [We introduced new terminology](/blog/2014/10/14/introducing-react-elements.html) and changed APIs to clean up and simplify some of the concepts of React. [We also made several changes to JSX](/blog/2014/10/16/react-v0.12-rc1.html) and deprecated a few functions. We won’t go into depth about these changes again but we encourage you to read up on these changes in the linked posts. We’ll summarize these changes and discuss some of the other changes and how they may impact you below. As always, a full changelog is also included below.

The release is available for download:

* **React**\
  Dev build with warnings: <https://fb.me/react-0.12.0.js>\
  Minified build for production: <https://fb.me/react-0.12.0.min.js>
* **React with Add-Ons**\
  Dev build with warnings: <https://fb.me/react-with-addons-0.12.0.js>\
  Minified build for production: <https://fb.me/react-with-addons-0.12.0.min.js>
* **In-Browser JSX transformer**\
  <https://fb.me/JSXTransformer-0.12.0.js>

We’ve also published version `0.12.0` of the `react` and `react-tools` packages on npm and the `react` package on bower.

## [](#new-terminology--updated-apis)New Terminology & Updated APIs

v0.12 is bringing about some new terminology. [We introduced](/blog/2014/10/14/introducing-react-elements.html) this 2 weeks ago and we’ve also documented it in [a new section of the documentation](/docs/glossary.html). As a part of this, we also corrected many of our top-level APIs to align with the terminology. `Component` has been removed from all of our `React.render*` methods. While at one point the argument you passed to these functions was called a Component, it no longer is. You are passing ReactElements. To align with `render` methods in your component classes, we decided to keep the top-level functions short and sweet. `React.renderComponent` is now `React.render`.

We also corrected some other misnomers. `React.isValidComponent` actually determines if the argument is a ReactElement, so it has been renamed to `React.isValidElement`. In the same vein, `React.PropTypes.component` is now `React.PropTypes.element` and `React.PropTypes.renderable` is now `React.PropTypes.node`.

The old methods will still work but will warn upon first use. They will be removed in v0.13.

## [](#jsx-changes)JSX Changes

[We talked more in depth about these before](/blog/2014/10/16/react-v0.12-rc1.html#jsx-changes), so here are the highlights.

* No more `/** @jsx React.DOM */`!
* We no longer transform to a straight function call. `<Component/>` now becomes `React.createElement(Component)`
* DOM components don’t make use of `React.DOM`, instead we pass the tag name directly. `<div/>` becomes `React.createElement('div')`
* We introduced spread attributes as a quick way to transfer props.

## [](#devtools-improvements-no-more-__internals)DevTools Improvements, No More `__internals`

For months we’ve gotten complaints about the React DevTools message. It shouldn’t have logged the up-sell message when you were already using the DevTools. Unfortunately this was because the way we implemented these tools resulted in the DevTools knowing about React, but not the reverse. We finally gave this some attention and enabled React to know if the DevTools are installed. We released an update to the devtools several weeks ago making this possible. Extensions in Chrome should auto-update so you probably already have the update installed!

As a result of this update, we no longer need to expose several internal modules to the world. If you were taking advantage of this implementation detail, your code will break. `React.__internals` is no more.

## [](#license-change---bsd)License Change - BSD

We updated the license on React to the BSD 3-Clause license with an explicit patent grant. Previously we used the Apache 2 license. These licenses are very similar and our extra patent grant is equivalent to the grant provided in the Apache license. You can still use React with the confidence that we have granted the use of any patents covering it. This brings us in line with the same licensing we use across the majority of our open source projects at Facebook.

You can read the full text of the [LICENSE](https://github.com/facebook/react/blob/main/LICENSE) and [`PATENTS`](https://github.com/facebook/react/blob/main/PATENTS) files on GitHub.

***

## [](#changelog)Changelog

### [](#react-core)React Core

#### [](#breaking-changes)Breaking Changes

* `key` and `ref` moved off props object, now accessible on the element directly
* React is now BSD licensed with accompanying Patents grant
* Default prop resolution has moved to Element creation time instead of mount time, making them effectively static
* `React.__internals` is removed - it was exposed for DevTools which no longer needs access
* Composite Component functions can no longer be called directly - they must be wrapped with `React.createFactory` first. This is handled for you when using JSX.

#### [](#new-features)New Features

* Spread syntax (`{...}`) introduced to deprecate `this.transferPropsTo`
* Added support for more HTML attributes: `acceptCharset`, `classID`, `manifest`

#### [](#deprecations)Deprecations

* `React.renderComponent` —> `React.render`
* `React.renderComponentToString` —> `React.renderToString`
* `React.renderComponentToStaticMarkup` —> `React.renderToStaticMarkup`
* `React.isValidComponent` —> `React.isValidElement`
* `React.PropTypes.component` —> `React.PropTypes.element`
* `React.PropTypes.renderable` —> `React.PropTypes.node`
* **DEPRECATED** `React.isValidClass`
* **DEPRECATED** `instance.transferPropsTo`
* **DEPRECATED** Returning `false` from event handlers to preventDefault
* **DEPRECATED** Convenience Constructor usage as function, instead wrap with `React.createFactory`
* **DEPRECATED** use of `key={null}` to assign implicit keys

#### [](#bug-fixes)Bug Fixes

* Better handling of events and updates in nested results, fixing value restoration in “layered” controlled components

* Correctly treat `event.getModifierState` as case sensitive

* Improved normalization of `event.charCode`

* Better error stacks when involving autobound methods

* Removed DevTools message when the DevTools are installed

* Correctly detect required language features across browsers

* Fixed support for some HTML attributes:

  * `list` updates correctly now
  * `scrollLeft`, `scrollTop` removed, these should not be specified as props

* Improved error messages

### [](#react-with-addons)React With Addons

#### [](#new-features-1)New Features

* `React.addons.batchedUpdates` added to API for hooking into update cycle

#### [](#breaking-changes-1)Breaking Changes

* `React.addons.update` uses `assign` instead of `copyProperties` which does `hasOwnProperty` checks. Properties on prototypes will no longer be updated correctly.

#### [](#bug-fixes-1)Bug Fixes

* Fixed some issues with CSS Transitions

### [](#jsx)JSX

#### [](#breaking-changes-2)Breaking Changes

* Enforced convention: lower case tag names are always treated as HTML tags, upper case tag names are always treated as composite components
* JSX no longer transforms to simple function calls

#### [](#new-features-2)New Features

* `@jsx React.DOM` no longer required
* spread (`{...}`) operator introduced to allow easier use of props

#### [](#bug-fixes-2)Bug Fixes

* JSXTransformer: Make sourcemaps an option when using APIs directly (eg, for react-rails)

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2014-10-28-react-v0.12.md)

----
url: https://legacy.reactjs.org/blog/2017/06/13/react-v15.6.0.html
----

June 13, 2017 by [Flarnie Marchan](https://twitter.com/ProbablyFlarnie)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

Today we are releasing React 15.6.0. As we prepare for React 16.0, we have been fixing and cleaning up many things. This release continues to pave the way.

## [](#improving-inputs)Improving Inputs

In React 15.6.0 the `onChange` event for inputs is a little bit more reliable and handles more edge cases, including the following:

* not firing when radio button is clicked but not changed ([issue 1471](https://github.com/facebook/react/issues/1471))
* changing an input of type `range` with the arrow keys ([issue 554](https://github.com/facebook/react/issues/554))
* pasting text into a text area in IE11 ([issue 7211](https://github.com/facebook/react/issues/7211))
* auto-fill in IE11 ([issue 6614](https://github.com/facebook/react/issues/6614))
* clearing input with ‘x’ button or right-click ‘delete’ in IE11 ([issue 6822](https://github.com/facebook/react/issues/6822))
* not firing when characters are present in the input on render in IE11 ([issue 2185](https://github.com/facebook/react/issues/2185))

Thanks to [Jason Quense](https://github.com/jquense) and everyone who helped out on those issues and PRs.

## [](#less-noisy-deprecation-warnings)Less Noisy Deprecation Warnings

We are also including a couple of new warnings for upcoming deprecations. These should not affect most users, and for more details see the changelog below.

After the last release, we got valuable community feedback that deprecation warnings were causing noise and failing tests. **In React 15.6, we have downgraded deprecation warnings to use `console.warn` instead of `console.error`.** Our other warnings will still use `console.error` because they surface urgent issues which could lead to bugs. Unlike our other warnings, deprecation warnings can be fixed over time and won’t cause problems in your app if shipped. We believe that downgrading the urgency of deprecation warnings will make your next update easier. Thanks to everyone who was involved in the discussion of this change.

***

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

## [](#installation)Installation

We recommend using [Yarn](https://yarnpkg.com/) or [npm](https://www.npmjs.com/) for managing front-end dependencies. If you’re new to package managers, the [Yarn documentation](https://yarnpkg.com/en/docs/getting-started) is a good place to get started.

To install React with Yarn, run:

```
yarn add react@^15.6.0 react-dom@^15.6.0
```

To install React with npm, run:

```
npm install --save react@^15.6.0 react-dom@^15.6.0
```

We recommend using a bundler like [webpack](https://webpack.js.org/) or [Browserify](http://browserify.org/) so you can write modular code and bundle it together into small packages to optimize load time.

Remember that by default, React runs extra checks and provides helpful warnings in development mode. When deploying your app, make sure to [use the production build](/docs/optimizing-performance.html#use-the-production-build).

In case you don’t use a bundler, we also provide pre-built bundles in the npm packages which you can [include as script tags](/docs/installation.html#using-a-cdn) on your page:

* **React**\
  Dev build with warnings: [react/dist/react.js](https://unpkg.com/react@15.6.0/dist/react.js)\
  Minified build for production: [react/dist/react.min.js](https://unpkg.com/react@15.6.0/dist/react.min.js)
* **React with Add-Ons**\
  Dev build with warnings: [react/dist/react-with-addons.js](https://unpkg.com/react@15.6.0/dist/react-with-addons.js)\
  Minified build for production: [react/dist/react-with-addons.min.js](https://unpkg.com/react@15.5.0/dist/react-with-addons.min.js)
* **React DOM** (include React in the page before React DOM)\
  Dev build with warnings: [react-dom/dist/react-dom.js](https://unpkg.com/react-dom@15.6.0/dist/react-dom.js)\
  Minified build for production: [react-dom/dist/react-dom.min.js](https://unpkg.com/react-dom@15.6.0/dist/react-dom.min.js)
* **React DOM Server** (include React in the page before React DOM Server)\
  Dev build with warnings: [react-dom/dist/react-dom-server.js](https://unpkg.com/react-dom@15.6.0/dist/react-dom-server.js)\
  Minified build for production: [react-dom/dist/react-dom-server.min.js](https://unpkg.com/react-dom@15.6.0/dist/react-dom-server.min.js)

We’ve also published version `15.6.0` of `react` and `react-dom` on npm, and the `react` package on bower.

***

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

## [](#changelog)Changelog

## [](#1560-june-13-2017)15.6.0 (June 13, 2017)

### [](#react)React

* Downgrade deprecation warnings to use `console.warn` instead of `console.error`. ([@flarnie](https://github.com/flarnie) in [#9753](https://github.com/facebook/react/pull/9753))
* Add a deprecation warning for `React.createClass`. Points users to `create-react-class` instead. ([@flarnie](https://github.com/flarnie) in [#9771](https://github.com/facebook/react/pull/9771))
* Add deprecation warnings and separate module for `React.DOM` factory helpers. ([@nhunzaker](https://github.com/nhunzaker) in [#8356](https://github.com/facebook/react/pull/8356))
* Warn for deprecation of `React.createMixin` helper, which was never used. ([@aweary](https://github.com/aweary) in [#8853](https://github.com/facebook/react/pull/8853))

### [](#react-dom)React DOM

* Add support for CSS variables in `style` attribute. ([@aweary](https://github.com/aweary) in [#9302](https://github.com/facebook/react/pull/9302))
* Add support for CSS Grid style properties. ([@ericsakmar](https://github.com/ericsakmar) in [#9185](https://github.com/facebook/react/pull/9185))
* Fix bug where inputs mutated value on type conversion. ([@nhunzaker](https://github.com/mhunzaker) in [#9806](https://github.com/facebook/react/pull/9806))
* Fix issues with `onChange` not firing properly for some inputs. ([@jquense](https://github.com/jquense) in [#8575](https://github.com/facebook/react/pull/8575))
* Fix bug where controlled number input mistakenly allowed period. ([@nhunzaker](https://github.com/nhunzaker) in [#9584](https://github.com/facebook/react/pull/9584))
* Fix bug where performance entries were being cleared. ([@chrisui](https://github.com/chrisui) in [#9451](https://github.com/facebook/react/pull/9451))

### [](#react-addons)React Addons

* Fix AMD support for addons depending on `react`. ([@flarnie](https://github.com/flarnie) in [#9919](https://github.com/facebook/react/issues/9919))
* Fix `isMounted()` to return `true` in `componentWillUnmount`. ([@mridgway](https://github.com/mridgway) in [#9638](https://github.com/facebook/react/issues/9638))
* Fix `react-addons-update` to not depend on native `Object.assign`. ([@gaearon](https://github.com/gaearon) in [#9937](https://github.com/facebook/react/pull/9937))
* Remove broken Google Closure Compiler annotation from `create-react-class`. ([@gaearon](https://github.com/gaearon) in [#9933](https://github.com/facebook/react/pull/9933))
* Remove unnecessary dependency from `react-linked-input`. ([@gaearon](https://github.com/gaearon) in [#9766](https://github.com/facebook/react/pull/9766))
* Point `react-addons-(css-)transition-group` to the new package. ([@gaearon](https://github.com/gaearon) in [#9937](https://github.com/facebook/react/pull/9937))

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2017-06-13-react-v15.6.0.md)

----
url: https://legacy.reactjs.org/blog/2015/09/02/new-react-developer-tools.html
----

September 02, 2015 by [Sophie Alpert](https://sophiebits.com/)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

A month ago, we [posted a beta](/blog/2015/08/03/new-react-devtools-beta.html) of the new React developer tools. Today, we’re releasing the first stable version of the new devtools. We’re calling it version 0.14, but it’s a full rewrite so we think of it more like a 2.0 release.

It contains a handful of new features, including:

* Built entirely with React, making it easier to develop and extend
* Firefox support
* Selected component instance is available as `$r` from the console
* More detail is shown in props in the component tree
* Right-click any node and choose “Show Source” to jump to the `render` method in the Sources panel
* Right-click any props or state value to make it available as `$tmp` from the console
* Full React Native support

## [](#installation)Installation

Download the new devtools from the [Chrome Web Store](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi), [Firefox Add-ons](https://addons.mozilla.org/en-US/firefox/addon/react-devtools/) for Firefox, and [Microsoft Edge Addons](https://microsoftedge.microsoft.com/addons/detail/gpphkfbcpidddadnkolkpfckpihlkkil) for Edge. If you’re developing using React, we highly recommend installing these devtools.

If you already have the Chrome extension installed, it should autoupdate within the next week. You can also head to `chrome://extensions` and click “Update extensions now” if you’d like to get the new version today. If you installed the devtools beta, please remove it and switch back to the version from the store to make sure you always get the latest updates and bug fixes.

If you run into any issues, please post them on the [React GitHub repo](https://github.com/facebook/react).

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2015-09-02-new-react-developer-tools.md)

----
url: https://legacy.reactjs.org/blog/2014/11/24/react-js-conf-updates.html
----

November 24, 2014 by [Vjeux](https://twitter.com/vjeux)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

Yesterday was the [React.js Conf](http://conf.reactjs.com/index.html) call for presenters submission deadline. We were surprised to have received a total of **one hundred talk proposals** and were amazed that 600 people requested to be notified when ticket go on sale. This is incredible!

When we organized the conference, we decided to start small since this is the first React.js conference. Also, we weren’t sure what level of demand to expect, so we planned for a single-track, two-day conference on Facebook’s campus. The largest room available would accommodate 18 speaking slots and 200 attendees. The spacial configuration makes it difficult to add a second track and changing venues only two months in advance would be too difficult, so we are deciding to stick with the originally planned format and venue on Facebook’s campus.

Unfortunately, this means that we can only accept a small number of the awesome conference talk proposals. In order to make sure attendees get a fair shot at registering, we’re going to sell tickets in three separate first-come, first-serve phases. **Tickets will cost $200 regardless of which phase they are purchased from and all proceeds will go to charity**.

* Friday November 28th 2014 — Noon PST: First wave of tickets
* Friday December 5th 2014 — Noon PST: Second wave of tickets
* Friday December 12th 2014 — Noon PST: Third and last wave of tickets

We really do wish that everyone could attend React.js Conf, but in order to ensure a quality experience for those who attend, we feel it will be best to limit the size of the conference to what was originally planned for. This means that not everyone who wants to attend will be able to, and many talks that would be excellent contributions to the conference will have to be postponed until the next conference. All the talks will be recorded and put online shortly after.

We hope to see many of you at React.js Conf this January.

Sincerely,

React Core Team

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2014-11-24-react-js-conf-updates.md)

----
url: https://react.dev/reference/react-dom/static
----

[API Reference](/reference/react)

# Static React DOM APIs[](#undefined "Link for this heading")

The `react-dom/static` APIs let you generate static HTML for React components. They have limited functionality compared to the streaming APIs. A [framework](/learn/creating-a-react-app#full-stack-frameworks) may call them for you. Most of your components don’t need to import or use them.

***

## Static APIs for Web Streams[](#static-apis-for-web-streams "Link for Static APIs for Web Streams ")

These methods are only available in the environments with [Web Streams](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API), which includes browsers, Deno, and some modern edge runtimes:

* [`prerender`](/reference/react-dom/static/prerender) renders a React tree to static HTML with a [Readable Web Stream.](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream)
* Experimental only [`resumeAndPrerender`](/reference/react-dom/static/resumeAndPrerender) continues a prerendered React tree to static HTML with a [Readable Web Stream](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream).

Node.js also includes these methods for compatibility, but they are not recommended due to worse performance. Use the [dedicated Node.js APIs](#static-apis-for-nodejs-streams) instead.

***

## Static APIs for Node.js Streams[](#static-apis-for-nodejs-streams "Link for Static APIs for Node.js Streams ")

These methods are only available in the environments with [Node.js Streams](https://nodejs.org/api/stream.html):

* [`prerenderToNodeStream`](/reference/react-dom/static/prerenderToNodeStream) renders a React tree to static HTML with a [Node.js Stream.](https://nodejs.org/api/stream.html)
* Experimental only [`resumeAndPrerenderToNodeStream`](/reference/react-dom/static/resumeAndPrerenderToNodeStream) continues a prerendered React tree to static HTML with a [Node.js Stream.](https://nodejs.org/api/stream.html)

[PreviousresumeToPipeableStream](/reference/react-dom/server/resumeToPipeableStream)

[Nextprerender](/reference/react-dom/static/prerender)

***

----
url: https://react.dev/reference/react/captureOwnerStack
----

[API Reference](/reference/react)

[APIs](/reference/react/apis)

# captureOwnerStack[](#undefined "Link for this heading")

`captureOwnerStack` reads the current Owner Stack in development and returns it as a string if available.

```
const stack = captureOwnerStack();
```

* [Reference](#reference)
  * [`captureOwnerStack()`](#captureownerstack)

* [Usage](#usage)
  * [Enhance a custom error overlay](#enhance-a-custom-error-overlay)

* [Troubleshooting](#troubleshooting)

  * [The Owner Stack is `null`](#the-owner-stack-is-null)
  * [`captureOwnerStack` is not available](#captureownerstack-is-not-available)

***

## Reference[](#reference "Link for Reference ")

### `captureOwnerStack()`[](#captureownerstack "Link for this heading")

Call `captureOwnerStack` to get the current Owner Stack.

```
import * as React from 'react';



function Component() {

  if (process.env.NODE_ENV !== 'production') {

    const ownerStack = React.captureOwnerStack();

    console.log(ownerStack);

  }

}
```

#### Parameters[](#parameters "Link for Parameters ")

`captureOwnerStack` does not take any parameters.

#### Returns[](#returns "Link for Returns ")

`captureOwnerStack` returns `string | null`.

Owner Stacks are available in

* Component render
* Effects (e.g. `useEffect`)
* React’s event handlers (e.g. `<button onClick={...} />`)
* React error handlers ([React Root options](/reference/react-dom/client/createRoot#parameters) `onCaughtError`, `onRecoverableError`, and `onUncaughtError`)

If no Owner Stack is available, `null` is returned (see [Troubleshooting: The Owner Stack is `null`](#the-owner-stack-is-null)).

#### Caveats[](#caveats "Link for Caveats ")

* Owner Stacks are only available in development. `captureOwnerStack` will always return `null` outside of development.

##### Deep Dive#### Owner Stack vs Component Stack[](#owner-stack-vs-component-stack "Link for Owner Stack vs Component Stack ")

The Owner Stack is different from the Component Stack available in React error handlers like [`errorInfo.componentStack` in `onUncaughtError`](/reference/react-dom/client/hydrateRoot#error-logging-in-production).

For example, consider the following code:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import {captureOwnerStack} from 'react';
import {createRoot} from 'react-dom/client';
import App, {Component} from './App.js';
import './styles.css';

createRoot(document.createElement('div'), {
  onUncaughtError: (error, errorInfo) => {
    // The stacks are logged instead of showing them in the UI directly to
    // highlight that browsers will apply sourcemaps to the logged stacks.
    // Note that sourcemapping is only applied in the real browser console not
    // in the fake one displayed on this page.
    // Press "fork" to be able to view the sourcemapped stack in a real console.
    console.log(errorInfo.componentStack);
    console.log(captureOwnerStack());
  },
}).render(
  <App>
    <Component label="disabled" />
  </App>
);
```

`SubComponent` would throw an error. The Component Stack of that error would be

```
at SubComponent

at fieldset

at Component

at main

at React.Suspense

at App
```

However, the Owner Stack would only read

```
at Component
```

Neither `App` nor the DOM components (e.g. `fieldset`) are considered Owners in this Stack since they didn’t contribute to “creating” the node containing `SubComponent`. `App` and DOM components only forwarded the node. `App` just rendered the `children` node as opposed to `Component` which created a node containing `SubComponent` via `<SubComponent />`.

Neither `Navigation` nor `legend` are in the stack at all since it’s only a sibling to a node containing `<SubComponent />`.

`SubComponent` is omitted because it’s already part of the callstack.

## Usage[](#usage "Link for Usage ")

### Enhance a custom error overlay[](#enhance-a-custom-error-overlay "Link for Enhance a custom error overlay ")

```
import { captureOwnerStack } from "react";

import { instrumentedConsoleError } from "./errorOverlay";



const originalConsoleError = console.error;

console.error = function patchedConsoleError(...args) {

  originalConsoleError.apply(console, args);

  const ownerStack = captureOwnerStack();

  onConsoleError({

    // Keep in mind that in a real application, console.error can be

    // called with multiple arguments which you should account for.

    consoleMessage: args[0],

    ownerStack,

  });

};
```

If you intercept `console.error` calls to highlight them in an error overlay, you can call `captureOwnerStack` to include the Owner Stack.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { captureOwnerStack } from "react";
import { createRoot } from "react-dom/client";
import App from './App';
import { onConsoleError } from "./errorOverlay";
import './styles.css';

const originalConsoleError = console.error;
console.error = function patchedConsoleError(...args) {
  originalConsoleError.apply(console, args);
  const ownerStack = captureOwnerStack();
  onConsoleError({
    // Keep in mind that in a real application, console.error can be
    // called with multiple arguments which you should account for.
    consoleMessage: args[0],
    ownerStack,
  });
};

const container = document.getElementById("root");
createRoot(container).render(<App />);
```

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### The Owner Stack is `null`[](#the-owner-stack-is-null "Link for this heading")

The call of `captureOwnerStack` happened outside of a React controlled function e.g. in a `setTimeout` callback, after a `fetch` call or in a custom DOM event handler. During render, Effects, React event handlers, and React error handlers (e.g. `hydrateRoot#options.onCaughtError`) Owner Stacks should be available.

In the example below, clicking the button will log an empty Owner Stack because `captureOwnerStack` was called during a custom DOM event handler. The Owner Stack must be captured earlier e.g. by moving the call of `captureOwnerStack` into the Effect body.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import {captureOwnerStack, useEffect} from 'react';

export default function App() {
  useEffect(() => {
    // Should call `captureOwnerStack` here.
    function handleEvent() {
      // Calling it in a custom DOM event handler is too late.
      // The Owner Stack will be `null` at this point.
      console.log('Owner Stack: ', captureOwnerStack());
    }

    document.addEventListener('click', handleEvent);

    return () => {
      document.removeEventListener('click', handleEvent);
    }
  })

  return <button>Click me to see that Owner Stacks are not available in custom DOM event handlers</button>;
}
```

### `captureOwnerStack` is not available[](#captureownerstack-is-not-available "Link for this heading")

`captureOwnerStack` is only exported in development builds. It will be `undefined` in production builds. If `captureOwnerStack` is used in files that are bundled for production and development, you should conditionally access it from a namespace import.

```
// Don't use named imports of `captureOwnerStack` in files that are bundled for development and production.

import {captureOwnerStack} from 'react';

// Use a namespace import instead and access `captureOwnerStack` conditionally.

import * as React from 'react';



if (process.env.NODE_ENV !== 'production') {

  const ownerStack = React.captureOwnerStack();

  console.log('Owner Stack', ownerStack);

}
```

[PreviouscacheSignal](/reference/react/cacheSignal)

[NextcreateContext](/reference/react/createContext)

***

----
url: https://react.dev/blog/2025/02/14/sunsetting-create-react-app
----

[Blog](/blog)

# Sunsetting Create React App[](#undefined "Link for this heading")

February 14, 2025 by [Matt Carroll](https://twitter.com/mattcarrollcode) and [Ricky Hanlon](https://bsky.app/profile/ricky.fm)

***

Today, we’re deprecating [Create React App](https://create-react-app.dev/) for new apps, and encouraging existing apps to migrate to a [framework](#how-to-migrate-to-a-framework), or to [migrate to a build tool](#how-to-migrate-to-a-build-tool) like Vite, Parcel, or RSBuild.

We’re also providing docs for when a framework isn’t a good fit for your project, you want to build your own framework, or you just want to learn how React works by [building a React app from scratch](/learn/build-a-react-app-from-scratch).

***

When we released Create React App in 2016, there was no clear way to build a new React app.

To create a React app, you had to install a bunch of tools and wire them up together yourself to support basic features like JSX, linting, and hot reloading. This was very tricky to do correctly, so the [community](https://github.com/react-boilerplate/react-boilerplate) [created](https://github.com/kriasoft/react-starter-kit) [boilerplates](https://github.com/petehunt/react-boilerplate) for [common](https://github.com/gaearon/react-hot-boilerplate) [setups](https://github.com/erikras/react-redux-universal-hot-example). However, boilerplates were difficult to update and fragmentation made it difficult for React to release new features.

Create React App solved these problems by combining several tools into a single recommended configuration. This allowed apps a simple way to upgrade to new tooling features, and allowed the React team to deploy non-trivial tooling changes (Fast Refresh support, React Hooks lint rules) to the broadest possible audience.

This model became so popular that there’s an entire category of tools working this way today.

## Deprecating Create React App[](#deprecating-create-react-app "Link for Deprecating Create React App ")

Although Create React App makes it easy to get started, [there are several limitations](#limitations-of-build-tools) that make it difficult to build high performant production apps. In principle, we could solve these problems by essentially evolving it into a [framework](#why-we-recommend-frameworks).

However, since Create React App currently has no active maintainers, and there are many existing frameworks that solve these problems already, we’ve decided to deprecate Create React App.

Starting today, if you install a new app, you will see a deprecation warning:

Console

create-react-app is deprecated. You can find a list of up-to-date React frameworks on react.dev For more info see: react.dev/link/cra This error message will only be shown once per install.

We’ve also added a deprecation notice to the Create React App [website](https://create-react-app.dev/) and GitHub [repo](https://github.com/facebook/create-react-app). Create React App will continue working in maintenance mode, and we’ve published a new version of Create React App to work with React 19.

## How to Migrate to a Framework[](#how-to-migrate-to-a-framework "Link for How to Migrate to a Framework ")

We recommend [creating new React apps](/learn/creating-a-react-app) with a framework. All the frameworks we recommend support client-side rendering ([CSR](https://developer.mozilla.org/en-US/docs/Glossary/CSR)) and single-page apps ([SPA](https://developer.mozilla.org/en-US/docs/Glossary/SPA)), and can be deployed to a CDN or static hosting service without a server.

For existing apps, these guides will help you migrate to a client-only SPA:

* [Next.js’ Create React App migration guide](https://nextjs.org/docs/app/building-your-application/upgrading/from-create-react-app)
* [React Router’s framework adoption guide](https://reactrouter.com/upgrading/component-routes).
* [Expo webpack to Expo Router migration guide](https://docs.expo.dev/router/migrate/from-expo-webpack/)

## How to Migrate to a Build Tool[](#how-to-migrate-to-a-build-tool "Link for How to Migrate to a Build Tool ")

If your app has unusual constraints, or you prefer to solve these problems by building your own framework, or you just want to learn how react works from scratch, you can roll your own custom setup with React using Vite, Parcel or Rsbuild.

For existing apps, these guides will help you migrate to a build tool:

* [Vite Create React App migration guide](https://www.robinwieruch.de/vite-create-react-app/)
* [Parcel Create React App migration guide](https://parceljs.org/migration/cra/)
* [Rsbuild Create React App migration guide](https://rsbuild.dev/guide/migration/cra)

To help get started with Vite, Parcel or Rsbuild, we’ve added new docs for [Building a React App from Scratch](/learn/build-a-react-app-from-scratch).

##### Deep Dive#### Do I need a framework?[](#do-i-need-a-framework "Link for Do I need a framework? ")

Most apps would benefit from a framework, but there are valid cases to build a React app from scratch. A good rule of thumb is if your app needs routing, you would probably benefit from a framework.

Just like Svelte has Sveltekit, Vue has Nuxt, and Solid has SolidStart, [React recommends using a framework](#why-we-recommend-frameworks) that fully integrates routing into features like data-fetching and code-splitting out of the box. This avoids the pain of needing to write your own complex configurations and essentially build a framework yourself.

However, you can always [build a React app from scratch](/learn/build-a-react-app-from-scratch) using a build tool like Vite, Parcel, or Rsbuild.

Continue reading to learn more about the [limitations of build tools](#limitations-of-build-tools) and [why we recommend frameworks](#why-we-recommend-frameworks).

## Limitations of Build Tools[](#limitations-of-build-tools "Link for Limitations of Build Tools ")

Create React App and build tools like it make it easy to get started building a React app. After running `npx create-react-app my-app`, you get a fully configured React app with a development server, linting, and a production build.

For example, if you’re building an internal admin tool, you can start with a landing page:

```
export default function App() {

  return (

    <div>

      <h1>Welcome to the Admin Tool!</h1>

    </div>

  )

}
```

This allows you to immediately start coding in React with features like JSX, default linting rules, and a bundler to run in both development and production. However, this setup is missing the tools you need to build a real production app.

Most production apps need solutions to problems like routing, data fetching, and code splitting.

### Routing[](#routing "Link for Routing ")

Create React App does not include a specific routing solution. If you’re just getting started, one option is to use `useState` to switch between routes. But doing this means that you can’t share links to your app - every link would go to the same page - and structuring your app becomes difficult over time:

```
import {useState} from 'react';



import Home from './Home';

import Dashboard from './Dashboard';



export default function App() {

  // ❌ Routing in state does not create URLs

  const [route, setRoute] = useState('home');

  return (

    <div>

      {route === 'home' && <Home />}

      {route === 'dashboard' && <Dashboard />}

    </div>

  )

}
```

This is why most apps that use Create React App solve add routing with a routing library like [React Router](https://reactrouter.com/) or [Tanstack Router](https://tanstack.com/router/latest). With a routing library, you can add additional routes to the app, which provides opinions on the structure of your app, and allows you to start sharing links to routes. For example, with React Router you can define routes:

```
import {RouterProvider, createBrowserRouter} from 'react-router';



import Home from './Home';

import Dashboard from './Dashboard';



// ✅ Each route has it's own URL

const router = createBrowserRouter([

  {path: '/', element: <Home />},

  {path: '/dashboard', element: <Dashboard />}

]);



export default function App() {

  return (

    <RouterProvider value={router} />

  )

}
```

With this change, you can share a link to `/dashboard` and the app will navigate to the dashboard page . Once you have a routing library, you can add additional features like nested routes, route guards, and route transitions, which are difficult to implement without a routing library.

There’s a tradeoff being made here: the routing library adds complexity to the app, but it also adds features that are difficult to implement without it.

### Data Fetching[](#data-fetching "Link for Data Fetching ")

Another common problem in Create React App is data fetching. Create React App does not include a specific data fetching solution. If you’re just getting started, a common option is to use `fetch` in an effect to load data.

But doing this means that the data is fetched after the component renders, which can cause network waterfalls. Network waterfalls are caused by fetching data when your app renders instead of in parallel while the code is downloading:

```
export default function Dashboard() {

  const [data, setData] = useState(null);



  // ❌ Fetching data in a component causes network waterfalls

  useEffect(() => {

    fetch('/api/data')

      .then(response => response.json())

      .then(data => setData(data));

  }, []);



  return (

    <div>

      {data.map(item => <div key={item.id}>{item.name}</div>)}

    </div>

  )

}
```

Fetching in an effect means the user has to wait longer to see the content, even though the data could have been fetched earlier. To solve this, you can use a data fetching library like [TanStack Query](https://tanstack.com/query/), [SWR](https://swr.vercel.app/), [Apollo](https://www.apollographql.com/docs/react), or [Relay](https://relay.dev/) which provide options to prefetch data so the request is started before the component renders.

These libraries work best when integrated with your routing “loader” pattern to specify data dependencies at the route level, which allows the router to optimize your data fetches:

```
export async function loader() {

  const response = await fetch(`/api/data`);

  const data = await response.json();

  return data;

}



// ✅ Fetching data in parallel while the code is downloading

export default function Dashboard({loaderData}) {

  return (

    <div>

      {loaderData.map(item => <div key={item.id}>{item.name}</div>)}

    </div>

  )

}
```

On initial load, the router can fetch the data immediately before the route is rendered. As the user navigates around the app, the router is able to fetch both the data and the route at the same time, parallelizing the fetches. This reduces the time it takes to see the content on the screen, and can improve the user experience.

However, this requires correctly configuring the loaders in your app and trades off complexity for performance.

### Code Splitting[](#code-splitting "Link for Code Splitting ")

Another common problem in Create React App is [code splitting](https://www.patterns.dev/vanilla/bundle-splitting). Create React App does not include a specific code splitting solution. If you’re just getting started, you might not consider code splitting at all.

This means your app is shipped as a single bundle:

```
- bundle.js    75kb
```

But for ideal performance, you should “split” your code into separate bundles so the user only needs to download what they need. This decreases the time the user needs to wait to load your app, by only downloading the code they need to see the page they are on.

```
- core.js      25kb

- home.js      25kb

- dashboard.js 25kb
```

One way to do code-splitting is with `React.lazy`. However, this means that the code is not fetched until the component renders, which can cause network waterfalls. A more optimal solution is to use a router feature that fetches the code in parallel while the code is downloading. For example, React Router provides a `lazy` option to specify that a route should be code split and optimize when it is loaded:

```
import Home from './Home';

import Dashboard from './Dashboard';



// ✅ Routes are downloaded before rendering

const router = createBrowserRouter([

  {path: '/', lazy: () => import('./Home')},

  {path: '/dashboard', lazy: () => import('Dashboard')}

]);
```

Optimized code-splitting is tricky to get right, and it’s easy to make mistakes that can cause the user to download more code than they need. It works best when integrated with your router and data loading solutions to maximize caching, parallelize fetches, and support [“import on interaction”](https://www.patterns.dev/vanilla/import-on-interaction) patterns.

### And more…[](#and-more "Link for And more… ")

These are just a few examples of the limitations of Create React App.

Once you’ve integrated routing, data-fetching, and code splitting, you now also need to consider pending states, navigation interruptions, error messages to the user, and revalidation of the data. There are entire categories of problems that users need to solve like:

* Accessibility
* Asset loading
* Authentication
* Caching

- Error handling
- Mutating data
- Navigations
- Optimistic updates

* Progressive enhancement
* Server-side rendering
* Static site generation
* Streaming

All of these work together to create the most optimal [loading sequence](https://www.patterns.dev/vanilla/loading-sequence).

Solving each of these problems individually in Create React App can be difficult as each problem is interconnected with the others and can require deep expertise in problem areas users may not be familiar with. In order to solve these problems, users end up building their own bespoke solutions on top of Create React App, which was the problem Create React App originally tried to solve.

## Why we Recommend Frameworks[](#why-we-recommend-frameworks "Link for Why we Recommend Frameworks ")

Although you could solve all these pieces yourself in a build tool like Create React App, Vite, or Parcel, it is hard to do well. Just like when Create React App itself integrated several build tools together, you need a tool to integrate all of these features together to provide the best experience to users.

This category of tools that integrates build tools, rendering, routing, data fetching, and code splitting are known as “frameworks” — or if you prefer to call React itself a framework, you might call them “metaframeworks”.

Frameworks impose some opinions about structuring your app in order to provide a much better user experience, in the same way build tools impose some opinions to make tooling easier. This is why we started recommending frameworks like [Next.js](https://nextjs.org/), [React Router](https://reactrouter.com/), and [Expo](https://expo.dev/) for new projects.

Frameworks provide the same getting started experience as Create React App, but also provide solutions to problems users need to solve anyway in real production apps.

##### Deep Dive#### Server rendering is optional[](#server-rendering-is-optional "Link for Server rendering is optional ")

The frameworks we recommend all provide the option to create a [client-side rendered (CSR)](https://developer.mozilla.org/en-US/docs/Glossary/CSR) app.

In some cases, CSR is the right choice for a page, but many times it’s not. Even if most of your app is client-side, there are often individual pages that could benefit from server rendering features like [static-site generation (SSG)](https://developer.mozilla.org/en-US/docs/Glossary/SSG) or [server-side rendering (SSR)](https://developer.mozilla.org/en-US/docs/Glossary/SSR), for example a Terms of Service page, or documentation.

Server rendering generally sends less JavaScript to the client, and a full HTML document which produces a faster [First Contentful Paint (FCP)](https://web.dev/articles/fcp) by reducing [Total Blocking Time (TBD)](https://web.dev/articles/tbt), which can also lower [Interaction to Next Paint (INP)](https://web.dev/articles/inp). This is why the [Chrome team has encouraged](https://web.dev/articles/rendering-on-the-web) developers to consider static or server-side render over a full client-side approach to achieve the best possible performance.

There are tradeoffs to using a server, and it is not always the best option for every page. Generating pages on the server incurs additional cost and takes time to generate which can increase [Time to First Byte (TTFB)](https://web.dev/articles/ttfb). The best performing apps are able to pick the right rendering strategy on a per-page basis, based on the tradeoffs of each strategy.

Frameworks provide the option to use a server on any page if you want to, but do not force you to use a server. This allows you to pick the right rendering strategy for each page in your app.

#### What About Server Components[](#server-components "Link for What About Server Components ")

The frameworks we recommend also include support for React Server Components.

Server Components help solve these problems by moving routing and data fetching to the server, and allowing code splitting to be done for client components based on the data you render, instead of just the route rendered, and reducing the amount of JavaScript shipped for the best possible [loading sequence](https://www.patterns.dev/vanilla/loading-sequence).

Server Components do not require a server. They can be run at build time on your CI server to create a static-site generated app (SSG) app, at runtime on a web server for a server-side rendered (SSR) app.

See [Introducing zero-bundle size React Server Components](/blog/2020/12/21/data-fetching-with-react-server-components) and [the docs](/reference/rsc/server-components) for more info.

### Note

#### Server Rendering is not just for SEO[](#server-rendering-is-not-just-for-seo "Link for Server Rendering is not just for SEO ")

A common misunderstanding is that server rendering is only for [SEO](https://developer.mozilla.org/en-US/docs/Glossary/SEO).

While server rendering can improve SEO, it also improves performance by reducing the amount of JavaScript the user needs to download and parse before they can see the content on the screen.

This is why the Chrome team [has encouraged](https://web.dev/articles/rendering-on-the-web) developers to consider static or server-side render over a full client-side approach to achieve the best possible performance.

***

*Thank you to [Dan Abramov](https://bsky.app/profile/danabra.mov) for creating Create React App, and [Joe Haddad](https://github.com/Timer), [Ian Schmitz](https://github.com/ianschmitz), [Brody McKee](https://github.com/mrmckeb), and [many others](https://github.com/facebook/create-react-app/graphs/contributors) for maintaining Create React App over the years. Thank you to [Brooks Lybrand](https://bsky.app/profile/brookslybrand.bsky.social), [Dan Abramov](https://bsky.app/profile/danabra.mov), [Devon Govett](https://bsky.app/profile/devongovett.bsky.social), [Eli White](https://x.com/Eli_White), [Jack Herrington](https://bsky.app/profile/jherr.dev), [Joe Savona](https://x.com/en_JS), [Lauren Tan](https://bsky.app/profile/no.lol), [Lee Robinson](https://x.com/leeerob), [Mark Erikson](https://bsky.app/profile/acemarke.dev), [Ryan Florence](https://x.com/ryanflorence), [Sophie Alpert](https://bsky.app/profile/sophiebits.com), [Tanner Linsley](https://bsky.app/profile/tannerlinsley.com), and [Theo Browne](https://x.com/theo) for reviewing and providing feedback on this post.*

[PreviousReact Labs: View Transitions, Activity, and more](/blog/2025/04/23/react-labs-view-transitions-activity-and-more)

[NextReact 19](/blog/2024/12/05/react-19)

***

----
url: https://react.dev/reference/react-dom/components/common
----

***

## Reference[](#reference "Link for Reference ")

### Common components (e.g. `<div>`)[](#common "Link for this heading")

```
<div className="wrapper">Some content</div>
```

***

### `ref` callback function[](#ref-callback "Link for this heading")

Instead of a ref object (like the one returned by [`useRef`](/reference/react/useRef#manipulating-the-dom-with-a-ref)), you may pass a function to the `ref` attribute.

```
<div ref={(node) => {

  console.log('Attached', node);



  return () => {

    console.log('Clean up', node)

  }

}}>
```

[See an example of using the `ref` callback.](/learn/manipulating-the-dom-with-refs#how-to-manage-a-list-of-refs-using-a-ref-callback)

When the `<div>` DOM node is added to the screen, React will call your `ref` callback with the DOM `node` as the argument. When that `<div>` DOM node is removed, React will call your the cleanup function returned from the callback.

React will also call your `ref` callback whenever you pass a *different* `ref` callback. In the above example, `(node) => { ... }` is a different function on every render. When your component re-renders, the *previous* function will be called with `null` as the argument, and the *next* function will be called with the DOM node.

#### Parameters[](#ref-callback-parameters "Link for Parameters ")

* `node`: A DOM node. React will pass you the DOM node when the ref gets attached. Unless you pass the same function reference for the `ref` callback on every render, the callback will get temporarily cleanup and re-create during every re-render of the component.

### Note

#### React 19 added cleanup functions for `ref` callbacks.[](#react-19-added-cleanup-functions-for-ref-callbacks "Link for this heading")

To support backwards compatibility, if a cleanup function is not returned from the `ref` callback, `node` will be called with `null` when the `ref` is detached. This behavior will be removed in a future version.

#### Returns[](#returns "Link for Returns ")

* **optional** `cleanup function`: When the `ref` is detached, React will call the cleanup function. If a function is not returned by the `ref` callback, React will call the callback again with `null` as the argument when the `ref` gets detached. This behavior will be removed in a future version.

#### Caveats[](#caveats "Link for Caveats ")

* When Strict Mode is on, React will **run one extra development-only setup+cleanup cycle** before the first real setup. This is a stress-test that ensures that your cleanup logic “mirrors” your setup logic and that it stops or undoes whatever the setup is doing. If this causes a problem, implement the cleanup function.
* When you pass a *different* `ref` callback, React will call the *previous* callback’s cleanup function if provided. If no cleanup function is defined, the `ref` callback will be called with `null` as the argument. The *next* function will be called with the DOM node.

***

### React event object[](#react-event-object "Link for React event object ")

Your event handlers will receive a *React event object.* It is also sometimes known as a “synthetic event”.

```
<button onClick={e => {

  console.log(e); // React event object

}} />
```

***

### `AnimationEvent` handler function[](#animationevent-handler "Link for this heading")

An event handler type for the [CSS animation](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Animations/Using_CSS_animations) events.

```
<div

  onAnimationStart={e => console.log('onAnimationStart')}

  onAnimationIteration={e => console.log('onAnimationIteration')}

  onAnimationEnd={e => console.log('onAnimationEnd')}

/>
```

#### Parameters[](#animationevent-handler-parameters "Link for Parameters ")

* `e`: A [React event object](#react-event-object) with these extra [`AnimationEvent`](https://developer.mozilla.org/en-US/docs/Web/API/AnimationEvent) properties:

  * [`animationName`](https://developer.mozilla.org/en-US/docs/Web/API/AnimationEvent/animationName)
  * [`elapsedTime`](https://developer.mozilla.org/en-US/docs/Web/API/AnimationEvent/elapsedTime)
  * [`pseudoElement`](https://developer.mozilla.org/en-US/docs/Web/API/AnimationEvent/pseudoElement)

***

### `ClipboardEvent` handler function[](#clipboadevent-handler "Link for this heading")

An event handler type for the [Clipboard API](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard_API) events.

```
<input

  onCopy={e => console.log('onCopy')}

  onCut={e => console.log('onCut')}

  onPaste={e => console.log('onPaste')}

/>
```

#### Parameters[](#clipboadevent-handler-parameters "Link for Parameters ")

* `e`: A [React event object](#react-event-object) with these extra [`ClipboardEvent`](https://developer.mozilla.org/en-US/docs/Web/API/ClipboardEvent) properties:

  * [`clipboardData`](https://developer.mozilla.org/en-US/docs/Web/API/ClipboardEvent/clipboardData)

***

### `CompositionEvent` handler function[](#compositionevent-handler "Link for this heading")

An event handler type for the [input method editor (IME)](https://developer.mozilla.org/en-US/docs/Glossary/Input_method_editor) events.

```
<input

  onCompositionStart={e => console.log('onCompositionStart')}

  onCompositionUpdate={e => console.log('onCompositionUpdate')}

  onCompositionEnd={e => console.log('onCompositionEnd')}

/>
```

#### Parameters[](#compositionevent-handler-parameters "Link for Parameters ")

* `e`: A [React event object](#react-event-object) with these extra [`CompositionEvent`](https://developer.mozilla.org/en-US/docs/Web/API/CompositionEvent) properties:
  * [`data`](https://developer.mozilla.org/en-US/docs/Web/API/CompositionEvent/data)

***

### `DragEvent` handler function[](#dragevent-handler "Link for this heading")

An event handler type for the [HTML Drag and Drop API](https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API) events.

```
<>

  <div

    draggable={true}

    onDragStart={e => console.log('onDragStart')}

    onDragEnd={e => console.log('onDragEnd')}

  >

    Drag source

  </div>



  <div

    onDragEnter={e => console.log('onDragEnter')}

    onDragLeave={e => console.log('onDragLeave')}

    onDragOver={e => { e.preventDefault(); console.log('onDragOver'); }}

    onDrop={e => console.log('onDrop')}

  >

    Drop target

  </div>

</>
```

***

### `FocusEvent` handler function[](#focusevent-handler "Link for this heading")

An event handler type for the focus events.

```
<input

  onFocus={e => console.log('onFocus')}

  onBlur={e => console.log('onBlur')}

/>
```

***

### `Event` handler function[](#event-handler "Link for this heading")

An event handler type for generic events.

#### Parameters[](#event-handler-parameters "Link for Parameters ")

* `e`: A [React event object](#react-event-object) with no additional properties.

***

### `InputEvent` handler function[](#inputevent-handler "Link for this heading")

An event handler type for the `onBeforeInput` event.

```
<input onBeforeInput={e => console.log('onBeforeInput')} />
```

#### Parameters[](#inputevent-handler-parameters "Link for Parameters ")

* `e`: A [React event object](#react-event-object) with these extra [`InputEvent`](https://developer.mozilla.org/en-US/docs/Web/API/InputEvent) properties:
  * [`data`](https://developer.mozilla.org/en-US/docs/Web/API/InputEvent/data)

***

### `KeyboardEvent` handler function[](#keyboardevent-handler "Link for this heading")

An event handler type for keyboard events.

```
<input

  onKeyDown={e => console.log('onKeyDown')}

  onKeyUp={e => console.log('onKeyUp')}

/>
```

***

### `MouseEvent` handler function[](#mouseevent-handler "Link for this heading")

An event handler type for mouse events.

```
<div

  onClick={e => console.log('onClick')}

  onMouseEnter={e => console.log('onMouseEnter')}

  onMouseOver={e => console.log('onMouseOver')}

  onMouseDown={e => console.log('onMouseDown')}

  onMouseUp={e => console.log('onMouseUp')}

  onMouseLeave={e => console.log('onMouseLeave')}

/>
```

***

### `PointerEvent` handler function[](#pointerevent-handler "Link for this heading")

An event handler type for [pointer events.](https://developer.mozilla.org/en-US/docs/Web/API/Pointer_events)

```
<div

  onPointerEnter={e => console.log('onPointerEnter')}

  onPointerMove={e => console.log('onPointerMove')}

  onPointerDown={e => console.log('onPointerDown')}

  onPointerUp={e => console.log('onPointerUp')}

  onPointerLeave={e => console.log('onPointerLeave')}

/>
```

***

### `TouchEvent` handler function[](#touchevent-handler "Link for this heading")

An event handler type for [touch events.](https://developer.mozilla.org/en-US/docs/Web/API/Touch_events)

```
<div

  onTouchStart={e => console.log('onTouchStart')}

  onTouchMove={e => console.log('onTouchMove')}

  onTouchEnd={e => console.log('onTouchEnd')}

  onTouchCancel={e => console.log('onTouchCancel')}

/>
```

***

### `TransitionEvent` handler function[](#transitionevent-handler "Link for this heading")

An event handler type for the CSS transition events.

```
<div

  onTransitionEnd={e => console.log('onTransitionEnd')}

/>
```

#### Parameters[](#transitionevent-handler-parameters "Link for Parameters ")

* `e`: A [React event object](#react-event-object) with these extra [`TransitionEvent`](https://developer.mozilla.org/en-US/docs/Web/API/TransitionEvent) properties:

  * [`elapsedTime`](https://developer.mozilla.org/en-US/docs/Web/API/TransitionEvent/elapsedTime)
  * [`propertyName`](https://developer.mozilla.org/en-US/docs/Web/API/TransitionEvent/propertyName)
  * [`pseudoElement`](https://developer.mozilla.org/en-US/docs/Web/API/TransitionEvent/pseudoElement)

***

### `UIEvent` handler function[](#uievent-handler "Link for this heading")

An event handler type for generic UI events.

```
<div

  onScroll={e => console.log('onScroll')}

/>
```

#### Parameters[](#uievent-handler-parameters "Link for Parameters ")

* `e`: A [React event object](#react-event-object) with these extra [`UIEvent`](https://developer.mozilla.org/en-US/docs/Web/API/UIEvent) properties:

  * [`detail`](https://developer.mozilla.org/en-US/docs/Web/API/UIEvent/detail)
  * [`view`](https://developer.mozilla.org/en-US/docs/Web/API/UIEvent/view)

***

### `WheelEvent` handler function[](#wheelevent-handler "Link for this heading")

An event handler type for the `onWheel` event.

```
<div

  onWheel={e => console.log('onWheel')}

/>
```

***

## Usage[](#usage "Link for Usage ")

### Applying CSS styles[](#applying-css-styles "Link for Applying CSS styles ")

In React, you specify a CSS class with [`className`.](https://developer.mozilla.org/en-US/docs/Web/API/Element/className) It works like the `class` attribute in HTML:

```
<img className="avatar" />
```

Then you write the CSS rules for it in a separate CSS file:

```
/* In your CSS */

.avatar {

  border-radius: 50%;

}
```

React does not prescribe how you add CSS files. In the simplest case, you’ll add a [`<link>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link) tag to your HTML. If you use a build tool or a framework, consult its documentation to learn how to add a CSS file to your project.

Sometimes, the style values depend on data. Use the `style` attribute to pass some styles dynamically:

```
<img

  className="avatar"

  style={{

    width: user.imageSize,

    height: user.imageSize

  }}

/>
```

In the above example, `style={{}}` is not a special syntax, but a regular `{}` object inside the `style={ }` [JSX curly braces.](/learn/javascript-in-jsx-with-curly-braces) We recommend only using the `style` attribute when your styles depend on JavaScript variables.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
export default function Avatar({ user }) {
  return (
    <img
      src={user.imageUrl}
      alt={'Photo of ' + user.name}
      className="avatar"
      style={{
        width: user.imageSize,
        height: user.imageSize
      }}
    />
  );
}
```

##### Deep Dive#### How to apply multiple CSS classes conditionally?[](#how-to-apply-multiple-css-classes-conditionally "Link for How to apply multiple CSS classes conditionally? ")

To apply CSS classes conditionally, you need to produce the `className` string yourself using JavaScript.

For example, `className={'row ' + (isSelected ? 'selected': '')}` will produce either `className="row"` or `className="row selected"` depending on whether `isSelected` is `true`.

To make this more readable, you can use a tiny helper library like [`classnames`:](https://github.com/JedWatson/classnames)

```
import cn from 'classnames';



function Row({ isSelected }) {

  return (

    <div className={cn('row', isSelected && 'selected')}>

      ...

    </div>

  );

}
```

It is especially convenient if you have multiple conditional classes:

```
import cn from 'classnames';



function Row({ isSelected, size }) {

  return (

    <div className={cn('row', {

      selected: isSelected,

      large: size === 'large',

      small: size === 'small',

    })}>

      ...

    </div>

  );

}
```

***

### Manipulating a DOM node with a ref[](#manipulating-a-dom-node-with-a-ref "Link for Manipulating a DOM node with a ref ")

Sometimes, you’ll need to get the browser DOM node associated with a tag in JSX. For example, if you want to focus an `<input>` when a button is clicked, you need to call [`focus()`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus) on the browser `<input>` DOM node.

To obtain the browser DOM node for a tag, [declare a ref](/reference/react/useRef) and pass it as the `ref` attribute to that tag:

```
import { useRef } from 'react';



export default function Form() {

  const inputRef = useRef(null);

  // ...

  return (

    <input ref={inputRef} />

    // ...
```

React will put the DOM node into `inputRef.current` after it’s been rendered to the screen.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useRef } from 'react';

export default function Form() {
  const inputRef = useRef(null);

  function handleClick() {
    inputRef.current.focus();
  }

  return (
    <>
      <input ref={inputRef} />
      <button onClick={handleClick}>
        Focus the input
      </button>
    </>
  );
}
```

Read more about [manipulating DOM with refs](/learn/manipulating-the-dom-with-refs) and [check out more examples.](/reference/react/useRef#usage)

For more advanced use cases, the `ref` attribute also accepts a [callback function.](#ref-callback)

***

### Dangerously setting the inner HTML[](#dangerously-setting-the-inner-html "Link for Dangerously setting the inner HTML ")

You can pass a raw HTML string to an element like so:

```
const markup = { __html: '<p>some raw html</p>' };

return <div dangerouslySetInnerHTML={markup} />;
```

**This is dangerous. As with the underlying DOM [`innerHTML`](https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML) property, you must exercise extreme caution! Unless the markup is coming from a completely trusted source, it is trivial to introduce an [XSS](https://en.wikipedia.org/wiki/Cross-site_scripting) vulnerability this way.**

For example, if you use a Markdown library that converts Markdown to HTML, you trust that its parser doesn’t contain bugs, and the user only sees their own input, you can display the resulting HTML like this:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { Remarkable } from 'remarkable';

const md = new Remarkable();

function renderMarkdownToHTML(markdown) {
  // This is ONLY safe because the output HTML
  // is shown to the same user, and because you
  // trust this Markdown parser to not have bugs.
  const renderedHTML = md.render(markdown);
  return {__html: renderedHTML};
}

export default function MarkdownPreview({ markdown }) {
  const markup = renderMarkdownToHTML(markdown);
  return <div dangerouslySetInnerHTML={markup} />;
}
```

The `{__html}` object should be created as close to where the HTML is generated as possible, like the above example does in the `renderMarkdownToHTML` function. This ensures that all raw HTML being used in your code is explicitly marked as such, and that only variables that you expect to contain HTML are passed to `dangerouslySetInnerHTML`. It is not recommended to create the object inline like `<div dangerouslySetInnerHTML={{__html: markup}} />`.

To see why rendering arbitrary HTML is dangerous, replace the code above with this:

```
const post = {

  // Imagine this content is stored in the database.

  content: `<img src="" onerror='alert("you were hacked")'>`

};



export default function MarkdownPreview() {

  // 🔴 SECURITY HOLE: passing untrusted input to dangerouslySetInnerHTML

  const markup = { __html: post.content };

  return <div dangerouslySetInnerHTML={markup} />;

}
```

The code embedded in the HTML will run. A hacker could use this security hole to steal user information or to perform actions on their behalf. **Only use `dangerouslySetInnerHTML` with trusted and sanitized data.**

***

### Handling mouse events[](#handling-mouse-events "Link for Handling mouse events ")

This example shows some common [mouse events](#mouseevent-handler) and when they fire.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
export default function MouseExample() {
  return (
    <div
      onMouseEnter={e => console.log('onMouseEnter (parent)')}
      onMouseLeave={e => console.log('onMouseLeave (parent)')}
    >
      <button
        onClick={e => console.log('onClick (first button)')}
        onMouseDown={e => console.log('onMouseDown (first button)')}
        onMouseEnter={e => console.log('onMouseEnter (first button)')}
        onMouseLeave={e => console.log('onMouseLeave (first button)')}
        onMouseOver={e => console.log('onMouseOver (first button)')}
        onMouseUp={e => console.log('onMouseUp (first button)')}
      >
        First button
      </button>
      <button
        onClick={e => console.log('onClick (second button)')}
        onMouseDown={e => console.log('onMouseDown (second button)')}
        onMouseEnter={e => console.log('onMouseEnter (second button)')}
        onMouseLeave={e => console.log('onMouseLeave (second button)')}
        onMouseOver={e => console.log('onMouseOver (second button)')}
        onMouseUp={e => console.log('onMouseUp (second button)')}
      >
        Second button
      </button>
    </div>
  );
}
```

***

### Handling pointer events[](#handling-pointer-events "Link for Handling pointer events ")

This example shows some common [pointer events](#pointerevent-handler) and when they fire.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
export default function PointerExample() {
  return (
    <div
      onPointerEnter={e => console.log('onPointerEnter (parent)')}
      onPointerLeave={e => console.log('onPointerLeave (parent)')}
      style={{ padding: 20, backgroundColor: '#ddd' }}
    >
      <div
        onPointerDown={e => console.log('onPointerDown (first child)')}
        onPointerEnter={e => console.log('onPointerEnter (first child)')}
        onPointerLeave={e => console.log('onPointerLeave (first child)')}
        onPointerMove={e => console.log('onPointerMove (first child)')}
        onPointerUp={e => console.log('onPointerUp (first child)')}
        style={{ padding: 20, backgroundColor: 'lightyellow' }}
      >
        First child
      </div>
      <div
        onPointerDown={e => console.log('onPointerDown (second child)')}
        onPointerEnter={e => console.log('onPointerEnter (second child)')}
        onPointerLeave={e => console.log('onPointerLeave (second child)')}
        onPointerMove={e => console.log('onPointerMove (second child)')}
        onPointerUp={e => console.log('onPointerUp (second child)')}
        style={{ padding: 20, backgroundColor: 'lightblue' }}
      >
        Second child
      </div>
    </div>
  );
}
```

***

### Handling focus events[](#handling-focus-events "Link for Handling focus events ")

In React, [focus events](#focusevent-handler) bubble. You can use the `currentTarget` and `relatedTarget` to differentiate if the focusing or blurring events originated from outside of the parent element. The example shows how to detect focusing a child, focusing the parent element, and how to detect focus entering or leaving the whole subtree.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
export default function FocusExample() {
  return (
    <div
      tabIndex={1}
      onFocus={(e) => {
        if (e.currentTarget === e.target) {
          console.log('focused parent');
        } else {
          console.log('focused child', e.target.name);
        }
        if (!e.currentTarget.contains(e.relatedTarget)) {
          // Not triggered when swapping focus between children
          console.log('focus entered parent');
        }
      }}
      onBlur={(e) => {
        if (e.currentTarget === e.target) {
          console.log('unfocused parent');
        } else {
          console.log('unfocused child', e.target.name);
        }
        if (!e.currentTarget.contains(e.relatedTarget)) {
          // Not triggered when swapping focus between children
          console.log('focus left parent');
        }
      }}
    >
      <label>
        First name:
        <input name="firstName" />
      </label>
      <label>
        Last name:
        <input name="lastName" />
      </label>
    </div>
  );
}
```

***

### Handling keyboard events[](#handling-keyboard-events "Link for Handling keyboard events ")

This example shows some common [keyboard events](#keyboardevent-handler) and when they fire.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
export default function KeyboardExample() {
  return (
    <label>
      First name:
      <input
        name="firstName"
        onKeyDown={e => console.log('onKeyDown:', e.key, e.code)}
        onKeyUp={e => console.log('onKeyUp:', e.key, e.code)}
      />
    </label>
  );
}
```

[PreviousComponents](/reference/react-dom/components)

[Next\<form>](/reference/react-dom/components/form)

***

----
url: https://react.dev/reference/rules/react-calls-components-and-hooks
----

[API Reference](/reference/react)

[Overview](/reference/rules)

# React calls Components and Hooks[](#undefined "Link for this heading")

React is responsible for rendering components and Hooks when necessary to optimize the user experience. It is declarative: you tell React what to render in your component’s logic, and React will figure out how best to display it to your user.

* [Never call component functions directly](#never-call-component-functions-directly)

* [Never pass around Hooks as regular values](#never-pass-around-hooks-as-regular-values)

  * [Don’t dynamically mutate a Hook](#dont-dynamically-mutate-a-hook)
  * [Don’t dynamically use Hooks](#dont-dynamically-use-hooks)

***

## Never call component functions directly[](#never-call-component-functions-directly "Link for Never call component functions directly ")

Components should only be used in JSX. Don’t call them as regular functions. React should call it.

React must decide when your component function is called [during rendering](/reference/rules/components-and-hooks-must-be-pure#how-does-react-run-your-code). In React, you do this using JSX.

```
function BlogPost() {

  return <Layout><Article /></Layout>; // ✅ Good: Only use components in JSX

}
```

```
function BlogPost() {

  return <Layout>{Article()}</Layout>; // 🔴 Bad: Never call them directly

}
```

If a component contains Hooks, it’s easy to violate the [Rules of Hooks](/reference/rules/rules-of-hooks) when components are called directly in a loop or conditionally.

Letting React orchestrate rendering also allows a number of benefits:

* **Components become more than functions.** React can augment them with features like *local state* through Hooks that are tied to the component’s identity in the tree.
* **Component types participate in reconciliation.** By letting React call your components, you also tell it more about the conceptual structure of your tree. For example, when you move from rendering `<Feed>` to the `<Profile>` page, React won’t attempt to re-use them.
* **React can enhance your user experience.** For example, it can let the browser do some work between component calls so that re-rendering a large component tree doesn’t block the main thread.
* **A better debugging story.** If components are first-class citizens that the library is aware of, we can build rich developer tools for introspection in development.
* **More efficient reconciliation.** React can decide exactly which components in the tree need re-rendering and skip over the ones that don’t. That makes your app faster and more snappy.

***

## Never pass around Hooks as regular values[](#never-pass-around-hooks-as-regular-values "Link for Never pass around Hooks as regular values ")

Hooks should only be called inside of components or Hooks. Never pass it around as a regular value.

Hooks allow you to augment a component with React features. They should always be called as a function, and never passed around as a regular value. This enables *local reasoning*, or the ability for developers to understand everything a component can do by looking at that component in isolation.

Breaking this rule will cause React to not automatically optimize your component.

### Don’t dynamically mutate a Hook[](#dont-dynamically-mutate-a-hook "Link for Don’t dynamically mutate a Hook ")

Hooks should be as “static” as possible. This means you shouldn’t dynamically mutate them. For example, this means you shouldn’t write higher order Hooks:

```
function ChatInput() {

  const useDataWithLogging = withLogging(useData); // 🔴 Bad: don't write higher order Hooks

  const data = useDataWithLogging();

}
```

Hooks should be immutable and not be mutated. Instead of mutating a Hook dynamically, create a static version of the Hook with the desired functionality.

```
function ChatInput() {

  const data = useDataWithLogging(); // ✅ Good: Create a new version of the Hook

}



function useDataWithLogging() {

  // ... Create a new version of the Hook and inline the logic here

}
```

### Don’t dynamically use Hooks[](#dont-dynamically-use-hooks "Link for Don’t dynamically use Hooks ")

Hooks should also not be dynamically used: for example, instead of doing dependency injection in a component by passing a Hook as a value:

```
function ChatInput() {

  return <Button useData={useDataWithLogging} /> // 🔴 Bad: don't pass Hooks as props

}
```

You should always inline the call of the Hook into that component and handle any logic in there.

```
function ChatInput() {

  return <Button />

}



function Button() {

  const data = useDataWithLogging(); // ✅ Good: Use the Hook directly

}



function useDataWithLogging() {

  // If there's any conditional logic to change the Hook's behavior, it should be inlined into

  // the Hook

}
```

This way, `<Button />` is much easier to understand and debug. When Hooks are used in dynamic ways, it increases the complexity of your app greatly and inhibits local reasoning, making your team less productive in the long term. It also makes it easier to accidentally break the [Rules of Hooks](/reference/rules/rules-of-hooks) that Hooks should not be called conditionally. If you find yourself needing to mock components for tests, it’s better to mock the server instead to respond with canned data. If possible, it’s also usually more effective to test your app with end-to-end tests.

[PreviousComponents and Hooks must be pure](/reference/rules/components-and-hooks-must-be-pure)

[NextRules of Hooks](/reference/rules/rules-of-hooks)

***

----
url: https://react.dev/reference/react/cloneElement
----

[API Reference](/reference/react)

[Legacy React APIs](/reference/react/legacy)

# cloneElement[](#undefined "Link for this heading")

### Pitfall

Using `cloneElement` is uncommon and can lead to fragile code. [See common alternatives.](#alternatives)

`cloneElement` lets you create a new React element using another element as a starting point.

```
const clonedElement = cloneElement(element, props, ...children)
```

***

## Reference[](#reference "Link for Reference ")

### `cloneElement(element, props, ...children)`[](#cloneelement "Link for this heading")

Call `cloneElement` to create a React element based on the `element`, but with different `props` and `children`:

```
import { cloneElement } from 'react';



// ...

const clonedElement = cloneElement(

  <Row title="Cabbage">

    Hello

  </Row>,

  { isHighlighted: true },

  'Goodbye'

);



console.log(clonedElement); // <Row title="Cabbage" isHighlighted={true}>Goodbye</Row>
```

***

## Usage[](#usage "Link for Usage ")

### Overriding props of an element[](#overriding-props-of-an-element "Link for Overriding props of an element ")

To override the props of some React element, pass it to `cloneElement` with the props you want to override:

```
import { cloneElement } from 'react';



// ...

const clonedElement = cloneElement(

  <Row title="Cabbage" />,

  { isHighlighted: true }

);
```

Here, the resulting cloned element will be `<Row title="Cabbage" isHighlighted={true} />`.

**Let’s walk through an example to see when it’s useful.**

Imagine a `List` component that renders its [`children`](/learn/passing-props-to-a-component#passing-jsx-as-children) as a list of selectable rows with a “Next” button that changes which row is selected. The `List` component needs to render the selected `Row` differently, so it clones every `<Row>` child that it has received, and adds an extra `isHighlighted: true` or `isHighlighted: false` prop:

```
export default function List({ children }) {

  const [selectedIndex, setSelectedIndex] = useState(0);

  return (

    <div className="List">

      {Children.map(children, (child, index) =>

        cloneElement(child, {

          isHighlighted: index === selectedIndex

        })

      )}
```

Let’s say the original JSX received by `List` looks like this:

```
<List>

  <Row title="Cabbage" />

  <Row title="Garlic" />

  <Row title="Apple" />

</List>
```

By cloning its children, the `List` can pass extra information to every `Row` inside. The result looks like this:

```
<List>

  <Row

    title="Cabbage"

    isHighlighted={true}

  />

  <Row

    title="Garlic"

    isHighlighted={false}

  />

  <Row

    title="Apple"

    isHighlighted={false}

  />

</List>
```

Notice how pressing “Next” updates the state of the `List`, and highlights a different row:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { Children, cloneElement, useState } from 'react';

export default function List({ children }) {
  const [selectedIndex, setSelectedIndex] = useState(0);
  return (
    <div className="List">
      {Children.map(children, (child, index) =>
        cloneElement(child, {
          isHighlighted: index === selectedIndex
        })
      )}
      <hr />
      <button onClick={() => {
        setSelectedIndex(i =>
          (i + 1) % Children.count(children)
        );
      }}>
        Next
      </button>
    </div>
  );
}
```

To summarize, the `List` cloned the `<Row />` elements it received and added an extra prop to them.

### Pitfall

Cloning children makes it hard to tell how the data flows through your app. Try one of the [alternatives.](#alternatives)

***

## Alternatives[](#alternatives "Link for Alternatives ")

### Passing data with a render prop[](#passing-data-with-a-render-prop "Link for Passing data with a render prop ")

Instead of using `cloneElement`, consider accepting a *render prop* like `renderItem`. Here, `List` receives `renderItem` as a prop. `List` calls `renderItem` for every item and passes `isHighlighted` as an argument:

```
export default function List({ items, renderItem }) {

  const [selectedIndex, setSelectedIndex] = useState(0);

  return (

    <div className="List">

      {items.map((item, index) => {

        const isHighlighted = index === selectedIndex;

        return renderItem(item, isHighlighted);

      })}
```

The `renderItem` prop is called a “render prop” because it’s a prop that specifies how to render something. For example, you can pass a `renderItem` implementation that renders a `<Row>` with the given `isHighlighted` value:

```
<List

  items={products}

  renderItem={(product, isHighlighted) =>

    <Row

      key={product.id}

      title={product.title}

      isHighlighted={isHighlighted}

    />

  }

/>
```

The end result is the same as with `cloneElement`:

```
<List>

  <Row

    title="Cabbage"

    isHighlighted={true}

  />

  <Row

    title="Garlic"

    isHighlighted={false}

  />

  <Row

    title="Apple"

    isHighlighted={false}

  />

</List>
```

However, you can clearly trace where the `isHighlighted` value is coming from.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function List({ items, renderItem }) {
  const [selectedIndex, setSelectedIndex] = useState(0);
  return (
    <div className="List">
      {items.map((item, index) => {
        const isHighlighted = index === selectedIndex;
        return renderItem(item, isHighlighted);
      })}
      <hr />
      <button onClick={() => {
        setSelectedIndex(i =>
          (i + 1) % items.length
        );
      }}>
        Next
      </button>
    </div>
  );
}
```

This pattern is preferred to `cloneElement` because it is more explicit.

***

### Passing data through context[](#passing-data-through-context "Link for Passing data through context ")

Another alternative to `cloneElement` is to [pass data through context.](/learn/passing-data-deeply-with-context)

For example, you can call [`createContext`](/reference/react/createContext) to define a `HighlightContext`:

```
export const HighlightContext = createContext(false);
```

Your `List` component can wrap every item it renders into a `HighlightContext` provider:

```
export default function List({ items, renderItem }) {

  const [selectedIndex, setSelectedIndex] = useState(0);

  return (

    <div className="List">

      {items.map((item, index) => {

        const isHighlighted = index === selectedIndex;

        return (

          <HighlightContext key={item.id} value={isHighlighted}>

            {renderItem(item)}

          </HighlightContext>

        );

      })}
```

With this approach, `Row` does not need to receive an `isHighlighted` prop at all. Instead, it reads the context:

```
export default function Row({ title }) {

  const isHighlighted = useContext(HighlightContext);

  // ...
```

This allows the calling component to not know or worry about passing `isHighlighted` to `<Row>`:

```
<List

  items={products}

  renderItem={product =>

    <Row title={product.title} />

  }

/>
```

Instead, `List` and `Row` coordinate the highlighting logic through context.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';
import { HighlightContext } from './HighlightContext.js';

export default function List({ items, renderItem }) {
  const [selectedIndex, setSelectedIndex] = useState(0);
  return (
    <div className="List">
      {items.map((item, index) => {
        const isHighlighted = index === selectedIndex;
        return (
          <HighlightContext
            key={item.id}
            value={isHighlighted}
          >
            {renderItem(item)}
          </HighlightContext>
        );
      })}
      <hr />
      <button onClick={() => {
        setSelectedIndex(i =>
          (i + 1) % items.length
        );
      }}>
        Next
      </button>
    </div>
  );
}
```

[Learn more about passing data through context.](/reference/react/useContext#passing-data-deeply-into-the-tree)

***

### Extracting logic into a custom Hook[](#extracting-logic-into-a-custom-hook "Link for Extracting logic into a custom Hook ")

Another approach you can try is to extract the “non-visual” logic into your own Hook, and use the information returned by your Hook to decide what to render. For example, you could write a `useList` custom Hook like this:

```
import { useState } from 'react';



export default function useList(items) {

  const [selectedIndex, setSelectedIndex] = useState(0);



  function onNext() {

    setSelectedIndex(i =>

      (i + 1) % items.length

    );

  }



  const selected = items[selectedIndex];

  return [selected, onNext];

}
```

Then you could use it like this:

```
export default function App() {

  const [selected, onNext] = useList(products);

  return (

    <div className="List">

      {products.map(product =>

        <Row

          key={product.id}

          title={product.title}

          isHighlighted={selected === product}

        />

      )}

      <hr />

      <button onClick={onNext}>

        Next

      </button>

    </div>

  );

}
```

The data flow is explicit, but the state is inside the `useList` custom Hook that you can use from any component:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import Row from './Row.js';
import useList from './useList.js';
import { products } from './data.js';

export default function App() {
  const [selected, onNext] = useList(products);
  return (
    <div className="List">
      {products.map(product =>
        <Row
          key={product.id}
          title={product.title}
          isHighlighted={selected === product}
        />
      )}
      <hr />
      <button onClick={onNext}>
        Next
      </button>
    </div>
  );
}
```

This approach is particularly useful if you want to reuse this logic between different components.

[PreviousChildren](/reference/react/Children)

[NextComponent](/reference/react/Component)

***

----
url: https://18.react.dev/learn/scaling-up-with-reducer-and-context
----

```
import { useReducer } from 'react';
import AddTask from './AddTask.js';
import TaskList from './TaskList.js';

export default function TaskApp() {
  const [tasks, dispatch] = useReducer(
    tasksReducer,
    initialTasks
  );

  function handleAddTask(text) {
    dispatch({
      type: 'added',
      id: nextId++,
      text: text,
    });
  }

  function handleChangeTask(task) {
    dispatch({
      type: 'changed',
      task: task
    });
  }

  function handleDeleteTask(taskId) {
    dispatch({
      type: 'deleted',
      id: taskId
    });
  }

  return (
    <>
      <h1>Day off in Kyoto</h1>
      <AddTask
        onAddTask={handleAddTask}
      />
      <TaskList
        tasks={tasks}
        onChangeTask={handleChangeTask}
        onDeleteTask={handleDeleteTask}
      />
    </>
  );
}

function tasksReducer(tasks, action) {
  switch (action.type) {
    case 'added': {
      return [...tasks, {
        id: action.id,
        text: action.text,
        done: false
      }];
    }
    case 'changed': {
      return tasks.map(t => {
        if (t.id === action.task.id) {
          return action.task;
        } else {
          return t;
        }
      });
    }
    case 'deleted': {
      return tasks.filter(t => t.id !== action.id);
    }
    default: {
      throw Error('Unknown action: ' + action.type);
    }
  }
}

let nextId = 3;
const initialTasks = [
  { id: 0, text: 'Philosopher’s Path', done: true },
  { id: 1, text: 'Visit the temple', done: false },
  { id: 2, text: 'Drink matcha', done: false }
];
```

A reducer helps keep the event handlers short and concise. However, as your app grows, you might run into another difficulty. **Currently, the `tasks` state and the `dispatch` function are only available in the top-level `TaskApp` component.** To let other components read the list of tasks or change it, you have to explicitly [pass down](/learn/passing-props-to-a-component) the current state and the event handlers that change it as props.

For example, `TaskApp` passes a list of tasks and the event handlers to `TaskList`:

```
<TaskList

  tasks={tasks}

  onChangeTask={handleChangeTask}

  onDeleteTask={handleDeleteTask}

/>
```

And `TaskList` passes the event handlers to `Task`:

```
<Task

  task={task}

  onChange={onChangeTask}

  onDelete={onDeleteTask}

/>
```

```
const [tasks, dispatch] = useReducer(tasksReducer, initialTasks);
```

To pass them down the tree, you will [create](/learn/passing-data-deeply-with-context#step-2-use-the-context) two separate contexts:

* `TasksContext` provides the current list of tasks.
* `TasksDispatchContext` provides the function that lets components dispatch actions.

Export them from a separate file so that you can later import them from other files:

```
import { createContext } from 'react';

export const TasksContext = createContext(null);
export const TasksDispatchContext = createContext(null);
```

Here, you’re passing `null` as the default value to both contexts. The actual values will be provided by the `TaskApp` component.

### Step 2: Put state and dispatch into context[](#step-2-put-state-and-dispatch-into-context "Link for Step 2: Put state and dispatch into context ")

Now you can import both contexts in your `TaskApp` component. Take the `tasks` and `dispatch` returned by `useReducer()` and [provide them](/learn/passing-data-deeply-with-context#step-3-provide-the-context) to the entire tree below:

```
import { TasksContext, TasksDispatchContext } from './TasksContext.js';



export default function TaskApp() {

  const [tasks, dispatch] = useReducer(tasksReducer, initialTasks);

  // ...

  return (

    <TasksContext.Provider value={tasks}>

      <TasksDispatchContext.Provider value={dispatch}>

        ...

      </TasksDispatchContext.Provider>

    </TasksContext.Provider>

  );

}
```

For now, you pass the information both via props and in context:

```
import { useReducer } from 'react';
import AddTask from './AddTask.js';
import TaskList from './TaskList.js';
import { TasksContext, TasksDispatchContext } from './TasksContext.js';

export default function TaskApp() {
  const [tasks, dispatch] = useReducer(
    tasksReducer,
    initialTasks
  );

  function handleAddTask(text) {
    dispatch({
      type: 'added',
      id: nextId++,
      text: text,
    });
  }

  function handleChangeTask(task) {
    dispatch({
      type: 'changed',
      task: task
    });
  }

  function handleDeleteTask(taskId) {
    dispatch({
      type: 'deleted',
      id: taskId
    });
  }

  return (
    <TasksContext.Provider value={tasks}>
      <TasksDispatchContext.Provider value={dispatch}>
        <h1>Day off in Kyoto</h1>
        <AddTask
          onAddTask={handleAddTask}
        />
        <TaskList
          tasks={tasks}
          onChangeTask={handleChangeTask}
          onDeleteTask={handleDeleteTask}
        />
      </TasksDispatchContext.Provider>
    </TasksContext.Provider>
  );
}

function tasksReducer(tasks, action) {
  switch (action.type) {
    case 'added': {
      return [...tasks, {
        id: action.id,
        text: action.text,
        done: false
      }];
    }
    case 'changed': {
      return tasks.map(t => {
        if (t.id === action.task.id) {
          return action.task;
        } else {
          return t;
        }
      });
    }
    case 'deleted': {
      return tasks.filter(t => t.id !== action.id);
    }
    default: {
      throw Error('Unknown action: ' + action.type);
    }
  }
}

let nextId = 3;
const initialTasks = [
  { id: 0, text: 'Philosopher’s Path', done: true },
  { id: 1, text: 'Visit the temple', done: false },
  { id: 2, text: 'Drink matcha', done: false }
];
```

In the next step, you will remove prop passing.

### Step 3: Use context anywhere in the tree[](#step-3-use-context-anywhere-in-the-tree "Link for Step 3: Use context anywhere in the tree ")

Now you don’t need to pass the list of tasks or the event handlers down the tree:

```
<TasksContext.Provider value={tasks}>

  <TasksDispatchContext.Provider value={dispatch}>

    <h1>Day off in Kyoto</h1>

    <AddTask />

    <TaskList />

  </TasksDispatchContext.Provider>

</TasksContext.Provider>
```

Instead, any component that needs the task list can read it from the `TaskContext`:

```
export default function TaskList() {

  const tasks = useContext(TasksContext);

  // ...
```

To update the task list, any component can read the `dispatch` function from context and call it:

```
export default function AddTask() {

  const [text, setText] = useState('');

  const dispatch = useContext(TasksDispatchContext);

  // ...

  return (

    // ...

    <button onClick={() => {

      setText('');

      dispatch({

        type: 'added',

        id: nextId++,

        text: text,

      });

    }}>Add</button>

    // ...
```

**The `TaskApp` component does not pass any event handlers down, and the `TaskList` does not pass any event handlers to the `Task` component either.** Each component reads the context that it needs:

```
import { useState, useContext } from 'react';
import { TasksContext, TasksDispatchContext } from './TasksContext.js';

export default function TaskList() {
  const tasks = useContext(TasksContext);
  return (
    <ul>
      {tasks.map(task => (
        <li key={task.id}>
          <Task task={task} />
        </li>
      ))}
    </ul>
  );
}

function Task({ task }) {
  const [isEditing, setIsEditing] = useState(false);
  const dispatch = useContext(TasksDispatchContext);
  let taskContent;
  if (isEditing) {
    taskContent = (
      <>
        <input
          value={task.text}
          onChange={e => {
            dispatch({
              type: 'changed',
              task: {
                ...task,
                text: e.target.value
              }
            });
          }} />
        <button onClick={() => setIsEditing(false)}>
          Save
        </button>
      </>
    );
  } else {
    taskContent = (
      <>
        {task.text}
        <button onClick={() => setIsEditing(true)}>
          Edit
        </button>
      </>
    );
  }
  return (
    <label>
      <input
        type="checkbox"
        checked={task.done}
        onChange={e => {
          dispatch({
            type: 'changed',
            task: {
              ...task,
              done: e.target.checked
            }
          });
        }}
      />
      {taskContent}
      <button onClick={() => {
        dispatch({
          type: 'deleted',
          id: task.id
        });
      }}>
        Delete
      </button>
    </label>
  );
}
```

**The state still “lives” in the top-level `TaskApp` component, managed with `useReducer`.** But its `tasks` and `dispatch` are now available to every component below in the tree by importing and using these contexts.

## Moving all wiring into a single file[](#moving-all-wiring-into-a-single-file "Link for Moving all wiring into a single file ")

You don’t have to do this, but you could further declutter the components by moving both reducer and context into a single file. Currently, `TasksContext.js` contains only two context declarations:

```
import { createContext } from 'react';



export const TasksContext = createContext(null);

export const TasksDispatchContext = createContext(null);
```

This file is about to get crowded! You’ll move the reducer into that same file. Then you’ll declare a new `TasksProvider` component in the same file. This component will tie all the pieces together:

1. It will manage the state with a reducer.
2. It will provide both contexts to components below.
3. It will [take `children` as a prop](/learn/passing-props-to-a-component#passing-jsx-as-children) so you can pass JSX to it.

```
export function TasksProvider({ children }) {

  const [tasks, dispatch] = useReducer(tasksReducer, initialTasks);



  return (

    <TasksContext.Provider value={tasks}>

      <TasksDispatchContext.Provider value={dispatch}>

        {children}

      </TasksDispatchContext.Provider>

    </TasksContext.Provider>

  );

}
```

**This removes all the complexity and wiring from your `TaskApp` component:**

```
import AddTask from './AddTask.js';
import TaskList from './TaskList.js';
import { TasksProvider } from './TasksContext.js';

export default function TaskApp() {
  return (
    <TasksProvider>
      <h1>Day off in Kyoto</h1>
      <AddTask />
      <TaskList />
    </TasksProvider>
  );
}
```

You can also export functions that *use* the context from `TasksContext.js`:

```
export function useTasks() {

  return useContext(TasksContext);

}



export function useTasksDispatch() {

  return useContext(TasksDispatchContext);

}
```

When a component needs to read context, it can do it through these functions:

```
const tasks = useTasks();

const dispatch = useTasksDispatch();
```

This doesn’t change the behavior in any way, but it lets you later split these contexts further or add some logic to these functions. **Now all of the context and reducer wiring is in `TasksContext.js`. This keeps the components clean and uncluttered, focused on what they display rather than where they get the data:**

```
import { useState } from 'react';
import { useTasks, useTasksDispatch } from './TasksContext.js';

export default function TaskList() {
  const tasks = useTasks();
  return (
    <ul>
      {tasks.map(task => (
        <li key={task.id}>
          <Task task={task} />
        </li>
      ))}
    </ul>
  );
}

function Task({ task }) {
  const [isEditing, setIsEditing] = useState(false);
  const dispatch = useTasksDispatch();
  let taskContent;
  if (isEditing) {
    taskContent = (
      <>
        <input
          value={task.text}
          onChange={e => {
            dispatch({
              type: 'changed',
              task: {
                ...task,
                text: e.target.value
              }
            });
          }} />
        <button onClick={() => setIsEditing(false)}>
          Save
        </button>
      </>
    );
  } else {
    taskContent = (
      <>
        {task.text}
        <button onClick={() => setIsEditing(true)}>
          Edit
        </button>
      </>
    );
  }
  return (
    <label>
      <input
        type="checkbox"
        checked={task.done}
        onChange={e => {
          dispatch({
            type: 'changed',
            task: {
              ...task,
              done: e.target.checked
            }
          });
        }}
      />
      {taskContent}
      <button onClick={() => {
        dispatch({
          type: 'deleted',
          id: task.id
        });
      }}>
        Delete
      </button>
    </label>
  );
}
```

***

----
url: https://legacy.reactjs.org/blog/2016/03/29/react-v0.14.8.html
----

March 29, 2016 by [Dan Abramov](https://twitter.com/dan_abramov)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

We have already released two release candidates for React 15, and the final version is coming soon.

However [Ian Christian Myers](https://github.com/iancmyers) discovered a memory leak related to server rendering in React 0.14 and [contributed a fix](https://github.com/facebook/react/pull/6060). While this memory leak has already been fixed in a different way in the React 15 release candidates, we decided to cut another 0.14 release that contains just this fix.

The release is now available for download:

* **React**\
  Dev build with warnings: <https://fb.me/react-0.14.8.js>\
  Minified build for production: <https://fb.me/react-0.14.8.min.js>
* **React with Add-Ons**\
  Dev build with warnings: <https://fb.me/react-with-addons-0.14.8.js>\
  Minified build for production: <https://fb.me/react-with-addons-0.14.8.min.js>
* **React DOM** (include React in the page before React DOM)\
  Dev build with warnings: <https://fb.me/react-dom-0.14.8.js>\
  Minified build for production: <https://fb.me/react-dom-0.14.8.min.js>
* **React DOM Server** (include React in the page before React DOM Server)\
  Dev build with warnings: <https://fb.me/react-dom-server-0.14.8.js>\
  Minified build for production: <https://fb.me/react-dom-server-0.14.8.min.js>

We’ve also published version `0.14.8` of the `react`, `react-dom`, and addons packages on npm and the `react` package on bower.

***

## [](#changelog)Changelog

### [](#react)React

* Fixed memory leak when rendering on the server

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2016-03-29-react-v0.14.8.md)

----
url: https://legacy.reactjs.org/blog/2017/09/26/react-v16.0.html
----

September 26, 2017 by [Andrew Clark](https://twitter.com/acdlite)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

We’re excited to announce the release of React v16.0! Among the changes are some long-standing feature requests, including [**fragments**](#new-render-return-types-fragments-and-strings), [**error boundaries**](#better-error-handling), [**portals**](#portals), support for [**custom DOM attributes**](#support-for-custom-dom-attributes), improved [**server-side rendering**](#better-server-side-rendering), and [**reduced file size**](#reduced-file-size).

### [](#new-render-return-types-fragments-and-strings)New render return types: fragments and strings

You can now return an array of elements from a component’s `render` method. Like with other arrays, you’ll need to add a key to each element to avoid the key warning:

```
render() {
  // No need to wrap list items in an extra element!
  return [
    // Don't forget the keys :)
    <li key="A">First item</li>,
    <li key="B">Second item</li>,
    <li key="C">Third item</li>,
  ];
}
```

[Starting with React 16.2.0](/blog/2017/11/28/react-v16.2.0-fragment-support.html), we are adding support for a special fragment syntax to JSX that doesn’t require keys.

We’ve added support for returning strings, too:

```
render() {
  return 'Look ma, no spans!';
}
```

[See the full list of supported return types](/docs/react-component.html#render).

### [](#better-error-handling)Better error handling

Previously, runtime errors during rendering could put React in a broken state, producing cryptic error messages and requiring a page refresh to recover. To address this problem, React 16 uses a more resilient error-handling strategy. By default, if an error is thrown inside a component’s render or lifecycle methods, the whole component tree is unmounted from the root. This prevents the display of corrupted data. However, it’s probably not the ideal user experience.

Instead of unmounting the whole app every time there’s an error, you can use error boundaries. Error boundaries are special components that capture errors inside their subtree and display a fallback UI in its place. Think of error boundaries like try-catch statements, but for React components.

For more details, check out our [previous post on error handling in React 16](/blog/2017/07/26/error-handling-in-react-16.html).

### [](#portals)Portals

Portals provide a first-class way to render children into a DOM node that exists outside the DOM hierarchy of the parent component.

```
render() {
  // React does *not* create a new div. It renders the children into `domNode`.
  // `domNode` is any valid DOM node, regardless of its location in the DOM.
  return ReactDOM.createPortal(
    this.props.children,
    domNode,
  );
}
```

See a full example in the [documentation for portals](/docs/portals.html).

### [](#better-server-side-rendering)Better server-side rendering

React 16 includes a completely rewritten server renderer. It’s really fast. It supports **streaming**, so you can start sending bytes to the client faster. And thanks to a [new packaging strategy](#reduced-file-size) that compiles away `process.env` checks (Believe it or not, reading `process.env` in Node is really slow!), you no longer need to bundle React to get good server-rendering performance.

Core team member Sasha Aickin wrote a [great article describing React 16’s SSR improvements](https://medium.com/@aickin/whats-new-with-server-side-rendering-in-react-16-9b0d78585d67). According to Sasha’s synthetic benchmarks, server rendering in React 16 is roughly **three times faster** than React 15. “When comparing against React 15 with `process.env` compiled out, there’s about a 2.4x improvement in Node 4, about a 3x performance improvement in Node 6, and a full 3.8x improvement in the new Node 8.4 release. And if you compare against React 15 without compilation, React 16 has a full order of magnitude gain in SSR in the latest version of Node!” (As Sasha points out, please be aware that these numbers are based on synthetic benchmarks and may not reflect real-world performance.)

In addition, React 16 is better at hydrating server-rendered HTML once it reaches the client. It no longer requires the initial render to exactly match the result from the server. Instead, it will attempt to reuse as much of the existing DOM as possible. No more checksums! In general, we don’t recommend that you render different content on the client versus the server, but it can be useful in some cases (e.g. timestamps). **However, it’s dangerous to have missing nodes on the server render as this might cause sibling nodes to be created with incorrect attributes.**

See the [documentation for `ReactDOMServer`](/docs/react-dom-server.html) for more details.

### [](#support-for-custom-dom-attributes)Support for custom DOM attributes

Instead of ignoring unrecognized HTML and SVG attributes, React will now [pass them through to the DOM](/blog/2017/09/08/dom-attributes-in-react-16.html). This has the added benefit of allowing us to get rid of most of React’s attribute whitelist, resulting in reduced file sizes.

### [](#reduced-file-size)Reduced file size

Despite all these additions, React 16 is actually **smaller** compared to 15.6.1!

* `react` is 5.3 kb (2.2 kb gzipped), down from 20.7 kb (6.9 kb gzipped).
* `react-dom` is 103.7 kb (32.6 kb gzipped), down from 141 kb (42.9 kb gzipped).
* `react` + `react-dom` is 109 kb (34.8 kb gzipped), down from 161.7 kb (49.8 kb gzipped).

That amounts to a combined **32% size decrease compared to the previous version (30% post-gzip)**.

The size difference is partly attributable to a change in packaging. React now uses [Rollup](https://rollupjs.org/) to create flat bundles for each of its different target formats, resulting in both size and runtime performance wins. The flat bundle format also means that React’s impact on bundle size is roughly consistent regardless of how you ship your app, whether it’s with Webpack, Browserify, the pre-built UMD bundles, or any other system.

### [](#mit-licensed)MIT licensed

[In case you missed it](https://code.facebook.com/posts/300798627056246/relicensing-react-jest-flow-and-immutable-js/), React 16 is available under the MIT license. We’ve also published React 15.6.2 under MIT, for those who are unable to upgrade immediately.

### [](#new-core-architecture)New core architecture

React 16 is the first version of React built on top of a new core architecture, codenamed “Fiber.” You can read all about this project over on [Facebook’s engineering blog](https://code.facebook.com/posts/1716776591680069/react-16-a-look-inside-an-api-compatible-rewrite-of-our-frontend-ui-library/). (Spoiler: we rewrote React!)

Fiber is responsible for most of the new features in React 16, like error boundaries and fragments. Over the next few releases, you can expect more new features as we begin to unlock the full potential of React.

Perhaps the most exciting area we’re working on is **async rendering**—a strategy for cooperatively scheduling rendering work by periodically yielding execution to the browser. The upshot is that, with async rendering, apps are more responsive because React avoids blocking the main thread.

This demo provides an early peek at the types of problems async rendering can solve:

> Ever wonder what "async rendering" means? Here's a demo of how to coordinate an async React tree with non-React work <https://t.co/3snoahB3uV> [pic.twitter.com/egQ988gBjR](https://t.co/egQ988gBjR)
>
> — Andrew Clark (@acdlite) [September 18, 2017](https://twitter.com/acdlite/status/909926793536094209)

*Tip: Pay attention to the spinning black square.*

We think async rendering is a big deal, and represents the future of React. To make migration to v16.0 as smooth as possible, we’re not enabling any async features yet, but we’re excited to start rolling them out in the coming months. Stay tuned!

## [](#installation)Installation

React v16.0.0 is available on the npm registry.

To install React 16 with Yarn, run:

```
yarn add react@^16.0.0 react-dom@^16.0.0
```

To install React 16 with npm, run:

```
npm install --save react@^16.0.0 react-dom@^16.0.0
```

We also provide UMD builds of React via a CDN:

```
<script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
```

Refer to the documentation for [detailed installation instructions](/docs/installation.html).

## [](#upgrading)Upgrading

Although React 16 includes significant internal changes, in terms of upgrading, you can think of this like any other major React release. We’ve been serving React 16 to Facebook and Messenger.com users since earlier this year, and we released several beta and release candidate versions to flush out additional issues. With minor exceptions, **if your app runs in 15.6 without any warnings, it should work in 16.**

For deprecations listed in [packaging](#packaging) below, codemods are provided to automatically transform your deprecated code. See the [15.5.0](/blog/2017/04/07/react-v15.5.0.html) blog post for more information, or browse the codemods in the [react-codemod](https://github.com/reactjs/react-codemod) project.

### [](#new-deprecations)New deprecations

Hydrating a server-rendered container now has an explicit API. If you’re reviving server-rendered HTML, use [`ReactDOM.hydrate`](/docs/react-dom.html#hydrate) instead of `ReactDOM.render`. Keep using `ReactDOM.render` if you’re just doing client-side rendering.

### [](#react-addons)React Addons

As previously announced, we’ve [discontinued support for React Addons](/blog/2017/04/07/react-v15.5.0.html#discontinuing-support-for-react-addons). We expect the latest version of each addon (except `react-addons-perf`; see below) to work for the foreseeable future, but we won’t publish additional updates.

Refer to the previous announcement for [suggestions on how to migrate](/blog/2017/04/07/react-v15.5.0.html#discontinuing-support-for-react-addons).

`react-addons-perf` no longer works at all in React 16. It’s likely that we’ll release a new version of this tool in the future. In the meantime, you can [use your browser’s performance tools to profile React components](/docs/optimizing-performance.html#profiling-components-with-the-chrome-performance-tab).

### [](#breaking-changes)Breaking changes

React 16 includes a number of small breaking changes. These only affect uncommon use cases and we don’t expect them to break most apps.

* React 15 had limited, undocumented support for error boundaries using `unstable_handleError`. This method has been renamed to `componentDidCatch`. You can use a codemod to [automatically migrate to the new API](https://github.com/reactjs/react-codemod#error-boundaries).

* `ReactDOM.render` and `ReactDOM.unstable_renderSubtreeIntoContainer` now return null if called from inside a lifecycle method. To work around this, you can use [portals](https://github.com/facebook/react/issues/10309#issuecomment-318433235) or [refs](https://github.com/facebook/react/issues/10309#issuecomment-318434635).

* `setState`:

  * Calling `setState` with null no longer triggers an update. This allows you to decide in an updater function if you want to re-render.
  * Calling `setState` directly in render always causes an update. This was not previously the case. Regardless, you should not be calling setState from render.
  * `setState` callbacks (second argument) now fire immediately after `componentDidMount` / `componentDidUpdate` instead of after all components have rendered.

* When replacing `<A />` with `<B />`, `B.componentWillMount` now always happens before `A.componentWillUnmount`. Previously, `A.componentWillUnmount` could fire first in some cases.

* Previously, changing the ref to a component would always detach the ref before that component’s render is called. Now, we change the ref later, when applying the changes to the DOM.

* It is not safe to re-render into a container that was modified by something other than React. This worked previously in some cases but was never supported. We now emit a warning in this case. Instead you should clean up your component trees using `ReactDOM.unmountComponentAtNode`. [See this example.](https://github.com/facebook/react/issues/10294#issuecomment-318820987)

* `componentDidUpdate` lifecycle no longer receives `prevContext` param. (See [#8631](https://github.com/facebook/react/issues/8631))

* Shallow renderer no longer calls `componentDidUpdate` because DOM refs are not available. This also makes it consistent with `componentDidMount` (which does not get called in previous versions either).

* Shallow renderer does not implement `unstable_batchedUpdates` anymore.

* `ReactDOM.unstable_batchedUpdates` now only takes one extra argument after the callback.

### [](#packaging)Packaging

* There is no `react/lib/*` and `react-dom/lib/*` anymore. Even in CommonJS environments, React and ReactDOM are precompiled to single files (“flat bundles”). If you previously relied on undocumented React internals, and they don’t work anymore, let us know about your specific case in a new issue, and we’ll try to figure out a migration strategy for you.

* There is no `react-with-addons.js` build anymore. All compatible addons are published separately on npm, and have single-file browser versions if you need them.

* The deprecations introduced in 15.x have been removed from the core package. `React.createClass` is now available as `create-react-class`, `React.PropTypes` as `prop-types`, `React.DOM` as `react-dom-factories`, `react-addons-test-utils` as `react-dom/test-utils`, and shallow renderer as `react-test-renderer/shallow`. See [15.5.0](/blog/2017/04/07/react-v15.5.0.html) and [15.6.0](/blog/2017/06/13/react-v15.6.0.html) blog posts for instructions on migrating code and automated codemods.

* The names and paths to the single-file browser builds have changed to emphasize the difference between development and production builds. For example:

  * `react/dist/react.js` → `react/umd/react.development.js`
  * `react/dist/react.min.js` → `react/umd/react.production.min.js`
  * `react-dom/dist/react-dom.js` → `react-dom/umd/react-dom.development.js`
  * `react-dom/dist/react-dom.min`.js → `react-dom/umd/react-dom.production.min.js`

## [](#javascript-environment-requirements)JavaScript Environment Requirements

React 16 depends on the collection types [Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) and [Set](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set). If you support older browsers and devices which may not yet provide these natively (e.g. IE < 11), consider including a global polyfill in your bundled application, such as [core-js](https://github.com/zloirock/core-js) or [babel-polyfill](https://babeljs.io/docs/usage/polyfill/).

A polyfilled environment for React 16 using core-js to support older browsers might look like:

```
import 'core-js/es6/map';
import 'core-js/es6/set';

import React from 'react';
import ReactDOM from 'react-dom';

ReactDOM.render(
  <h1>Hello, world!</h1>,
  document.getElementById('root')
);
```

React also depends on `requestAnimationFrame` (even in test environments).\
You can use the [raf](https://www.npmjs.com/package/raf) package to shim `requestAnimationFrame`:

```
import 'raf/polyfill';
```

## [](#acknowledgments)Acknowledgments

As always, this release would not have been possible without our open source contributors. Thanks to everyone who filed bugs, opened PRs, responded to issues, wrote documentation, and more!

Special thanks to our core contributors, especially for their heroic efforts over the past few weeks during the prerelease cycle: [Brandon Dail](https://twitter.com/aweary), [Jason Quense](https://twitter.com/monasticpanic), [Nathan Hunzaker](https://twitter.com/natehunzaker), and [Sasha Aickin](https://twitter.com/xander76).

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2017-09-26-react-v16.0.md)

----
url: https://react.dev/learn/importing-and-exporting-components
----

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
function Profile() {
  return (
    <img
      src="https://react.dev/images/docs/scientists/MK3eW3As.jpg"
      alt="Katherine Johnson"
    />
  );
}

export default function Gallery() {
  return (
    <section>
      <h1>Amazing scientists</h1>
      <Profile />
      <Profile />
      <Profile />
    </section>
  );
}
```

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import Gallery from './Gallery.js';

export default function App() {
  return (
    <Gallery />
  );
}
```

```
import Gallery from './Gallery';
```

Either `'./Gallery.js'` or `'./Gallery'` will work with React, though the former is closer to how [native ES Modules](https://developer.mozilla.org/docs/Web/JavaScript/Guide/Modules) work.

##### Deep Dive#### Default vs named exports[](#default-vs-named-exports "Link for Default vs named exports ")

There are two primary ways to export values with JavaScript: default exports and named exports. So far, our examples have only used default exports. But you can use one or both of them in the same file. **A file can have no more than one *default* export, but it can have as many *named* exports as you like.**

How you export your component dictates how you must import it. You will get an error if you try to import a default export the same way you would a named export! This chart can help you keep track:

| Syntax  | Export statement                      | Import statement                        |
| ------- | ------------------------------------- | --------------------------------------- |
| Default | `export default function Button() {}` | `import Button from './Button.js';`     |
| Named   | `export function Button() {}`         | `import { Button } from './Button.js';` |

```
export function Profile() {

  // ...

}
```

Then, **import** `Profile` from `Gallery.js` to `App.js` using a named import (with the curly braces):

```
import { Profile } from './Gallery.js';
```

Finally, **render** `<Profile />` from the `App` component:

```
export default function App() {

  return <Profile />;

}
```

Now `Gallery.js` contains two exports: a default `Gallery` export, and a named `Profile` export. `App.js` imports both of them. Try editing `<Profile />` to `<Gallery />` and back in this example:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import Gallery from './Gallery.js';
import { Profile } from './Gallery.js';

export default function App() {
  return (
    <Profile />
  );
}
```

| Syntax  | Export statement                      | Import statement                        |
| ------- | ------------------------------------- | --------------------------------------- |
| Default | `export default function Button() {}` | `import Button from './Button.js';`     |
| Named   | `export function Button() {}`         | `import { Button } from './Button.js';` |

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
// Move me to Profile.js!
export function Profile() {
  return (
    <img
      src="https://react.dev/images/docs/scientists/QIrZWGIs.jpg"
      alt="Alan L. Hart"
    />
  );
}

export default function Gallery() {
  return (
    <section>
      <h1>Amazing scientists</h1>
      <Profile />
      <Profile />
      <Profile />
    </section>
  );
}
```

After you get it working with one kind of exports, make it work with the other kind.

[PreviousYour First Component](/learn/your-first-component)

[NextWriting Markup with JSX](/learn/writing-markup-with-jsx)

***

----
url: https://react.dev/reference/react-dom/client
----

[API Reference](/reference/react)

# Client React DOM APIs[](#undefined "Link for this heading")

The `react-dom/client` APIs let you render React components on the client (in the browser). These APIs are typically used at the top level of your app to initialize your React tree. A [framework](/learn/creating-a-react-app#full-stack-frameworks) may call them for you. Most of your components don’t need to import or use them.

***

## Client APIs[](#client-apis "Link for Client APIs ")

* [`createRoot`](/reference/react-dom/client/createRoot) lets you create a root to display React components inside a browser DOM node.
* [`hydrateRoot`](/reference/react-dom/client/hydrateRoot) lets you display React components inside a browser DOM node whose HTML content was previously generated by [`react-dom/server`.](/reference/react-dom/server)

***

## Browser support[](#browser-support "Link for Browser support ")

React supports all popular browsers, including Internet Explorer 9 and above. Some polyfills are required for older browsers such as IE 9 and IE 10.

[PreviouspreloadModule](/reference/react-dom/preloadModule)

[NextcreateRoot](/reference/react-dom/client/createRoot)

***

----
url: https://legacy.reactjs.org/docs/refs-and-the-dom.html
----

> These docs are old and won’t be updated. Go to [react.dev](https://react.dev/) for the new React docs.
>
> These new documentation pages teach modern React and include live examples:
>
> * [Referencing Values with Refs](https://react.dev/learn/referencing-values-with-refs)
> * [Manipulating the DOM with Refs](https://react.dev/learn/manipulating-the-dom-with-refs)
> * [`useRef`](https://react.dev/reference/react/useRef)
> * [`forwardRef`](https://react.dev/reference/react/forwardRef)

Refs provide a way to access DOM nodes or React elements created in the render method.

In the typical React dataflow, [props](/docs/components-and-props.html) are the only way that parent components interact with their children. To modify a child, you re-render it with new props. However, there are a few cases where you need to imperatively modify a child outside of the typical dataflow. The child to be modified could be an instance of a React component, or it could be a DOM element. For both of these cases, React provides an escape hatch.

### [](#when-to-use-refs)When to Use Refs

There are a few good use cases for refs:

* Managing focus, text selection, or media playback.
* Triggering imperative animations.
* Integrating with third-party DOM libraries.

Avoid using refs for anything that can be done declaratively.

For example, instead of exposing `open()` and `close()` methods on a `Dialog` component, pass an `isOpen` prop to it.

### [](#dont-overuse-refs)Don’t Overuse Refs

Your first inclination may be to use refs to “make things happen” in your app. If this is the case, take a moment and think more critically about where state should be owned in the component hierarchy. Often, it becomes clear that the proper place to “own” that state is at a higher level in the hierarchy. See the [Lifting State Up](/docs/lifting-state-up.html) guide for examples of this.

> Note
>
> The examples below have been updated to use the `React.createRef()` API introduced in React 16.3. If you are using an earlier release of React, we recommend using [callback refs](#callback-refs) instead.

### [](#creating-refs)Creating Refs

Refs are created using `React.createRef()` and attached to React elements via the `ref` attribute. Refs are commonly assigned to an instance property when a component is constructed so they can be referenced throughout the component.

```
class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.myRef = React.createRef();  }
  render() {
    return <div ref={this.myRef} />;  }
}
```

### [](#accessing-refs)Accessing Refs

When a ref is passed to an element in `render`, a reference to the node becomes accessible at the `current` attribute of the ref.

```
const node = this.myRef.current;
```

The value of the ref differs depending on the type of the node:

* When the `ref` attribute is used on an HTML element, the `ref` created in the constructor with `React.createRef()` receives the underlying DOM element as its `current` property.
* When the `ref` attribute is used on a custom class component, the `ref` object receives the mounted instance of the component as its `current`.
* **You may not use the `ref` attribute on function components** because they don’t have instances.

The examples below demonstrate the differences.

#### [](#adding-a-ref-to-a-dom-element)Adding a Ref to a DOM Element

This code uses a `ref` to store a reference to a DOM node:

```
class CustomTextInput extends React.Component {
  constructor(props) {
    super(props);
    // create a ref to store the textInput DOM element
    this.textInput = React.createRef();    this.focusTextInput = this.focusTextInput.bind(this);
  }

  focusTextInput() {
    // Explicitly focus the text input using the raw DOM API
    // Note: we're accessing "current" to get the DOM node
    this.textInput.current.focus();  }

  render() {
    // tell React that we want to associate the <input> ref
    // with the `textInput` that we created in the constructor
    return (
      <div>
        <input
          type="text"
          ref={this.textInput} />        <input
          type="button"
          value="Focus the text input"
          onClick={this.focusTextInput}
        />
      </div>
    );
  }
}
```

React will assign the `current` property with the DOM element when the component mounts, and assign it back to `null` when it unmounts. `ref` updates happen before `componentDidMount` or `componentDidUpdate` lifecycle methods.

#### [](#adding-a-ref-to-a-class-component)Adding a Ref to a Class Component

If we wanted to wrap the `CustomTextInput` above to simulate it being clicked immediately after mounting, we could use a ref to get access to the custom input and call its `focusTextInput` method manually:

```
class AutoFocusTextInput extends React.Component {
  constructor(props) {
    super(props);
    this.textInput = React.createRef();  }

  componentDidMount() {
    this.textInput.current.focusTextInput();  }

  render() {
    return (
      <CustomTextInput ref={this.textInput} />    );
  }
}
```

Note that this only works if `CustomTextInput` is declared as a class:

```
class CustomTextInput extends React.Component {  // ...
}
```

#### [](#refs-and-function-components)Refs and Function Components

By default, **you may not use the `ref` attribute on function components** because they don’t have instances:

```
function MyFunctionComponent() {  return <input />;
}

class Parent extends React.Component {
  constructor(props) {
    super(props);
    this.textInput = React.createRef();  }
  render() {
    // This will *not* work!
    return (
      <MyFunctionComponent ref={this.textInput} />    );
  }
}
```

If you want to allow people to take a `ref` to your function component, you can use [`forwardRef`](/docs/forwarding-refs.html) (possibly in conjunction with [`useImperativeHandle`](/docs/hooks-reference.html#useimperativehandle)), or you can convert the component to a class.

You can, however, **use the `ref` attribute inside a function component** as long as you refer to a DOM element or a class component:

```
function CustomTextInput(props) {
  // textInput must be declared here so the ref can refer to it  const textInput = useRef(null);  
  function handleClick() {
    textInput.current.focus();  }

  return (
    <div>
      <input
        type="text"
        ref={textInput} />      <input
        type="button"
        value="Focus the text input"
        onClick={handleClick}
      />
    </div>
  );
}
```

### [](#exposing-dom-refs-to-parent-components)Exposing DOM Refs to Parent Components

In rare cases, you might want to have access to a child’s DOM node from a parent component. This is generally not recommended because it breaks component encapsulation, but it can occasionally be useful for triggering focus or measuring the size or position of a child DOM node.

While you could [add a ref to the child component](#adding-a-ref-to-a-class-component), this is not an ideal solution, as you would only get a component instance rather than a DOM node. Additionally, this wouldn’t work with function components.

If you use React 16.3 or higher, we recommend to use [ref forwarding](/docs/forwarding-refs.html) for these cases. **Ref forwarding lets components opt into exposing any child component’s ref as their own**. You can find a detailed example of how to expose a child’s DOM node to a parent component [in the ref forwarding documentation](/docs/forwarding-refs.html#forwarding-refs-to-dom-components).

If you use React 16.2 or lower, or if you need more flexibility than provided by ref forwarding, you can use [this alternative approach](https://gist.github.com/gaearon/1a018a023347fe1c2476073330cc5509) and explicitly pass a ref as a differently named prop.

When possible, we advise against exposing DOM nodes, but it can be a useful escape hatch. Note that this approach requires you to add some code to the child component. If you have absolutely no control over the child component implementation, your last option is to use [`findDOMNode()`](/docs/react-dom.html#finddomnode), but it is discouraged and deprecated in [`StrictMode`](/docs/strict-mode.html#warning-about-deprecated-finddomnode-usage).

### [](#callback-refs)Callback Refs

React also supports another way to set refs called “callback refs”, which gives more fine-grain control over when refs are set and unset.

Instead of passing a `ref` attribute created by `createRef()`, you pass a function. The function receives the React component instance or HTML DOM element as its argument, which can be stored and accessed elsewhere.

The example below implements a common pattern: using the `ref` callback to store a reference to a DOM node in an instance property.

```
class CustomTextInput extends React.Component {
  constructor(props) {
    super(props);

    this.textInput = null;
    this.setTextInputRef = element => {      this.textInput = element;    };
    this.focusTextInput = () => {      // Focus the text input using the raw DOM API      if (this.textInput) this.textInput.focus();    };  }

  componentDidMount() {
    // autofocus the input on mount
    this.focusTextInput();  }

  render() {
    // Use the `ref` callback to store a reference to the text input DOM
    // element in an instance field (for example, this.textInput).
    return (
      <div>
        <input
          type="text"
          ref={this.setTextInputRef}        />
        <input
          type="button"
          value="Focus the text input"
          onClick={this.focusTextInput}        />
      </div>
    );
  }
}
```

React will call the `ref` callback with the DOM element when the component mounts, and call it with `null` when it unmounts. Refs are guaranteed to be up-to-date before `componentDidMount` or `componentDidUpdate` fires.

You can pass callback refs between components like you can with object refs that were created with `React.createRef()`.

```
function CustomTextInput(props) {
  return (
    <div>
      <input ref={props.inputRef} />    </div>
  );
}

class Parent extends React.Component {
  render() {
    return (
      <CustomTextInput
        inputRef={el => this.inputElement = el}      />
    );
  }
}
```

In the example above, `Parent` passes its ref callback as an `inputRef` prop to the `CustomTextInput`, and the `CustomTextInput` passes the same function as a special `ref` attribute to the `<input>`. As a result, `this.inputElement` in `Parent` will be set to the DOM node corresponding to the `<input>` element in the `CustomTextInput`.

### [](#legacy-api-string-refs)Legacy API: String Refs

If you worked with React before, you might be familiar with an older API where the `ref` attribute is a string, like `"textInput"`, and the DOM node is accessed as `this.refs.textInput`. We advise against it because string refs have [some issues](https://github.com/facebook/react/pull/8333#issuecomment-271648615), are considered legacy, and **are likely to be removed in one of the future releases**.

> Note
>
> If you’re currently using `this.refs.textInput` to access refs, we recommend using either the [callback pattern](#callback-refs) or the [`createRef` API](#creating-refs) instead.

### [](#caveats-with-callback-refs)Caveats with callback refs

If the `ref` callback is defined as an inline function, it will get called twice during updates, first with `null` and then again with the DOM element. This is because a new instance of the function is created with each render, so React needs to clear the old ref and set up the new one. You can avoid this by defining the `ref` callback as a bound method on the class, but note that it shouldn’t matter in most cases.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/refs-and-the-dom.md)

----
url: https://legacy.reactjs.org/blog/2015/05/22/react-native-release-process.html
----

May 22, 2015 by [Vjeux](https://twitter.com/vjeux)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

The React Native release process have been a bit chaotic since we open sourced. It was unclear when new code was released, there was no changelog, we bumped the minor and patch version inconsistently and we often had to submit updates right after a release to fix a bad bug. In order to *move fast with stable infra*, we are introducing a real release process with a two-week release schedule.

To explain how it works, let me walk you through an example. Today, Friday, we took the current state of master and put it on the 0.5-stable branch. We [published 0.5.0-rc](https://github.com/facebook/react-native/releases/tag/v0.5.0-rc), an RC (Release Candidate) when we cut the branch. For two weeks, we’re going to let it stabilize and only cherry-pick critical bug fixes from master.

Friday in two weeks, we’re going to publish the 0.5.0 release, create the 0.6-stable branch and publish 0.6.0-rc as well.

The release process is synchronized with Facebook’s mobile release process. This means that everything in the open source release is also being shipped as part of all the Facebook apps that use React Native!

You now have three ways to get React Native. You should chose the one you want based on the amount of risk you tolerate:

* **master**: You have updates as soon as they are committed. This is if you want to live on the bleeding edge or want to submit pull requests.
* **rc**: If you don’t want to update every day and deal with many instabilities but want to have recent updates, this is your best shot.
* **release**: This is the most stable version we offer. The trade-off is that it contains commits that are up to a month old.

If you want more details, I highly recommend this video that explains how Facebook mobile release process works and why it was setup this way.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2015-05-22-react-native-release-process.md)

----
url: https://18.react.dev/reference/react/createContext
----

[API Reference](/reference/react)

[APIs](/reference/react/apis)

# createContext[](#undefined "Link for this heading")

`createContext` lets you create a [context](/learn/passing-data-deeply-with-context) that components can provide or read.

```
const SomeContext = createContext(defaultValue)
```

* [Reference](#reference)

  * [`createContext(defaultValue)`](#createcontext)
  * [`SomeContext.Provider`](#provider)
  * [`SomeContext.Consumer`](#consumer)

* [Usage](#usage)

  * [Creating context](#creating-context)
  * [Importing and exporting context from a file](#importing-and-exporting-context-from-a-file)

* [Troubleshooting](#troubleshooting)
  * [I can’t find a way to change the context value](#i-cant-find-a-way-to-change-the-context-value)

***

## Reference[](#reference "Link for Reference ")

### `createContext(defaultValue)`[](#createcontext "Link for this heading")

Call `createContext` outside of any components to create a context.

```
import { createContext } from 'react';



const ThemeContext = createContext('light');
```

[See more examples below.](#usage)

#### Parameters[](#parameters "Link for Parameters ")

* `defaultValue`: The value that you want the context to have when there is no matching context provider in the tree above the component that reads context. If you don’t have any meaningful default value, specify `null`. The default value is meant as a “last resort” fallback. It is static and never changes over time.

#### Returns[](#returns "Link for Returns ")

`createContext` returns a context object.

**The context object itself does not hold any information.** It represents *which* context other components read or provide. Typically, you will use [`SomeContext.Provider`](#provider) in components above to specify the context value, and call [`useContext(SomeContext)`](/reference/react/useContext) in components below to read it. The context object has a few properties:

* `SomeContext.Provider` lets you provide the context value to components.
* `SomeContext.Consumer` is an alternative and rarely used way to read the context value.

***

### `SomeContext.Provider`[](#provider "Link for this heading")

Wrap your components into a context provider to specify the value of this context for all components inside:

```
function App() {

  const [theme, setTheme] = useState('light');

  // ...

  return (

    <ThemeContext.Provider value={theme}>

      <Page />

    </ThemeContext.Provider>

  );

}
```

#### Props[](#provider-props "Link for Props ")

* `value`: The value that you want to pass to all the components reading this context inside this provider, no matter how deep. The context value can be of any type. A component calling [`useContext(SomeContext)`](/reference/react/useContext) inside of the provider receives the `value` of the innermost corresponding context provider above it.

***

### `SomeContext.Consumer`[](#consumer "Link for this heading")

Before `useContext` existed, there was an older way to read context:

```
function Button() {

  // 🟡 Legacy way (not recommended)

  return (

    <ThemeContext.Consumer>

      {theme => (

        <button className={theme} />

      )}

    </ThemeContext.Consumer>

  );

}
```

Although this older way still works, but **newly written code should read context with [`useContext()`](/reference/react/useContext) instead:**

```
function Button() {

  // ✅ Recommended way

  const theme = useContext(ThemeContext);

  return <button className={theme} />;

}
```

#### Props[](#consumer-props "Link for Props ")

* `children`: A function. React will call the function you pass with the current context value determined by the same algorithm as [`useContext()`](/reference/react/useContext) does, and render the result you return from this function. React will also re-run this function and update the UI whenever the context from the parent components changes.

***

## Usage[](#usage "Link for Usage ")

### Creating context[](#creating-context "Link for Creating context ")

Context lets components [pass information deep down](/learn/passing-data-deeply-with-context) without explicitly passing props.

Call `createContext` outside any components to create one or more contexts.

```
import { createContext } from 'react';



const ThemeContext = createContext('light');

const AuthContext = createContext(null);
```

`createContext` returns a context object. Components can read context by passing it to [`useContext()`](/reference/react/useContext):

```
function Button() {

  const theme = useContext(ThemeContext);

  // ...

}



function Profile() {

  const currentUser = useContext(AuthContext);

  // ...

}
```

By default, the values they receive will be the default values you have specified when creating the contexts. However, by itself this isn’t useful because the default values never change.

Context is useful because you can **provide other, dynamic values from your components:**

```
function App() {

  const [theme, setTheme] = useState('dark');

  const [currentUser, setCurrentUser] = useState({ name: 'Taylor' });



  // ...



  return (

    <ThemeContext.Provider value={theme}>

      <AuthContext.Provider value={currentUser}>

        <Page />

      </AuthContext.Provider>

    </ThemeContext.Provider>

  );

}
```

Now the `Page` component and any components inside it, no matter how deep, will “see” the passed context values. If the passed context values change, React will re-render the components reading the context as well.

[Read more about reading and providing context and see examples.](/reference/react/useContext)

***

### Importing and exporting context from a file[](#importing-and-exporting-context-from-a-file "Link for Importing and exporting context from a file ")

Often, components in different files will need access to the same context. This is why it’s common to declare contexts in a separate file. Then you can use the [`export` statement](https://developer.mozilla.org/en-US/docs/web/javascript/reference/statements/export) to make context available for other files:

```
// Contexts.js

import { createContext } from 'react';



export const ThemeContext = createContext('light');

export const AuthContext = createContext(null);
```

Components declared in other files can then use the [`import`](https://developer.mozilla.org/en-US/docs/web/javascript/reference/statements/import) statement to read or provide this context:

```
// Button.js

import { ThemeContext } from './Contexts.js';



function Button() {

  const theme = useContext(ThemeContext);

  // ...

}
```

```
// App.js

import { ThemeContext, AuthContext } from './Contexts.js';



function App() {

  // ...

  return (

    <ThemeContext.Provider value={theme}>

      <AuthContext.Provider value={currentUser}>

        <Page />

      </AuthContext.Provider>

    </ThemeContext.Provider>

  );

}
```

This works similar to [importing and exporting components.](/learn/importing-and-exporting-components)

***

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### I can’t find a way to change the context value[](#i-cant-find-a-way-to-change-the-context-value "Link for I can’t find a way to change the context value ")

Code like this specifies the *default* context value:

```
const ThemeContext = createContext('light');
```

This value never changes. React only uses this value as a fallback if it can’t find a matching provider above.

To make context change over time, [add state and wrap components in a context provider.](/reference/react/useContext#updating-data-passed-via-context)

[Previouscache](/reference/react/cache)

[NextforwardRef](/reference/react/forwardRef)

***

----
url: https://legacy.reactjs.org/blog/2016/07/13/mixins-considered-harmful.html
----

July 13, 2016 by [Dan Abramov](https://twitter.com/dan_abramov)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

“How do I share the code between several components?” is one of the first questions that people ask when they learn React. Our answer has always been to use component composition for code reuse. You can define a component and use it in several other components.

It is not always obvious how a certain pattern can be solved with composition. React is influenced by functional programming but it came into the field that was dominated by object-oriented libraries. It was hard for engineers both inside and outside of Facebook to give up on the patterns they were used to.

To ease the initial adoption and learning, we included certain escape hatches into React. The mixin system was one of those escape hatches, and its goal was to give you a way to reuse code between components when you aren’t sure how to solve the same problem with composition.

Three years passed since React was released. The landscape has changed. Multiple view libraries now adopt a component model similar to React. Using composition over inheritance to build declarative user interfaces is no longer a novelty. We are also more confident in the React component model, and we have seen many creative uses of it both internally and in the community.

In this post, we will consider the problems commonly caused by mixins. Then we will suggest several alternative patterns for the same use cases. We have found those patterns to scale better with the complexity of the codebase than mixins.

## [](#why-mixins-are-broken)Why Mixins are Broken

At Facebook, React usage has grown from a few components to thousands of them. This gives us a window into how people use React. Thanks to declarative rendering and top-down data flow, many teams were able to fix a bunch of bugs while shipping new features as they adopted React.

However it’s inevitable that some of our code using React gradually became incomprehensible. Occasionally, the React team would see groups of components in different projects that people were afraid to touch. These components were too easy to break accidentally, were confusing to new developers, and eventually became just as confusing to the people who wrote them in the first place. Much of this confusion was caused by mixins. At the time, I wasn’t working at Facebook but I came to the [same conclusions](https://medium.com/@dan_abramov/mixins-are-dead-long-live-higher-order-components-94a0d2f9e750) after writing my fair share of terrible mixins.

This doesn’t mean that mixins themselves are bad. People successfully employ them in different languages and paradigms, including some functional languages. At Facebook, we extensively use traits in Hack which are fairly similar to mixins. Nevertheless, we think that mixins are unnecessary and problematic in React codebases. Here’s why.

### [](#mixins-introduce-implicit-dependencies)Mixins introduce implicit dependencies

Sometimes a component relies on a certain method defined in the mixin, such as `getClassName()`. Sometimes it’s the other way around, and mixin calls a method like `renderHeader()` on the component. JavaScript is a dynamic language so it’s hard to enforce or document these dependencies.

Mixins break the common and usually safe assumption that you can rename a state key or a method by searching for its occurrences in the component file. You might write a stateful component and then your coworker might add a mixin that reads this state. In a few months, you might want to move that state up to the parent component so it can be shared with a sibling. Will you remember to update the mixin to read a prop instead? What if, by now, other components also use this mixin?

These implicit dependencies make it hard for new team members to contribute to a codebase. A component’s `render()` method might reference some method that isn’t defined on the class. Is it safe to remove? Perhaps it’s defined in one of the mixins. But which one of them? You need to scroll up to the mixin list, open each of those files, and look for this method. Worse, mixins can specify their own mixins, so the search can be deep.

Often, mixins come to depend on other mixins, and removing one of them breaks the other. In these situations it is very tricky to tell how the data flows in and out of mixins, and what their dependency graph looks like. Unlike components, mixins don’t form a hierarchy: they are flattened and operate in the same namespace.

### [](#mixins-cause-name-clashes)Mixins cause name clashes

There is no guarantee that two particular mixins can be used together. For example, if `FluxListenerMixin` defines `handleChange()` and `WindowSizeMixin` defines `handleChange()`, you can’t use them together. You also can’t define a method with this name on your own component.

It’s not a big deal if you control the mixin code. When you have a conflict, you can rename that method on one of the mixins. However it’s tricky because some components or other mixins may already be calling this method directly, and you need to find and fix those calls as well.

If you have a name conflict with a mixin from a third party package, you can’t just rename a method on it. Instead, you have to use awkward method names on your component to avoid clashes.

The situation is no better for mixin authors. Even adding a new method to a mixin is always a potentially breaking change because a method with the same name might already exist on some of the components using it, either directly or through another mixin. Once written, mixins are hard to remove or change. Bad ideas don’t get refactored away because refactoring is too risky.

### [](#mixins-cause-snowballing-complexity)Mixins cause snowballing complexity

Even when mixins start out simple, they tend to become complex over time. The example below is based on a real scenario I’ve seen play out in a codebase.

A component needs some state to track mouse hover. To keep this logic reusable, you might extract `handleMouseEnter()`, `handleMouseLeave()` and `isHovering()` into a `HoverMixin`. Next, somebody needs to implement a tooltip. They don’t want to duplicate the logic in `HoverMixin` so they create a `TooltipMixin` that uses `HoverMixin`. `TooltipMixin` reads `isHovering()` provided by `HoverMixin` in its `componentDidUpdate()` and either shows or hides the tooltip.

A few months later, somebody wants to make the tooltip direction configurable. In an effort to avoid code duplication, they add support for a new optional method called `getTooltipOptions()` to `TooltipMixin`. By this time, components that show popovers also use `HoverMixin`. However popovers need a different hover delay. To solve this, somebody adds support for an optional `getHoverOptions()` method and implements it in `TooltipMixin`. Those mixins are now tightly coupled.

This is fine while there are no new requirements. However this solution doesn’t scale well. What if you want to support displaying multiple tooltips in a single component? You can’t define the same mixin twice in a component. What if the tooltips need to be displayed automatically in a guided tour instead of on hover? Good luck decoupling `TooltipMixin` from `HoverMixin`. What if you need to support the case where the hover area and the tooltip anchor are located in different components? You can’t easily hoist the state used by mixin up into the parent component. Unlike components, mixins don’t lend themselves naturally to such changes.

Every new requirement makes the mixins harder to understand. Components using the same mixin become increasingly coupled with time. Any new capability gets added to all of the components using that mixin. There is no way to split a “simpler” part of the mixin without either duplicating the code or introducing more dependencies and indirection between mixins. Gradually, the encapsulation boundaries erode, and since it’s hard to change or remove the existing mixins, they keep getting more abstract until nobody understands how they work.

These are the same problems we faced building apps before React. We found that they are solved by declarative rendering, top-down data flow, and encapsulated components. At Facebook, we have been migrating our code to use alternative patterns to mixins, and we are generally happy with the results. You can read about those patterns below.

## [](#migrating-from-mixins)Migrating from Mixins

Let’s make it clear that mixins are not technically deprecated. If you use `React.createClass()`, you may keep using them. We only say that they didn’t work well for us, and so we won’t recommend using them in the future.

Every section below corresponds to a mixin usage pattern that we found in the Facebook codebase. For each of them, we describe the problem and a solution that we think works better than mixins. The examples are written in ES5 but once you don’t need mixins, you can switch to ES6 classes if you’d like.

We hope that you find this list helpful. Please let us know if we missed important use cases so we can either amend the list or be proven wrong!

### [](#performance-optimizations)Performance Optimizations

One of the most commonly used mixins is [`PureRenderMixin`](/docs/pure-render-mixin.html). You might be using it in some components to [prevent unnecessary re-renders](/docs/advanced-performance.html#shouldcomponentupdate-in-action) when the props and state are shallowly equal to the previous props and state:

```
var PureRenderMixin = require('react-addons-pure-render-mixin');

var Button = React.createClass({
  mixins: [PureRenderMixin],

  // ...

});
```

#### [](#solution)Solution

To express the same without mixins, you can use the [`shallowCompare`](/docs/shallow-compare.html) function directly instead:

```
var shallowCompare = require('react-addons-shallow-compare');

var Button = React.createClass({
  shouldComponentUpdate: function(nextProps, nextState) {
    return shallowCompare(this, nextProps, nextState);
  },

  // ...

});
```

If you use a custom mixin implementing a `shouldComponentUpdate` function with different algorithm, we suggest exporting just that single function from a module and calling it directly from your components.

We understand that more typing can be annoying. For the most common case, we plan to [introduce a new base class](https://github.com/facebook/react/pull/7195) called `React.PureComponent` in the next minor release. It uses the same shallow comparison as `PureRenderMixin` does today.

### [](#subscriptions-and-side-effects)Subscriptions and Side Effects

The second most common type of mixins that we encountered are mixins that subscribe a React component to a third-party data source. Whether this data source is a Flux Store, an Rx Observable, or something else, the pattern is very similar: the subscription is created in `componentDidMount`, destroyed in `componentWillUnmount`, and the change handler calls `this.setState()`.

```
var SubscriptionMixin = {
  getInitialState: function() {
    return {
      comments: DataSource.getComments()
    };
  },

  componentDidMount: function() {
    DataSource.addChangeListener(this.handleChange);
  },

  componentWillUnmount: function() {
    DataSource.removeChangeListener(this.handleChange);
  },

  handleChange: function() {
    this.setState({
      comments: DataSource.getComments()
    });
  }
};

var CommentList = React.createClass({
  mixins: [SubscriptionMixin],

  render: function() {
    // Reading comments from state managed by mixin.
    var comments = this.state.comments;
    return (
      <div>
        {comments.map(function(comment) {
          return <Comment comment={comment} key={comment.id} />
        })}
      </div>
    )
  }
});

module.exports = CommentList;
```

#### [](#solution-1)Solution

If there is just one component subscribed to this data source, it is fine to embed the subscription logic right into the component. Avoid premature abstractions.

If several components used this mixin to subscribe to a data source, a nice way to avoid repetition is to use a pattern called [“higher-order components”](https://medium.com/@dan_abramov/mixins-are-dead-long-live-higher-order-components-94a0d2f9e750). It can sound intimidating so we will take a closer look at how this pattern naturally emerges from the component model.

#### [](#higher-order-components-explained)Higher-Order Components Explained

Let’s forget about React for a second. Consider these two functions that add and multiply numbers, logging the results as they do that:

```
function addAndLog(x, y) {
  var result = x + y;
  console.log('result:', result);
  return result;
}

function multiplyAndLog(x, y) {
  var result = x * y;
  console.log('result:', result);
  return result;
}
```

These two functions are not very useful but they help us demonstrate a pattern that we can later apply to components.

Let’s say that we want to extract the logging logic out of these functions without changing their signatures. How can we do this? An elegant solution is to write a [higher-order function](https://en.wikipedia.org/wiki/Higher-order_function), that is, a function that takes a function as an argument and returns a function.

Again, it sounds more intimidating than it really is:

```
function withLogging(wrappedFunction) {
  // Return a function with the same API...
  return function(x, y) {
    // ... that calls the original function
    var result = wrappedFunction(x, y);
    // ... but also logs its result!
    console.log('result:', result);
    return result;
  };
}
```

The `withLogging` higher-order function lets us write `add` and `multiply` without the logging statements, and later wrap them to get `addAndLog` and `multiplyAndLog` with exactly the same signatures as before:

```
function add(x, y) {
  return x + y;
}

function multiply(x, y) {
  return x * y;
}

function withLogging(wrappedFunction) {
  return function(x, y) {
    var result = wrappedFunction(x, y);
    console.log('result:', result);
    return result;
  };
}

// Equivalent to writing addAndLog by hand:
var addAndLog = withLogging(add);

// Equivalent to writing multiplyAndLog by hand:
var multiplyAndLog = withLogging(multiply);
```

Higher-order components are a very similar pattern, but applied to components in React. We will apply this transformation from mixins in two steps.

As a first step, we will split our `CommentList` component in two, a child and a parent. The child will be only concerned with rendering the comments. The parent will set up the subscription and pass the up-to-date data to the child via props.

```
// This is a child component.
// It only renders the comments it receives as props.
var CommentList = React.createClass({
  render: function() {
    // Note: now reading from props rather than state.
    var comments = this.props.comments;
    return (
      <div>
        {comments.map(function(comment) {
          return <Comment comment={comment} key={comment.id} />
        })}
      </div>
    )
  }
});

// This is a parent component.
// It subscribes to the data source and renders <CommentList />.
var CommentListWithSubscription = React.createClass({
  getInitialState: function() {
    return {
      comments: DataSource.getComments()
    };
  },

  componentDidMount: function() {
    DataSource.addChangeListener(this.handleChange);
  },

  componentWillUnmount: function() {
    DataSource.removeChangeListener(this.handleChange);
  },

  handleChange: function() {
    this.setState({
      comments: DataSource.getComments()
    });
  },

  render: function() {
    // We pass the current state as props to CommentList.
    return <CommentList comments={this.state.comments} />;
  }
});

module.exports = CommentListWithSubscription;
```

There is just one final step left to do.

Remember how we made `withLogging()` take a function and return another function wrapping it? We can apply a similar pattern to React components.

We will write a new function called `withSubscription(WrappedComponent)`. Its argument could be any React component. We will pass `CommentList` as `WrappedComponent`, but we could also apply `withSubscription()` to any other component in our codebase.

This function would return another component. The returned component would manage the subscription and render `<WrappedComponent />` with the current data.

We call this pattern a “higher-order component”.

The composition happens at React rendering level rather than with a direct function call. This is why it doesn’t matter whether the wrapped component is defined with `createClass()`, as an ES6 class or a function. If `WrappedComponent` is a React component, the component created by `withSubscription()` can render it.

```
// This function takes a component...
function withSubscription(WrappedComponent) {
  // ...and returns another component...
  return React.createClass({
    getInitialState: function() {
      return {
        comments: DataSource.getComments()
      };
    },

    componentDidMount: function() {
      // ... that takes care of the subscription...
      DataSource.addChangeListener(this.handleChange);
    },

    componentWillUnmount: function() {
      DataSource.removeChangeListener(this.handleChange);
    },

    handleChange: function() {
      this.setState({
        comments: DataSource.getComments()
      });
    },

    render: function() {
      // ... and renders the wrapped component with the fresh data!
      return <WrappedComponent comments={this.state.comments} />;
    }
  });
}
```

Now we can declare `CommentListWithSubscription` by applying `withSubscription` to `CommentList`:

```
var CommentList = React.createClass({
  render: function() {
    var comments = this.props.comments;
    return (
      <div>
        {comments.map(function(comment) {
          return <Comment comment={comment} key={comment.id} />
        })}
      </div>
    )
  }
});

// withSubscription() returns a new component that
// is subscribed to the data source and renders
// <CommentList /> with up-to-date data.
var CommentListWithSubscription = withSubscription(CommentList);

// The rest of the app is interested in the subscribed component
// so we export it instead of the original unwrapped CommentList.
module.exports = CommentListWithSubscription;
```

#### [](#solution-revisited)Solution, Revisited

Now that we understand higher-order components better, let’s take another look at the complete solution that doesn’t involve mixins. There are a few minor changes that are annotated with inline comments:

```
function withSubscription(WrappedComponent) {
  return React.createClass({
    getInitialState: function() {
      return {
        comments: DataSource.getComments()
      };
    },

    componentDidMount: function() {
      DataSource.addChangeListener(this.handleChange);
    },

    componentWillUnmount: function() {
      DataSource.removeChangeListener(this.handleChange);
    },

    handleChange: function() {
      this.setState({
        comments: DataSource.getComments()
      });
    },

    render: function() {
      // Use JSX spread syntax to pass all props and state down automatically.
      return <WrappedComponent {...this.props} {...this.state} />;
    }
  });
}

// Optional change: convert CommentList to a function component
// because it doesn't use lifecycle methods or state.
function CommentList(props) {
  var comments = props.comments;
  return (
    <div>
      {comments.map(function(comment) {
        return <Comment comment={comment} key={comment.id} />
      })}
    </div>
  )
}

// Instead of declaring CommentListWithSubscription,
// we export the wrapped component right away.
module.exports = withSubscription(CommentList);
```

Higher-order components are a powerful pattern. You can pass additional arguments to them if you want to further customize their behavior. After all, they are not even a feature of React. They are just functions that receive components and return components that wrap them.

Like any solution, higher-order components have their own pitfalls. For example, if you heavily use [refs](/docs/more-about-refs.html), you might notice that wrapping something into a higher-order component changes the ref to point to the wrapping component. In practice we discourage using refs for component communication so we don’t think it’s a big issue. In the future, we might consider adding [ref forwarding](https://github.com/facebook/react/issues/4213) to React to solve this annoyance.

### [](#rendering-logic)Rendering Logic

The next most common use case for mixins that we discovered in our codebase is sharing rendering logic between components.

Here is a typical example of this pattern:

```
var RowMixin = {
  // Called by components from render()
  renderHeader: function() {
    return (
      <div className='row-header'>
        <h1>
          {this.getHeaderText() /* Defined by components */}
        </h1>
      </div>
    );
  }
};

var UserRow = React.createClass({
  mixins: [RowMixin],

  // Called by RowMixin.renderHeader()
  getHeaderText: function() {
    return this.props.user.fullName;
  },

  render: function() {
    return (
      <div>
        {this.renderHeader() /* Defined by RowMixin */}
        <h2>{this.props.user.biography}</h2>
      </div>
    )
  }
});
```

Multiple components may be sharing `RowMixin` to render the header, and each of them would need to define `getHeaderText()`.

#### [](#solution-2)Solution

If you see rendering logic inside a mixin, it’s time to extract a component!

Instead of `RowMixin`, we will define a `<RowHeader>` component. We will also replace the convention of defining a `getHeaderText()` method with the standard mechanism of top-data flow in React: passing props.

Finally, since neither of those components currently need lifecycle methods or state, we can declare them as simple functions:

```
function RowHeader(props) {
  return (
    <div className='row-header'>
      <h1>{props.text}</h1>
    </div>
  );
}

function UserRow(props) {
  return (
    <div>
      <RowHeader text={props.user.fullName} />
      <h2>{props.user.biography}</h2>
    </div>
  );
}
```

Props keep component dependencies explicit, easy to replace, and enforceable with tools like [Flow](https://flowtype.org/) and [TypeScript](https://www.typescriptlang.org/).

> **Note:**
>
> Defining components as functions is not required. There is also nothing wrong with using lifecycle methods and state—they are first-class React features. We use function components in this example because they are easier to read and we didn’t need those extra features, but classes would work just as fine.

### [](#context)Context

Another group of mixins we discovered were helpers for providing and consuming [React context](/docs/context.html). Context is an experimental unstable feature, has [certain issues](https://github.com/facebook/react/issues/2517), and will likely change its API in the future. We don’t recommend using it unless you’re confident there is no other way of solving your problem.

Nevertheless, if you already use context today, you might have been hiding its usage with mixins like this:

```
var RouterMixin = {
  contextTypes: {
    router: React.PropTypes.object.isRequired
  },

  // The mixin provides a method so that components
  // don't have to use the context API directly.
  push: function(path) {
    this.context.router.push(path)
  }
};

var Link = React.createClass({
  mixins: [RouterMixin],

  handleClick: function(e) {
    e.stopPropagation();

    // This method is defined in RouterMixin.
    this.push(this.props.to);
  },

  render: function() {
    return (
      <a onClick={this.handleClick}>
        {this.props.children}
      </a>
    );
  }
});

module.exports = Link;
```

#### [](#solution-3)Solution

We agree that hiding context usage from consuming components is a good idea until the context API stabilizes. However, we recommend using higher-order components instead of mixins for this.

Let the wrapping component grab something from the context, and pass it down with props to the wrapped component:

```
function withRouter(WrappedComponent) {
  return React.createClass({
    contextTypes: {
      router: React.PropTypes.object.isRequired
    },

    render: function() {
      // The wrapper component reads something from the context
      // and passes it down as a prop to the wrapped component.
      var router = this.context.router;
      return <WrappedComponent {...this.props} router={router} />;
    }
  });
};

var Link = React.createClass({
  handleClick: function(e) {
    e.stopPropagation();

    // The wrapped component uses props instead of context.
    this.props.router.push(this.props.to);
  },

  render: function() {
    return (
      <a onClick={this.handleClick}>
        {this.props.children}
      </a>
    );
  }
});

// Don't forget to wrap the component!
module.exports = withRouter(Link);
```

If you’re using a third party library that only provides a mixin, we encourage you to file an issue with them linking to this post so that they can provide a higher-order component instead. In the meantime, you can create a higher-order component around it yourself in exactly the same way.

### [](#utility-methods)Utility Methods

Sometimes, mixins are used solely to share utility functions between components:

```
var ColorMixin = {
  getLuminance(color) {
    var c = parseInt(color, 16);
    var r = (c & 0xFF0000) >> 16;
    var g = (c & 0x00FF00) >> 8;
    var b = (c & 0x0000FF);
    return (0.299 * r + 0.587 * g + 0.114 * b);
  }
};

var Button = React.createClass({
  mixins: [ColorMixin],

  render: function() {
    var theme = this.getLuminance(this.props.color) > 160 ? 'dark' : 'light';
    return (
      <div className={theme}>
        {this.props.children}
      </div>
    )
  }
});
```

#### [](#solution-4)Solution

Put utility functions into regular JavaScript modules and import them. This also makes it easier to test them or use them outside of your components:

```
var getLuminance = require('../utils/getLuminance');

var Button = React.createClass({
  render: function() {
    var theme = getLuminance(this.props.color) > 160 ? 'dark' : 'light';
    return (
      <div className={theme}>
        {this.props.children}
      </div>
    )
  }
});
```

### [](#other-use-cases)Other Use Cases

Sometimes people use mixins to selectively add logging to lifecycle methods in some components. In the future, we intend to provide an [official DevTools API](https://github.com/facebook/react/issues/5306) that would let you implement something similar without touching the components. However it’s still very much a work in progress. If you heavily depend on logging mixins for debugging, you might want to keep using those mixins for a little longer.

If you can’t accomplish something with a component, a higher-order component, or a utility module, it could mean that React should provide this out of the box. [File an issue](https://github.com/facebook/react/issues/new) to tell us about your use case for mixins, and we’ll help you consider alternatives or perhaps implement your feature request.

Mixins are not deprecated in the traditional sense. You can keep using them with `React.createClass()`, as we won’t be changing it further. Eventually, as ES6 classes gain more adoption and their usability problems in React are solved, we might split `React.createClass()` into a separate package because most people wouldn’t need it. Even in that case, your old mixins would keep working.

We believe that the alternatives above are better for the vast majority of cases, and we invite you to try writing React apps without using mixins.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2016-07-13-mixins-considered-harmful.md)

----
url: https://legacy.reactjs.org/blog/2018/11/13/react-conf-recap.html
----

November 13, 2018 by [Tom Occhino](https://twitter.com/tomocchino)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

This year’s [React Conf](https://conf.reactjs.org/) took place on October 25 and 26 in Henderson, Nevada, where more than 600 attendees gathered to discuss the latest in UI engineering.



Sophie Alpert and Dan Abramov kicked off Day 1 with their keynote, React Today and Tomorrow. In the talk, they introduced [Hooks](/docs/hooks-intro.html), which are a new proposal that adds the ability to access features such as state without writing a JavaScript class. Hooks promise to dramatically simplify the code required for React components and are currently available in a React alpha release.



On the morning of Day 2, Andrew Clark and Brian Vaughn presented Concurrent Rendering in React. Andrew covered the recently announced [React.lazy API for code splitting](/blog/2018/10/23/react-v-16-6.html) and previewed two upcoming features: concurrent mode and Suspense. Brian demonstrated how to use [React’s new profiler](/blog/2018/09/10/introducing-the-react-profiler.html) tooling to make apps built in React run faster.



In the afternoon, Parashuram N spoke in detail about React Native’s New Architecture, a long-term project that the React Native team has been working on over the past year and [announced in June](https://reactnative.dev/blog/2018/06/14/state-of-react-native-2018). We’re really excited about the potential of this project to improve performance, simplify interoperability with other libraries, and set a strong foundation for the future of React Native.

Now that the conference is over, all 28 conference talks are [available to stream online](https://www.youtube.com/playlist?list=PLPxbbTqCLbGE5AihOSExAa4wUM-P42EIJ). There are tons of great ones from both days. We can’t wait until next year!

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2018-11-13-react-conf-recap.md)

----
url: https://legacy.reactjs.org/blog/2014/09/16/react-v0.11.2.html
----

September 16, 2014 by [Paul O’Shannessy](https://twitter.com/zpao)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

Today we’re releasing React v0.11.2 to add a few small features.

We’re adding support for two more DOM elements, `<dialog>` and `<picture>`, as well as the associated attributes needed to use these elements: `open`, `media`, and `sizes`. While not all browsers support these natively, some of our cutting edge users want to make use of them, so we’re making them available to everybody.

We’re also doing some work to prepare for v0.12 and improve compatibility between the versions. To do this we are replacing `React.createDescriptor` with `React.createElement`. `createDescriptor` will continue to work with a warning and will be gone in v0.12. Chances are that this won’t affect anybody.

And lastly, on the heels of announcing Flow at [@Scale](http://atscaleconference.com/) yesterday, we’re adding the ability to strip TypeScript-like type annotations as part of the `jsx` transform. To use, simply use the `--strip-types` flag on the command line, or set `stripTypes` in the `options` object when calling the API. We’ll be talking about Flow more in the coming months. But for now, it’s helpful to know that it is a flow-sensitive JavaScript type checker we will be open sourcing soon.

The release is available for download from the CDN:

* **React**\
  Dev build with warnings: <https://fb.me/react-0.11.2.js>\
  Minified build for production: <https://fb.me/react-0.11.2.min.js>
* **React with Add-Ons**\
  Dev build with warnings: <https://fb.me/react-with-addons-0.11.2.js>\
  Minified build for production: <https://fb.me/react-with-addons-0.11.2.min.js>
* **In-Browser JSX transformer**\
  <https://fb.me/JSXTransformer-0.11.2.js>

We’ve also published version `0.11.2` of the `react` and `react-tools` packages on npm and the `react` package on bower.

Please try these builds out and [file an issue on GitHub](https://github.com/facebook/react/issues/new) if you see anything awry.

### [](#react-core)React Core

#### [](#new-features)New Features

* Added support for `<dialog>` element and associated `open` attribute

* Added support for `<picture>` element and associated `media` and `sizes` attributes

* Added `React.createElement` API in preparation for React v0.12

  * `React.createDescriptor` has been deprecated as a result

### [](#jsx)JSX

* `<picture>` is now parsed into `React.DOM.picture`

### [](#react-tools)React Tools

* Update `esprima` and `jstransform` for correctness fixes

* The `jsx` executable now exposes a `--strip-types` flag which can be used to remove TypeScript-like type annotations

  * This option is also exposed to `require('react-tools').transform` as `stripTypes`

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2014-09-16-react-v0.11.2.md)

----
url: https://react.dev/learn/editor-setup
----

[Learn React](/learn)

[Setup](/learn/setup)

> If your ESLint preset has formatting rules, they may conflict with Prettier. We recommend disabling all formatting rules in your ESLint preset using [`eslint-config-prettier`](https://github.com/prettier/eslint-config-prettier) so that ESLint is *only* used for catching logical mistakes. If you want to enforce that files are formatted before a pull request is merged, use [`prettier --check`](https://prettier.io/docs/en/cli.html#--check) for your continuous integration.

[PreviousSetup](/learn/setup)

[NextUsing TypeScript](/learn/typescript)

***

----
url: https://legacy.reactjs.org/docs/introducing-jsx.html
----

> These docs are old and won’t be updated. Go to [react.dev](https://react.dev/) for the new React docs.
>
> These new documentation pages teach modern React and include live examples:
>
> * [Writing Markup with JSX](https://react.dev/learn/writing-markup-with-jsx)
> * [JavaScript in JSX with Curly Braces](https://react.dev/learn/javascript-in-jsx-with-curly-braces)

Consider this variable declaration:

```
const element = <h1>Hello, world!</h1>;
```

This funny tag syntax is neither a string nor HTML.

It is called JSX, and it is a syntax extension to JavaScript. We recommend using it with React to describe what the UI should look like. JSX may remind you of a template language, but it comes with the full power of JavaScript.

JSX produces React “elements”. We will explore rendering them to the DOM in the [next section](/docs/rendering-elements.html). Below, you can find the basics of JSX necessary to get you started.

### [](#why-jsx)Why JSX?

React embraces the fact that rendering logic is inherently coupled with other UI logic: how events are handled, how the state changes over time, and how the data is prepared for display.

Instead of artificially separating *technologies* by putting markup and logic in separate files, React [separates *concerns*](https://en.wikipedia.org/wiki/Separation_of_concerns) with loosely coupled units called “components” that contain both. We will come back to components in a [further section](/docs/components-and-props.html), but if you’re not yet comfortable putting markup in JS, [this talk](https://www.youtube.com/watch?v=x7cQ3mrcKaY) might convince you otherwise.

React [doesn’t require](/docs/react-without-jsx.html) using JSX, but most people find it helpful as a visual aid when working with UI inside the JavaScript code. It also allows React to show more useful error and warning messages.

With that out of the way, let’s get started!

### [](#embedding-expressions-in-jsx)Embedding Expressions in JSX

In the example below, we declare a variable called `name` and then use it inside JSX by wrapping it in curly braces:

```
const name = 'Josh Perez';const element = <h1>Hello, {name}</h1>;
```

You can put any valid [JavaScript expression](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Expressions) inside the curly braces in JSX. For example, `2 + 2`, `user.firstName`, or `formatName(user)` are all valid JavaScript expressions.

In the example below, we embed the result of calling a JavaScript function, `formatName(user)`, into an `<h1>` element.

```
function formatName(user) {
  return user.firstName + ' ' + user.lastName;
}

const user = {
  firstName: 'Harper',
  lastName: 'Perez'
};

const element = (
  <h1>
    Hello, {formatName(user)}!  </h1>
);
```

**[Try it on CodePen](https://codepen.io/gaearon/pen/PGEjdG?editors=1010)**

We split JSX over multiple lines for readability. While it isn’t required, when doing this, we also recommend wrapping it in parentheses to avoid the pitfalls of [automatic semicolon insertion](https://stackoverflow.com/q/2846283).

### [](#jsx-is-an-expression-too)JSX is an Expression Too

After compilation, JSX expressions become regular JavaScript function calls and evaluate to JavaScript objects.

This means that you can use JSX inside of `if` statements and `for` loops, assign it to variables, accept it as arguments, and return it from functions:

```
function getGreeting(user) {
  if (user) {
    return <h1>Hello, {formatName(user)}!</h1>;  }
  return <h1>Hello, Stranger.</h1>;}
```

### [](#specifying-attributes-with-jsx)Specifying Attributes with JSX

You may use quotes to specify string literals as attributes:

```
const element = <a href="https://www.reactjs.org"> link </a>;
```

You may also use curly braces to embed a JavaScript expression in an attribute:

```
const element = <img src={user.avatarUrl}></img>;
```

Don’t put quotes around curly braces when embedding a JavaScript expression in an attribute. You should either use quotes (for string values) or curly braces (for expressions), but not both in the same attribute.

> **Warning:**
>
> Since JSX is closer to JavaScript than to HTML, React DOM uses `camelCase` property naming convention instead of HTML attribute names.
>
> For example, `class` becomes [`className`](https://developer.mozilla.org/en-US/docs/Web/API/Element/className) in JSX, and `tabindex` becomes [`tabIndex`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/tabIndex).

### [](#specifying-children-with-jsx)Specifying Children with JSX

If a tag is empty, you may close it immediately with `/>`, like XML:

```
const element = <img src={user.avatarUrl} />;
```

JSX tags may contain children:

```
const element = (
  <div>
    <h1>Hello!</h1>
    <h2>Good to see you here.</h2>
  </div>
);
```

### [](#jsx-prevents-injection-attacks)JSX Prevents Injection Attacks

It is safe to embed user input in JSX:

```
const title = response.potentiallyMaliciousInput;
// This is safe:
const element = <h1>{title}</h1>;
```

By default, React DOM [escapes](https://stackoverflow.com/questions/7381974/which-characters-need-to-be-escaped-on-html) any values embedded in JSX before rendering them. Thus it ensures that you can never inject anything that’s not explicitly written in your application. Everything is converted to a string before being rendered. This helps prevent [XSS (cross-site-scripting)](https://en.wikipedia.org/wiki/Cross-site_scripting) attacks.

### [](#jsx-represents-objects)JSX Represents Objects

Babel compiles JSX down to `React.createElement()` calls.

These two examples are identical:

```
const element = (
  <h1 className="greeting">
    Hello, world!
  </h1>
);
```

```
const element = React.createElement(
  'h1',
  {className: 'greeting'},
  'Hello, world!'
);
```

`React.createElement()` performs a few checks to help you write bug-free code but essentially it creates an object like this:

```
// Note: this structure is simplified
const element = {
  type: 'h1',
  props: {
    className: 'greeting',
    children: 'Hello, world!'
  }
};
```

These objects are called “React elements”. You can think of them as descriptions of what you want to see on the screen. React reads these objects and uses them to construct the DOM and keep it up to date.

We will explore rendering React elements to the DOM in the [next section](/docs/rendering-elements.html).

> **Tip:**
>
> We recommend using the [“Babel” language definition](https://babeljs.io/docs/en/next/editors) for your editor of choice so that both ES6 and JSX code is properly highlighted.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/introducing-jsx.md)

* Previous article

  [Hello World](/docs/hello-world.html)

* Next article

  [Rendering Elements](/docs/rendering-elements.html)

----
url: https://legacy.reactjs.org/blog/2018/11/27/react-16-roadmap.html
----

November 27, 2018 by [Dan Abramov](https://twitter.com/dan_abramov)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

You might have heard about features like “Hooks”, “Suspense”, and “Concurrent Rendering” in the previous blog posts and talks. In this post, we’ll look at how they fit together and the expected timeline for their availability in a stable release of React.

> An Update from August, 2019
>
> You can find an update to this roadmap in the [React 16.9 release blog post](/blog/2019/08/08/react-v16.9.0.html#an-update-to-the-roadmap).

## [](#tldr)tl;dr

We plan to split the rollout of new React features into the following milestones:

* React 16.6 with [Suspense for Code Splitting](#react-166-shipped-the-one-with-suspense-for-code-splitting) (*already shipped*)
* A minor 16.x release with [React Hooks](#react-16x-q1-2019-the-one-with-hooks) (\~Q1 2019)
* A minor 16.x release with [Concurrent Mode](#react-16x-q2-2019-the-one-with-concurrent-mode) (\~Q2 2019)
* A minor 16.x release with [Suspense for Data Fetching](#react-16x-mid-2019-the-one-with-suspense-for-data-fetching) (\~mid 2019)

*(The original version of this post used exact version numbers. We edited it to reflect that there might need to be a few other minor releases in the middle between these ones.)*

These are estimates, and the details may change as we’re further along. There’s at least two more projects we plan to complete in 2019. They require more exploration and aren’t tied to a particular release yet:

* [Modernizing React DOM](#modernizing-react-dom)
* [Suspense for Server Rendering](#suspense-for-server-rendering)

We expect to get more clarity on their timeline in the coming months.

> Note
>
> This post is just a roadmap — there is nothing in it that requires your immediate attention. When each of these features are released, we’ll publish a full blog post announcing them.

## [](#release-timeline)Release Timeline

We have a single vision for how all of these features fit together, but we’re releasing each part as soon as it is ready so that you can test and start using them sooner. The API design doesn’t always make sense when looking at one piece in isolation; this post lays out the major parts of our plan to help you see the whole picture. (See our [versioning policy](/docs/faq-versioning.html) to learn more about our commitment to stability.)

The gradual release strategy helps us refine the APIs, but the transitional period when some things aren’t ready can be confusing. Let’s look at what these different features mean for your app, how they relate to each other, and when you can expect to start learning and using them.

### [](#react-166-shipped-the-one-with-suspense-for-code-splitting)[React 16.6](/blog/2018/10/23/react-v-16-6.html) (shipped): The One with Suspense for Code Splitting

*Suspense* refers to React’s new ability to “suspend” rendering while components are waiting for something, and display a loading indicator. In React 16.6, Suspense supports only one use case: lazy loading components with `React.lazy()` and `<React.Suspense>`.

```
// This component is loaded dynamically
const OtherComponent = React.lazy(() => import('./OtherComponent'));

function MyComponent() {
  return (
    <React.Suspense fallback={<Spinner />}>
      <div>
        <OtherComponent />
      </div>
    </React.Suspense>
  );
}
```

Code splitting with `React.lazy()` with `<React.Suspense>` is documented [in the Code Splitting guide](/docs/code-splitting.html#reactlazy). You can find another practical explanation in [this article](https://medium.com/@pomber/lazy-loading-and-preloading-components-in-react-16-6-804de091c82d).

We have been using Suspense for code splitting at Facebook since July, and expect it to be stable. There’s been a few regressions in the initial public release in 16.6.0, but they were fixed in 16.6.3.

Code splitting is just the first step for Suspense. Our longer term vision for Suspense involves letting it handle data fetching too (and integrate with libraries like Apollo). In addition to a convenient programming model, Suspense also provides better user experience in Concurrent Mode. You’ll find information about these topics further below.

**Status in React DOM:** Available since React 16.6.0.

**Status in React DOM Server:** Suspense is not available in the server renderer yet. This isn’t for the lack of attention. We’ve started work on a new asynchronous server renderer that will support Suspense, but it’s a large project and will take a good chunk of 2019 to complete.

**Status in React Native:** Bundle splitting isn’t very useful in React Native, but there’s nothing technically preventing `React.lazy()` and `<Suspense>` from working when given a Promise to a module.

**Recommendation:** If you only do client rendering, we recommend widely adopting `React.lazy()` and `<React.Suspense>` for code splitting React components. If you do server rendering, you’ll have to wait with adoption until the new server renderer is ready.

### [](#react-16x-q1-2019-the-one-with-hooks)React 16.x (\~Q1 2019): The One with Hooks

*Hooks* let you use features like state and lifecycle from function components. They also let you reuse stateful logic between components without introducing extra nesting in your tree.

```
function Example() {
  // Declare a new state variable, which we'll call "count"
  const [count, setCount] = useState(0);

  return (
   <div>
     <p>You clicked {count} times</p>
     <button onClick={() => setCount(count + 1)}>
       Click me
     </button>
   </div>
 );
}
```

Hooks [introduction](/docs/hooks-intro.html) and [overview](/docs/hooks-overview.html) are good places to start. Watch [these talks](https://www.youtube.com/watch?v=V-QO-KO90iQ) for a video introduction and a deep dive. The [FAQ](/docs/hooks-faq.html) should answer most of your further questions. To learn more about the motivation behind Hooks, you can read [this article](https://medium.com/@dan_abramov/making-sense-of-react-hooks-fdbde8803889). Some of the rationale for the API design of Hooks is explained in [this RFC thread reply](https://github.com/reactjs/rfcs/pull/68#issuecomment-439314884).

We have been dogfooding Hooks at Facebook since September. We don’t expect major bugs in the implementation. Hooks are only available in the 16.7 alpha versions of React. Some of their API is expected to change in the final version (see the end of [this comment](https://github.com/reactjs/rfcs/pull/68#issuecomment-439314884) for details). It is possible that the minor release with Hooks might not be React 16.7.

Hooks represent our vision for the future of React. They solve both problems that React users experience directly (“wrapper hell” of render props and higher-order components, duplication of logic in lifecycle methods), and the issues we’ve encountered optimizing React at scale (such as difficulties in inlining components with a compiler). Hooks don’t deprecate classes. However, if Hooks are successful, it is possible that in a future *major* release class support might move to a separate package, reducing the default bundle size of React.

**Status in React DOM:** The first version of `react` and `react-dom` supporting Hooks is `16.7.0-alpha.0`. We expect to publish more alphas over the next months (at the time of writing, the latest one is `16.7.0-alpha.2`). You can try them by installing `react@next` with `react-dom@next`. Don’t forget to update `react-dom` — otherwise Hooks won’t work.

**Status in React DOM Server:** The same 16.7 alpha versions of `react-dom` fully support Hooks with `react-dom/server`.

**Status in React Native:** There is no officially supported way to try Hooks in React Native yet. If you’re feeling adventurous, check out [this thread](https://github.com/facebook/react-native/issues/21967) for unofficial instructions. There is a known issue with `useEffect` firing too late which still needs to be solved.

**Recommendation:** When you’re ready, we encourage you to start trying Hooks in new components you write. Make sure everyone on your team is on board with using them and familiar with this documentation. We don’t recommend rewriting your existing classes to Hooks unless you planned to rewrite them anyway (e.g. to fix bugs). Read more about the adoption strategy [here](/docs/hooks-faq.html#adoption-strategy).

### [](#react-16x-q2-2019-the-one-with-concurrent-mode)React 16.x (\~Q2 2019): The One with Concurrent Mode

*Concurrent Mode* lets React apps be more responsive by rendering component trees without blocking the main thread. It is opt-in and allows React to interrupt a long-running render (for example, rendering a news feed story) to handle a high-priority event (for example, text input or hover). Concurrent Mode also improves the user experience of Suspense by skipping unnecessary loading states on fast connections.

> Note
>
> You might have previously heard Concurrent Mode being referred to as [“async mode”](/blog/2018/03/27/update-on-async-rendering.html). We’ve changed the name to Concurrent Mode to highlight React’s ability to perform work on different priority levels. This sets it apart from other approaches to async rendering.

```
// Two ways to opt in:

// 1. Part of an app (not final API)
<React.unstable_ConcurrentMode>
  <Something />
</React.unstable_ConcurrentMode>

// 2. Whole app (not final API)
ReactDOM.unstable_createRoot(domNode).render(<App />);
```

There is no documentation written for the Concurrent Mode yet. It is important to highlight that the conceptual model will likely be unfamiliar at first. Documenting its benefits, how to use it efficiently, and its pitfalls is a high priority for us, and will be a prerequisite for calling it stable. Until then, [Andrew’s talk](https://www.youtube.com/watch?v=ByBPyMBTzM0) is the best introduction available.

Concurrent Mode is *much* less polished than Hooks. Some APIs aren’t properly “wired up” yet and don’t do what they’re expected to. At the time of writing this post, we don’t recommend using it for anything except very early experimentation. We don’t expect many bugs in Concurrent Mode itself, but note that components that produce warnings in [`<React.StrictMode>`](https://reactjs.org/docs/strict-mode.html) may not work correctly. On a separate note, we’ve seen that Concurrent Mode *surfaces* performance problems in other code which can sometimes be mistaken for performance issues in Concurrent Mode itself. For example, a stray `setInterval(fn, 1)` call that runs every millisecond would have a worse effect in Concurrent Mode. We plan to publish more guidance about diagnosing and fixing issues like this as part of this release’s documentation.

Concurrent Mode is a big part of our vision for React. For CPU-bound work, it allows non-blocking rendering and keeps your app responsive while rendering complex component trees. That’s demoed in the first part of [our JSConf Iceland talk](/blog/2018/03/01/sneak-peek-beyond-react-16.html). Concurrent Mode also makes Suspense better. It lets you avoid flickering a loading indicator if the network is fast enough. It’s hard to explain without seeing so [Andrew’s talk](https://www.youtube.com/watch?v=ByBPyMBTzM0) is the best resource available today. Concurrent Mode relies on a cooperative main thread [scheduler](https://github.com/facebook/react/tree/main/packages/scheduler), and we are [collaborating with the Chrome team](https://www.youtube.com/watch?v=mDdgfyRB5kg) to eventually move this functionality into the browser itself.

**Status in React DOM:** A *very* unstable version of Concurrent Mode is available behind an `unstable_` prefix in React 16.6 but we don’t recommend trying it unless you’re willing to often run into walls or missing features. The 16.7 alphas include `React.ConcurrentMode` and `ReactDOM.createRoot` without an `unstable_` prefix, but we’ll likely keep the prefix in 16.7, and only document and mark Concurrent Mode as stable in this future minor release.

**Status in React DOM Server:** Concurrent Mode doesn’t directly affect server rendering. It will work with the existing server renderer.

**Status in React Native:** The current plan is to delay enabling Concurrent Mode in React Native until [React Fabric](https://github.com/react-native-community/discussions-and-proposals/issues/4) project is near completion.

**Recommendation:** If you wish to adopt Concurrent Mode in the future, wrapping some component subtrees in [`<React.StrictMode>`](https://reactjs.org/docs/strict-mode.html) and fixing the resulting warnings is a good first step. In general it’s not expected that legacy code would immediately be compatible. For example, at Facebook we mostly intend to use the Concurrent Mode in the more recently developed codebases, and keep the legacy ones running in the synchronous mode for the near future.

### [](#react-16x-mid-2019-the-one-with-suspense-for-data-fetching)React 16.x (\~mid 2019): The One with Suspense for Data Fetching

As mentioned earlier, *Suspense* refers to React’s ability to “suspend” rendering while components are waiting for something, and display a loading indicator. In the already shipped React 16.6, the only supported use case for Suspense is code splitting. In this future minor release, we’d like to provide officially supported ways to use it for data fetching too. We’ll provide a reference implementation of a basic “React Cache” that’s compatible with Suspense, but you can also write your own. Data fetching libraries like Apollo and Relay will be able to integrate with Suspense by following a simple specification that we’ll document.

```
// React Cache for simple data fetching (not final API)
import {unstable_createResource} from 'react-cache';

// Tell React Cache how to fetch your data
const TodoResource = unstable_createResource(fetchTodo);

function Todo(props) {
  // Suspends until the data is in the cache
  const todo = TodoResource.read(props.id);
  return <li>{todo.title}</li>;
}

function App() {
  return (
    // Same Suspense component you already use for code splitting
    // would be able to handle data fetching too.
    <React.Suspense fallback={<Spinner />}>
      <ul>
        {/* Siblings fetch in parallel */}
        <Todo id="1" />
        <Todo id="2" />
      </ul>
    </React.Suspense>
  );
}

// Other libraries like Apollo and Relay can also
// provide Suspense integrations with similar APIs.
```

There is no official documentation for how to fetch data with Suspense yet, but you can find some early information in [this talk](https://youtu.be/ByBPyMBTzM0?t=1312) and [this small demo](https://github.com/facebook/react/blob/main/packages/react-devtools/CHANGELOG.md#suspense-toggle). We’ll write documentation for React Cache (and how to write your own Suspense-compatible library) closer to this React release, but if you’re curious, you can find its very early source code [here](https://github.com/facebook/react/blob/main/packages/react-cache/src/ReactCache.js).

The low-level Suspense mechanism (suspending rendering and showing a fallback) is expected to be stable even in React 16.6. We’ve used it for code splitting in production for months. However, the higher-level APIs for data fetching are very unstable. React Cache is rapidly changing, and will change at least a few more times. There are some low-level APIs that are [missing](https://github.com/reactjs/rfcs/pull/89) for a good higher-level API to be possible. We don’t recommend using React Cache anywhere except very early experiments. Note that React Cache itself isn’t strictly tied to React releases, but the current alphas lack basic features as cache invalidation, and you’ll run into a wall very soon. We expect to have something usable with this React release.

Eventually we’d like most data fetching to happen through Suspense but it will take a long time until all integrations are ready. In practice we expect it to be adopted very incrementally, and often through layers like Apollo or Relay rather than directly. Missing higher level APIs aren’t the only obstacle — there are also some important UI patterns we don’t support yet such as [showing progress indicator outside of the loading view hierarchy](https://github.com/facebook/react/issues/14248). As always, we will communicate our progress in the release notes on this blog.

**Status in React DOM and React Native:** Technically, a compatible cache would already work with `<React.Suspense>` in React 16.6. However, we don’t expect to have a good cache implementation until this React minor release. If you’re feeling adventurous, you can try to write your own cache by looking at the React Cache alphas. However, note that the mental model is sufficiently different that there’s a high risk of misunderstanding it until the docs are ready.

**Status in React DOM Server:** Suspense is not available in the server renderer yet. As we mentioned earlier, we’ve started work on a new asynchronous server renderer that will support Suspense, but it’s a large project and will take a good chunk of 2019 to complete.

**Recommendation:** Wait for this minor React release in order to use Suspense for data fetching. Don’t try to use Suspense features in 16.6 for it; it’s not supported. However, your existing `<Suspense>` components for code splitting will be able to show loading states for data too when Suspense for Data Fetching becomes officially supported.

## [](#other-projects)Other Projects

### [](#modernizing-react-dom)Modernizing React DOM

We started an investigation into [simplifying and modernizing](https://github.com/facebook/react/issues/13525) ReactDOM, with a goal of reduced bundle size and aligning closer with the browser behavior. It is still early to say which specific bullet points will “make it” because the project is in an exploratory phase. We will communicate our progress on that issue.

### [](#suspense-for-server-rendering)Suspense for Server Rendering

We started designing a new server renderer that supports Suspense (including waiting for asynchronous data on the server without double rendering) and progressively loading and hydrating page content in chunks for best user experience. You can watch an overview of its early prototype in [this talk](https://www.youtube.com/watch?v=z-6JC0_cOns). The new server renderer is going to be our major focus in 2019, but it’s too early to say anything about its release schedule. Its development, as always, [will happen on GitHub](https://github.com/facebook/react/pulls?utf8=%E2%9C%93\&q=is%3Apr+is%3Aopen+fizz).

***

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

And that’s about it! As you can see, there’s a lot here to keep us busy but we expect much progress in the coming months.

We hope this post gives you an idea of what we’re working on, what you can use today, and what you can expect to use in the future. While there’s a lot of discussion about new features on social media platforms, you won’t miss anything important if you read this blog.

We’re always open to feedback, and love to hear from you in the [RFC repository](https://github.com/reactjs/rfcs), [the issue tracker](https://github.com/facebook/react/issues), and [on Twitter](https://mobile.twitter.com/reactjs).

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2018-11-27-react-16-roadmap.md)

----
url: https://18.react.dev/learn/choosing-the-state-structure
----

```
const [x, setX] = useState(0);

const [y, setY] = useState(0);
```

Or this?

```
const [position, setPosition] = useState({ x: 0, y: 0 });
```

Technically, you can use either of these approaches. But **if some two state variables always change together, it might be a good idea to unify them into a single state variable.** Then you won’t forget to always keep them in sync, like in this example where moving the cursor updates both coordinates of the red dot:

```
import { useState } from 'react';

export default function MovingDot() {
  const [position, setPosition] = useState({
    x: 0,
    y: 0
  });
  return (
    <div
      onPointerMove={e => {
        setPosition({
          x: e.clientX,
          y: e.clientY
        });
      }}
      style={{
        position: 'relative',
        width: '100vw',
        height: '100vh',
      }}>
      <div style={{
        position: 'absolute',
        backgroundColor: 'red',
        borderRadius: '50%',
        transform: `translate(${position.x}px, ${position.y}px)`,
        left: -10,
        top: -10,
        width: 20,
        height: 20,
      }} />
    </div>
  )
}
```

Another case where you’ll group data into an object or an array is when you don’t know how many pieces of state you’ll need. For example, it’s helpful when you have a form where the user can add custom fields.

### Pitfall

If your state variable is an object, remember that [you can’t update only one field in it](/learn/updating-objects-in-state) without explicitly copying the other fields. For example, you can’t do `setPosition({ x: 100 })` in the above example because it would not have the `y` property at all! Instead, if you wanted to set `x` alone, you would either do `setPosition({ ...position, x: 100 })`, or split them into two state variables and do `setX(100)`.

## Avoid contradictions in state[](#avoid-contradictions-in-state "Link for Avoid contradictions in state ")

Here is a hotel feedback form with `isSending` and `isSent` state variables:

```
import { useState } from 'react';

export default function FeedbackForm() {
  const [text, setText] = useState('');
  const [isSending, setIsSending] = useState(false);
  const [isSent, setIsSent] = useState(false);

  async function handleSubmit(e) {
    e.preventDefault();
    setIsSending(true);
    await sendMessage(text);
    setIsSending(false);
    setIsSent(true);
  }

  if (isSent) {
    return <h1>Thanks for feedback!</h1>
  }

  return (
    <form onSubmit={handleSubmit}>
      <p>How was your stay at The Prancing Pony?</p>
      <textarea
        disabled={isSending}
        value={text}
        onChange={e => setText(e.target.value)}
      />
      <br />
      <button
        disabled={isSending}
        type="submit"
      >
        Send
      </button>
      {isSending && <p>Sending...</p>}
    </form>
  );
}

// Pretend to send a message.
function sendMessage(text) {
  return new Promise(resolve => {
    setTimeout(resolve, 2000);
  });
}
```

While this code works, it leaves the door open for “impossible” states. For example, if you forget to call `setIsSent` and `setIsSending` together, you may end up in a situation where both `isSending` and `isSent` are `true` at the same time. The more complex your component is, the harder it is to understand what happened.

**Since `isSending` and `isSent` should never be `true` at the same time, it is better to replace them with one `status` state variable that may take one of *three* valid states:** `'typing'` (initial), `'sending'`, and `'sent'`:

```
import { useState } from 'react';

export default function FeedbackForm() {
  const [text, setText] = useState('');
  const [status, setStatus] = useState('typing');

  async function handleSubmit(e) {
    e.preventDefault();
    setStatus('sending');
    await sendMessage(text);
    setStatus('sent');
  }

  const isSending = status === 'sending';
  const isSent = status === 'sent';

  if (isSent) {
    return <h1>Thanks for feedback!</h1>
  }

  return (
    <form onSubmit={handleSubmit}>
      <p>How was your stay at The Prancing Pony?</p>
      <textarea
        disabled={isSending}
        value={text}
        onChange={e => setText(e.target.value)}
      />
      <br />
      <button
        disabled={isSending}
        type="submit"
      >
        Send
      </button>
      {isSending && <p>Sending...</p>}
    </form>
  );
}

// Pretend to send a message.
function sendMessage(text) {
  return new Promise(resolve => {
    setTimeout(resolve, 2000);
  });
}
```

You can still declare some constants for readability:

```
const isSending = status === 'sending';

const isSent = status === 'sent';
```

But they’re not state variables, so you don’t need to worry about them getting out of sync with each other.

## Avoid redundant state[](#avoid-redundant-state "Link for Avoid redundant state ")

If you can calculate some information from the component’s props or its existing state variables during rendering, you **should not** put that information into that component’s state.

For example, take this form. It works, but can you find any redundant state in it?

```
import { useState } from 'react';

export default function Form() {
  const [firstName, setFirstName] = useState('');
  const [lastName, setLastName] = useState('');
  const [fullName, setFullName] = useState('');

  function handleFirstNameChange(e) {
    setFirstName(e.target.value);
    setFullName(e.target.value + ' ' + lastName);
  }

  function handleLastNameChange(e) {
    setLastName(e.target.value);
    setFullName(firstName + ' ' + e.target.value);
  }

  return (
    <>
      <h2>Let’s check you in</h2>
      <label>
        First name:{' '}
        <input
          value={firstName}
          onChange={handleFirstNameChange}
        />
      </label>
      <label>
        Last name:{' '}
        <input
          value={lastName}
          onChange={handleLastNameChange}
        />
      </label>
      <p>
        Your ticket will be issued to: <b>{fullName}</b>
      </p>
    </>
  );
}
```

This form has three state variables: `firstName`, `lastName`, and `fullName`. However, `fullName` is redundant. **You can always calculate `fullName` from `firstName` and `lastName` during render, so remove it from state.**

This is how you can do it:

```
import { useState } from 'react';

export default function Form() {
  const [firstName, setFirstName] = useState('');
  const [lastName, setLastName] = useState('');

  const fullName = firstName + ' ' + lastName;

  function handleFirstNameChange(e) {
    setFirstName(e.target.value);
  }

  function handleLastNameChange(e) {
    setLastName(e.target.value);
  }

  return (
    <>
      <h2>Let’s check you in</h2>
      <label>
        First name:{' '}
        <input
          value={firstName}
          onChange={handleFirstNameChange}
        />
      </label>
      <label>
        Last name:{' '}
        <input
          value={lastName}
          onChange={handleLastNameChange}
        />
      </label>
      <p>
        Your ticket will be issued to: <b>{fullName}</b>
      </p>
    </>
  );
}
```

Here, `fullName` is *not* a state variable. Instead, it’s calculated during render:

```
const fullName = firstName + ' ' + lastName;
```

As a result, the change handlers don’t need to do anything special to update it. When you call `setFirstName` or `setLastName`, you trigger a re-render, and then the next `fullName` will be calculated from the fresh data.

##### Deep Dive#### Don’t mirror props in state[](#don-t-mirror-props-in-state "Link for Don’t mirror props in state ")

A common example of redundant state is code like this:

```
function Message({ messageColor }) {

  const [color, setColor] = useState(messageColor);
```

Here, a `color` state variable is initialized to the `messageColor` prop. The problem is that **if the parent component passes a different value of `messageColor` later (for example, `'red'` instead of `'blue'`), the `color` *state variable* would not be updated!** The state is only initialized during the first render.

This is why “mirroring” some prop in a state variable can lead to confusion. Instead, use the `messageColor` prop directly in your code. If you want to give it a shorter name, use a constant:

```
function Message({ messageColor }) {

  const color = messageColor;
```

This way it won’t get out of sync with the prop passed from the parent component.

”Mirroring” props into state only makes sense when you *want* to ignore all updates for a specific prop. By convention, start the prop name with `initial` or `default` to clarify that its new values are ignored:

```
function Message({ initialColor }) {

  // The `color` state variable holds the *first* value of `initialColor`.

  // Further changes to the `initialColor` prop are ignored.

  const [color, setColor] = useState(initialColor);
```

## Avoid duplication in state[](#avoid-duplication-in-state "Link for Avoid duplication in state ")

This menu list component lets you choose a single travel snack out of several:

```
import { useState } from 'react';

const initialItems = [
  { title: 'pretzels', id: 0 },
  { title: 'crispy seaweed', id: 1 },
  { title: 'granola bar', id: 2 },
];

export default function Menu() {
  const [items, setItems] = useState(initialItems);
  const [selectedItem, setSelectedItem] = useState(
    items[0]
  );

  return (
    <>
      <h2>What's your travel snack?</h2>
      <ul>
        {items.map(item => (
          <li key={item.id}>
            {item.title}
            {' '}
            <button onClick={() => {
              setSelectedItem(item);
            }}>Choose</button>
          </li>
        ))}
      </ul>
      <p>You picked {selectedItem.title}.</p>
    </>
  );
}
```

Currently, it stores the selected item as an object in the `selectedItem` state variable. However, this is not great: **the contents of the `selectedItem` is the same object as one of the items inside the `items` list.** This means that the information about the item itself is duplicated in two places.

Why is this a problem? Let’s make each item editable:

```
import { useState } from 'react';

const initialItems = [
  { title: 'pretzels', id: 0 },
  { title: 'crispy seaweed', id: 1 },
  { title: 'granola bar', id: 2 },
];

export default function Menu() {
  const [items, setItems] = useState(initialItems);
  const [selectedItem, setSelectedItem] = useState(
    items[0]
  );

  function handleItemChange(id, e) {
    setItems(items.map(item => {
      if (item.id === id) {
        return {
          ...item,
          title: e.target.value,
        };
      } else {
        return item;
      }
    }));
  }

  return (
    <>
      <h2>What's your travel snack?</h2> 
      <ul>
        {items.map((item, index) => (
          <li key={item.id}>
            <input
              value={item.title}
              onChange={e => {
                handleItemChange(item.id, e)
              }}
            />
            {' '}
            <button onClick={() => {
              setSelectedItem(item);
            }}>Choose</button>
          </li>
        ))}
      </ul>
      <p>You picked {selectedItem.title}.</p>
    </>
  );
}
```

Notice how if you first click “Choose” on an item and *then* edit it, **the input updates but the label at the bottom does not reflect the edits.** This is because you have duplicated state, and you forgot to update `selectedItem`.

Although you could update `selectedItem` too, an easier fix is to remove duplication. In this example, instead of a `selectedItem` object (which creates a duplication with objects inside `items`), you hold the `selectedId` in state, and *then* get the `selectedItem` by searching the `items` array for an item with that ID:

```
import { useState } from 'react';

const initialItems = [
  { title: 'pretzels', id: 0 },
  { title: 'crispy seaweed', id: 1 },
  { title: 'granola bar', id: 2 },
];

export default function Menu() {
  const [items, setItems] = useState(initialItems);
  const [selectedId, setSelectedId] = useState(0);

  const selectedItem = items.find(item =>
    item.id === selectedId
  );

  function handleItemChange(id, e) {
    setItems(items.map(item => {
      if (item.id === id) {
        return {
          ...item,
          title: e.target.value,
        };
      } else {
        return item;
      }
    }));
  }

  return (
    <>
      <h2>What's your travel snack?</h2>
      <ul>
        {items.map((item, index) => (
          <li key={item.id}>
            <input
              value={item.title}
              onChange={e => {
                handleItemChange(item.id, e)
              }}
            />
            {' '}
            <button onClick={() => {
              setSelectedId(item.id);
            }}>Choose</button>
          </li>
        ))}
      </ul>
      <p>You picked {selectedItem.title}.</p>
    </>
  );
}
```

```
export const initialTravelPlan = {
  id: 0,
  title: '(Root)',
  childPlaces: [{
    id: 1,
    title: 'Earth',
    childPlaces: [{
      id: 2,
      title: 'Africa',
      childPlaces: [{
        id: 3,
        title: 'Botswana',
        childPlaces: []
      }, {
        id: 4,
        title: 'Egypt',
        childPlaces: []
      }, {
        id: 5,
        title: 'Kenya',
        childPlaces: []
      }, {
        id: 6,
        title: 'Madagascar',
        childPlaces: []
      }, {
        id: 7,
        title: 'Morocco',
        childPlaces: []
      }, {
        id: 8,
        title: 'Nigeria',
        childPlaces: []
      }, {
        id: 9,
        title: 'South Africa',
        childPlaces: []
      }]
    }, {
      id: 10,
      title: 'Americas',
      childPlaces: [{
        id: 11,
        title: 'Argentina',
        childPlaces: []
      }, {
        id: 12,
        title: 'Brazil',
        childPlaces: []
      }, {
        id: 13,
        title: 'Barbados',
        childPlaces: []
      }, {
        id: 14,
        title: 'Canada',
        childPlaces: []
      }, {
        id: 15,
        title: 'Jamaica',
        childPlaces: []
      }, {
        id: 16,
        title: 'Mexico',
        childPlaces: []
      }, {
        id: 17,
        title: 'Trinidad and Tobago',
        childPlaces: []
      }, {
        id: 18,
        title: 'Venezuela',
        childPlaces: []
      }]
    }, {
      id: 19,
      title: 'Asia',
      childPlaces: [{
        id: 20,
        title: 'China',
        childPlaces: []
      }, {
        id: 21,
        title: 'India',
        childPlaces: []
      }, {
        id: 22,
        title: 'Singapore',
        childPlaces: []
      }, {
        id: 23,
        title: 'South Korea',
        childPlaces: []
      }, {
        id: 24,
        title: 'Thailand',
        childPlaces: []
      }, {
        id: 25,
        title: 'Vietnam',
        childPlaces: []
      }]
    }, {
      id: 26,
      title: 'Europe',
      childPlaces: [{
        id: 27,
        title: 'Croatia',
        childPlaces: [],
      }, {
        id: 28,
        title: 'France',
        childPlaces: [],
      }, {
        id: 29,
        title: 'Germany',
        childPlaces: [],
      }, {
        id: 30,
        title: 'Italy',
        childPlaces: [],
      }, {
        id: 31,
        title: 'Portugal',
        childPlaces: [],
      }, {
        id: 32,
        title: 'Spain',
        childPlaces: [],
      }, {
        id: 33,
        title: 'Turkey',
        childPlaces: [],
      }]
    }, {
      id: 34,
      title: 'Oceania',
      childPlaces: [{
        id: 35,
        title: 'Australia',
        childPlaces: [],
      }, {
        id: 36,
        title: 'Bora Bora (French Polynesia)',
        childPlaces: [],
      }, {
        id: 37,
        title: 'Easter Island (Chile)',
        childPlaces: [],
      }, {
        id: 38,
        title: 'Fiji',
        childPlaces: [],
      }, {
        id: 39,
        title: 'Hawaii (the USA)',
        childPlaces: [],
      }, {
        id: 40,
        title: 'New Zealand',
        childPlaces: [],
      }, {
        id: 41,
        title: 'Vanuatu',
        childPlaces: [],
      }]
    }]
  }, {
    id: 42,
    title: 'Moon',
    childPlaces: [{
      id: 43,
      title: 'Rheita',
      childPlaces: []
    }, {
      id: 44,
      title: 'Piccolomini',
      childPlaces: []
    }, {
      id: 45,
      title: 'Tycho',
      childPlaces: []
    }]
  }, {
    id: 46,
    title: 'Mars',
    childPlaces: [{
      id: 47,
      title: 'Corn Town',
      childPlaces: []
    }, {
      id: 48,
      title: 'Green Hill',
      childPlaces: []      
    }]
  }]
};
```

Now let’s say you want to add a button to delete a place you’ve already visited. How would you go about it? [Updating nested state](/learn/updating-objects-in-state#updating-a-nested-object) involves making copies of objects all the way up from the part that changed. Deleting a deeply nested place would involve copying its entire parent place chain. Such code can be very verbose.

**If the state is too nested to update easily, consider making it “flat”.** Here is one way you can restructure this data. Instead of a tree-like structure where each `place` has an array of *its child places*, you can have each place hold an array of *its child place IDs*. Then store a mapping from each place ID to the corresponding place.

This data restructuring might remind you of seeing a database table:

```
export const initialTravelPlan = {
  0: {
    id: 0,
    title: '(Root)',
    childIds: [1, 42, 46],
  },
  1: {
    id: 1,
    title: 'Earth',
    childIds: [2, 10, 19, 26, 34]
  },
  2: {
    id: 2,
    title: 'Africa',
    childIds: [3, 4, 5, 6 , 7, 8, 9]
  }, 
  3: {
    id: 3,
    title: 'Botswana',
    childIds: []
  },
  4: {
    id: 4,
    title: 'Egypt',
    childIds: []
  },
  5: {
    id: 5,
    title: 'Kenya',
    childIds: []
  },
  6: {
    id: 6,
    title: 'Madagascar',
    childIds: []
  }, 
  7: {
    id: 7,
    title: 'Morocco',
    childIds: []
  },
  8: {
    id: 8,
    title: 'Nigeria',
    childIds: []
  },
  9: {
    id: 9,
    title: 'South Africa',
    childIds: []
  },
  10: {
    id: 10,
    title: 'Americas',
    childIds: [11, 12, 13, 14, 15, 16, 17, 18],   
  },
  11: {
    id: 11,
    title: 'Argentina',
    childIds: []
  },
  12: {
    id: 12,
    title: 'Brazil',
    childIds: []
  },
  13: {
    id: 13,
    title: 'Barbados',
    childIds: []
  }, 
  14: {
    id: 14,
    title: 'Canada',
    childIds: []
  },
  15: {
    id: 15,
    title: 'Jamaica',
    childIds: []
  },
  16: {
    id: 16,
    title: 'Mexico',
    childIds: []
  },
  17: {
    id: 17,
    title: 'Trinidad and Tobago',
    childIds: []
  },
  18: {
    id: 18,
    title: 'Venezuela',
    childIds: []
  },
  19: {
    id: 19,
    title: 'Asia',
    childIds: [20, 21, 22, 23, 24, 25],   
  },
  20: {
    id: 20,
    title: 'China',
    childIds: []
  },
  21: {
    id: 21,
    title: 'India',
    childIds: []
  },
  22: {
    id: 22,
    title: 'Singapore',
    childIds: []
  },
  23: {
    id: 23,
    title: 'South Korea',
    childIds: []
  },
  24: {
    id: 24,
    title: 'Thailand',
    childIds: []
  },
  25: {
    id: 25,
    title: 'Vietnam',
    childIds: []
  },
  26: {
    id: 26,
    title: 'Europe',
    childIds: [27, 28, 29, 30, 31, 32, 33],   
  },
  27: {
    id: 27,
    title: 'Croatia',
    childIds: []
  },
  28: {
    id: 28,
    title: 'France',
    childIds: []
  },
  29: {
    id: 29,
    title: 'Germany',
    childIds: []
  },
  30: {
    id: 30,
    title: 'Italy',
    childIds: []
  },
  31: {
    id: 31,
    title: 'Portugal',
    childIds: []
  },
  32: {
    id: 32,
    title: 'Spain',
    childIds: []
  },
  33: {
    id: 33,
    title: 'Turkey',
    childIds: []
  },
  34: {
    id: 34,
    title: 'Oceania',
    childIds: [35, 36, 37, 38, 39, 40, 41],   
  },
  35: {
    id: 35,
    title: 'Australia',
    childIds: []
  },
  36: {
    id: 36,
    title: 'Bora Bora (French Polynesia)',
    childIds: []
  },
  37: {
    id: 37,
    title: 'Easter Island (Chile)',
    childIds: []
  },
  38: {
    id: 38,
    title: 'Fiji',
    childIds: []
  },
  39: {
    id: 40,
    title: 'Hawaii (the USA)',
    childIds: []
  },
  40: {
    id: 40,
    title: 'New Zealand',
    childIds: []
  },
  41: {
    id: 41,
    title: 'Vanuatu',
    childIds: []
  },
  42: {
    id: 42,
    title: 'Moon',
    childIds: [43, 44, 45]
  },
  43: {
    id: 43,
    title: 'Rheita',
    childIds: []
  },
  44: {
    id: 44,
    title: 'Piccolomini',
    childIds: []
  },
  45: {
    id: 45,
    title: 'Tycho',
    childIds: []
  },
  46: {
    id: 46,
    title: 'Mars',
    childIds: [47, 48]
  },
  47: {
    id: 47,
    title: 'Corn Town',
    childIds: []
  },
  48: {
    id: 48,
    title: 'Green Hill',
    childIds: []
  }
};
```

**Now that the state is “flat” (also known as “normalized”), updating nested items becomes easier.**

In order to remove a place now, you only need to update two levels of state:

* The updated version of its *parent* place should exclude the removed ID from its `childIds` array.
* The updated version of the root “table” object should include the updated version of the parent place.

Here is an example of how you could go about it:

```
import { useState } from 'react';
import { initialTravelPlan } from './places.js';

export default function TravelPlan() {
  const [plan, setPlan] = useState(initialTravelPlan);

  function handleComplete(parentId, childId) {
    const parent = plan[parentId];
    // Create a new version of the parent place
    // that doesn't include this child ID.
    const nextParent = {
      ...parent,
      childIds: parent.childIds
        .filter(id => id !== childId)
    };
    // Update the root state object...
    setPlan({
      ...plan,
      // ...so that it has the updated parent.
      [parentId]: nextParent
    });
  }

  const root = plan[0];
  const planetIds = root.childIds;
  return (
    <>
      <h2>Places to visit</h2>
      <ol>
        {planetIds.map(id => (
          <PlaceTree
            key={id}
            id={id}
            parentId={0}
            placesById={plan}
            onComplete={handleComplete}
          />
        ))}
      </ol>
    </>
  );
}

function PlaceTree({ id, parentId, placesById, onComplete }) {
  const place = placesById[id];
  const childIds = place.childIds;
  return (
    <li>
      {place.title}
      <button onClick={() => {
        onComplete(parentId, id);
      }}>
        Complete
      </button>
      {childIds.length > 0 &&
        <ol>
          {childIds.map(childId => (
            <PlaceTree
              key={childId}
              id={childId}
              parentId={id}
              placesById={placesById}
              onComplete={onComplete}
            />
          ))}
        </ol>
      }
    </li>
  );
}
```

You can nest state as much as you like, but making it “flat” can solve numerous problems. It makes state easier to update, and it helps ensure you don’t have duplication in different parts of a nested object.

##### Deep Dive#### Improving memory usage[](#improving-memory-usage "Link for Improving memory usage ")

Ideally, you would also remove the deleted items (and their children!) from the “table” object to improve memory usage. This version does that. It also [uses Immer](/learn/updating-objects-in-state#write-concise-update-logic-with-immer) to make the update logic more concise.

```
{
  "dependencies": {
    "immer": "1.7.3",
    "react": "latest",
    "react-dom": "latest",
    "react-scripts": "latest",
    "use-immer": "0.5.1"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject"
  },
  "devDependencies": {}
}
```

```
import { useState } from 'react';

export default function Clock(props) {
  const [color, setColor] = useState(props.color);
  return (
    <h1 style={{ color: color }}>
      {props.time}
    </h1>
  );
}
```

[PreviousReacting to Input with State](/learn/reacting-to-input-with-state)

[NextSharing State Between Components](/learn/sharing-state-between-components)

***

----
url: https://legacy.reactjs.org/docs/react-dom-client.html
----

> These docs are old and won’t be updated. Go to [react.dev](https://react.dev/) for the new React docs.
>
> These new documentation pages teach modern React:
>
> * [`react-dom`: Client APIs](https://react.dev/reference/react-dom/client)

The `react-dom/client` package provides client-specific methods used for initializing an app on the client. Most of your components should not need to use this module.

```
import * as ReactDOM from 'react-dom/client';
```

If you use ES5 with npm, you can write:

```
var ReactDOM = require('react-dom/client');
```

## [](#overview)Overview

The following methods can be used in client environments:

* [`createRoot()`](#createroot)
* [`hydrateRoot()`](#hydrateroot)

### [](#browser-support)Browser Support

React supports all modern browsers, although [some polyfills are required](/docs/javascript-environment-requirements.html) for older versions.

> Note
>
> We do not support older browsers that don’t support ES5 methods or microtasks such as Internet Explorer. You may find that your apps do work in older browsers if polyfills such as [es5-shim and es5-sham](https://github.com/es-shims/es5-shim) are included in the page, but you’re on your own if you choose to take this path.

## [](#reference)Reference

### [](#createroot)`createRoot()`

> This content is out of date.
>
> Read the new React documentation for [`createRoot`](https://react.dev/reference/react-dom/client/createRoot).

```
createRoot(container[, options]);
```

Create a React root for the supplied `container` and return the root. The root can be used to render a React element into the DOM with `render`:

```
const root = createRoot(container);
root.render(element);
```

`createRoot` accepts two options:

* `onRecoverableError`: optional callback called when React automatically recovers from errors.
* `identifierPrefix`: optional prefix React uses for ids generated by `React.useId`. Useful to avoid conflicts when using multiple roots on the same page. Must be the same prefix used on the server.

The root can also be unmounted with `unmount`:

```
root.unmount();
```

> Note:
>
> `createRoot()` controls the contents of the container node you pass in. Any existing DOM elements inside are replaced when render is called. Later calls use React’s DOM diffing algorithm for efficient updates.
>
> `createRoot()` does not modify the container node (only modifies the children of the container). It may be possible to insert a component to an existing DOM node without overwriting the existing children.
>
> Using `createRoot()` to hydrate a server-rendered container is not supported. Use [`hydrateRoot()`](#hydrateroot) instead.

***

### [](#hydrateroot)`hydrateRoot()`

> This content is out of date.
>
> Read the new React documentation for [`hydrateRoot`](https://react.dev/reference/react-dom/client/hydrateRoot).

```
hydrateRoot(container, element[, options])
```

Same as [`createRoot()`](#createroot), but is used to hydrate a container whose HTML contents were rendered by [`ReactDOMServer`](/docs/react-dom-server.html). React will attempt to attach event listeners to the existing markup.

`hydrateRoot` accepts two options:

* `onRecoverableError`: optional callback called when React automatically recovers from errors.
* `identifierPrefix`: optional prefix React uses for ids generated by `React.useId`. Useful to avoid conflicts when using multiple roots on the same page. Must be the same prefix used on the server.

> Note
>
> React expects that the rendered content is identical between the server and the client. It can patch up differences in text content, but you should treat mismatches as bugs and fix them. In development mode, React warns about mismatches during hydration. There are no guarantees that attribute differences will be patched up in case of mismatches. This is important for performance reasons because in most apps, mismatches are rare, and so validating all markup would be prohibitively expensive.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/reference-react-dom-client.md)

----
url: https://react.dev/reference/react-dom/components/textarea
----

[API Reference](/reference/react)

[Components](/reference/react-dom/components)

# \<textarea>[](#undefined "Link for this heading")

The [built-in browser `<textarea>` component](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea) lets you render a multiline text input.

```
<textarea />
```

***

## Reference[](#reference "Link for Reference ")

### `<textarea>`[](#textarea "Link for this heading")

To display a text area, render the [built-in browser `<textarea>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea) component.

```
<textarea name="postContent" />
```

[See more examples below.](#usage)

#### Props[](#props "Link for Props ")

`<textarea>` supports all [common element props.](/reference/react-dom/components/common#common-props)

***

## Usage[](#usage "Link for Usage ")

### Displaying a text area[](#displaying-a-text-area "Link for Displaying a text area ")

Render `<textarea>` to display a text area. You can specify its default size with the [`rows`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea#rows) and [`cols`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea#cols) attributes, but by default the user will be able to resize it. To disable resizing, you can specify `resize: none` in the CSS.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
export default function NewPost() {
  return (
    <label>
      Write your post:
      <textarea name="postContent" rows={4} cols={40} />
    </label>
  );
}
```

***

### Providing a label for a text area[](#providing-a-label-for-a-text-area "Link for Providing a label for a text area ")

Typically, you will place every `<textarea>` inside a [`<label>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/label) tag. This tells the browser that this label is associated with that text area. When the user clicks the label, the browser will focus the text area. It’s also essential for accessibility: a screen reader will announce the label caption when the user focuses the text area.

If you can’t nest `<textarea>` into a `<label>`, associate them by passing the same ID to `<textarea id>` and [`<label htmlFor>`.](https://developer.mozilla.org/en-US/docs/Web/API/HTMLLabelElement/htmlFor) To avoid conflicts between instances of one component, generate such an ID with [`useId`.](/reference/react/useId)

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useId } from 'react';

export default function Form() {
  const postTextAreaId = useId();
  return (
    <>
      <label htmlFor={postTextAreaId}>
        Write your post:
      </label>
      <textarea
        id={postTextAreaId}
        name="postContent"
        rows={4}
        cols={40}
      />
    </>
  );
}
```

***

### Providing an initial value for a text area[](#providing-an-initial-value-for-a-text-area "Link for Providing an initial value for a text area ")

You can optionally specify the initial value for the text area. Pass it as the `defaultValue` string.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
export default function EditPost() {
  return (
    <label>
      Edit your post:
      <textarea
        name="postContent"
        defaultValue="I really enjoyed biking yesterday!"
        rows={4}
        cols={40}
      />
    </label>
  );
}
```

### Pitfall

Unlike in HTML, passing initial text like `<textarea>Some content</textarea>` is not supported.

***

### Reading the text area value when submitting a form[](#reading-the-text-area-value-when-submitting-a-form "Link for Reading the text area value when submitting a form ")

Add a [`<form>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form) around your textarea with a [`<button type="submit">`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button) inside. It will call your `<form onSubmit>` event handler. By default, the browser will send the form data to the current URL and refresh the page. You can override that behavior by calling `e.preventDefault()`. Read the form data with [`new FormData(e.target)`](https://developer.mozilla.org/en-US/docs/Web/API/FormData).

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
export default function EditPost() {
  function handleSubmit(e) {
    // Prevent the browser from reloading the page
    e.preventDefault();

    // Read the form data
    const form = e.target;
    const formData = new FormData(form);

    // You can pass formData as a fetch body directly:
    fetch('/some-api', { method: form.method, body: formData });

    // Or you can work with it as a plain object:
    const formJson = Object.fromEntries(formData.entries());
    console.log(formJson);
  }

  return (
    <form method="post" onSubmit={handleSubmit}>
      <label>
        Post title: <input name="postTitle" defaultValue="Biking" />
      </label>
      <label>
        Edit your post:
        <textarea
          name="postContent"
          defaultValue="I really enjoyed biking yesterday!"
          rows={4}
          cols={40}
        />
      </label>
      <hr />
      <button type="reset">Reset edits</button>
      <button type="submit">Save post</button>
    </form>
  );
}
```

### Note

Give a `name` to your `<textarea>`, for example `<textarea name="postContent" />`. The `name` you specified will be used as a key in the form data, for example `{ postContent: "Your post" }`.

### Pitfall

By default, *any* `<button>` inside a `<form>` will submit it. This can be surprising! If you have your own custom `Button` React component, consider returning [`<button type="button">`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/button) instead of `<button>`. Then, to be explicit, use `<button type="submit">` for buttons that *are* supposed to submit the form.

***

### Controlling a text area with a state variable[](#controlling-a-text-area-with-a-state-variable "Link for Controlling a text area with a state variable ")

A text area like `<textarea />` is *uncontrolled.* Even if you [pass an initial value](#providing-an-initial-value-for-a-text-area) like `<textarea defaultValue="Initial text" />`, your JSX only specifies the initial value, not the value right now.

**To render a *controlled* text area, pass the `value` prop to it.** React will force the text area to always have the `value` you passed. Typically, you will control a text area by declaring a [state variable:](/reference/react/useState)

```
function NewPost() {

  const [postContent, setPostContent] = useState(''); // Declare a state variable...

  // ...

  return (

    <textarea

      value={postContent} // ...force the input's value to match the state variable...

      onChange={e => setPostContent(e.target.value)} // ... and update the state variable on any edits!

    />

  );

}
```

This is useful if you want to re-render some part of the UI in response to every keystroke.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
{
  "dependencies": {
    "react": "latest",
    "react-dom": "latest",
    "react-scripts": "latest",
    "remarkable": "2.0.1"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject"
  },
  "devDependencies": {}
}
```

### Pitfall

**If you pass `value` without `onChange`, it will be impossible to type into the text area.** When you control a text area by passing some `value` to it, you *force* it to always have the value you passed. So if you pass a state variable as a `value` but forget to update that state variable synchronously during the `onChange` event handler, React will revert the text area after every keystroke back to the `value` that you specified.

***

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### My text area doesn’t update when I type into it[](#my-text-area-doesnt-update-when-i-type-into-it "Link for My text area doesn’t update when I type into it ")

If you render a text area with `value` but no `onChange`, you will see an error in the console:

```
// 🔴 Bug: controlled text area with no onChange handler

<textarea value={something} />
```

Console

You provided a `value` prop to a form field without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultValue`. Otherwise, set either `onChange` or `readOnly`.

As the error message suggests, if you only wanted to [specify the *initial* value,](#providing-an-initial-value-for-a-text-area) pass `defaultValue` instead:

```
// ✅ Good: uncontrolled text area with an initial value

<textarea defaultValue={something} />
```

If you want [to control this text area with a state variable,](#controlling-a-text-area-with-a-state-variable) specify an `onChange` handler:

```
// ✅ Good: controlled text area with onChange

<textarea value={something} onChange={e => setSomething(e.target.value)} />
```

If the value is intentionally read-only, add a `readOnly` prop to suppress the error:

```
// ✅ Good: readonly controlled text area without on change

<textarea value={something} readOnly={true} />
```

***

### My text area caret jumps to the beginning on every keystroke[](#my-text-area-caret-jumps-to-the-beginning-on-every-keystroke "Link for My text area caret jumps to the beginning on every keystroke ")

If you [control a text area,](#controlling-a-text-area-with-a-state-variable) you must update its state variable to the text area’s value from the DOM during `onChange`.

You can’t update it to something other than `e.target.value`:

```
function handleChange(e) {

  // 🔴 Bug: updating an input to something other than e.target.value

  setFirstName(e.target.value.toUpperCase());

}
```

You also can’t update it asynchronously:

```
function handleChange(e) {

  // 🔴 Bug: updating an input asynchronously

  setTimeout(() => {

    setFirstName(e.target.value);

  }, 100);

}
```

To fix your code, update it synchronously to `e.target.value`:

```
function handleChange(e) {

  // ✅ Updating a controlled input to e.target.value synchronously

  setFirstName(e.target.value);

}
```

If this doesn’t fix the problem, it’s possible that the text area gets removed and re-added from the DOM on every keystroke. This can happen if you’re accidentally [resetting state](/learn/preserving-and-resetting-state) on every re-render. For example, this can happen if the text area or one of its parents always receives a different `key` attribute, or if you nest component definitions (which is not allowed in React and causes the “inner” component to remount on every render).

***

### I’m getting an error: “A component is changing an uncontrolled input to be controlled”[](#im-getting-an-error-a-component-is-changing-an-uncontrolled-input-to-be-controlled "Link for I’m getting an error: “A component is changing an uncontrolled input to be controlled” ")

If you provide a `value` to the component, it must remain a string throughout its lifetime.

You cannot pass `value={undefined}` first and later pass `value="some string"` because React won’t know whether you want the component to be uncontrolled or controlled. A controlled component should always receive a string `value`, not `null` or `undefined`.

If your `value` is coming from an API or a state variable, it might be initialized to `null` or `undefined`. In that case, either set it to an empty string (`''`) initially, or pass `value={someValue ?? ''}` to ensure `value` is a string.

[Previous\<select>](/reference/react-dom/components/select)

[Next\<link>](/reference/react-dom/components/link)

***

----
url: https://react.dev/reference/react/memo
----

[API Reference](/reference/react)

[APIs](/reference/react/apis)

# memo[](#undefined "Link for this heading")

`memo` lets you skip re-rendering a component when its props are unchanged.

```
const MemoizedComponent = memo(SomeComponent, arePropsEqual?)
```

### Note

[React Compiler](/learn/react-compiler) automatically applies the equivalent of `memo` to all components, reducing the need for manual memoization. You can use the compiler to handle component memoization automatically.

  * [Do I still need React.memo if I use React Compiler?](#react-compiler-memo)

* [Troubleshooting](#troubleshooting)
  * [My component re-renders when a prop is an object, array, or function](#my-component-rerenders-when-a-prop-is-an-object-or-array)

***

## Reference[](#reference "Link for Reference ")

### `memo(Component, arePropsEqual?)`[](#memo "Link for this heading")

Wrap a component in `memo` to get a *memoized* version of that component. This memoized version of your component will usually not be re-rendered when its parent component is re-rendered as long as its props have not changed. But React may still re-render it: memoization is a performance optimization, not a guarantee.

```
import { memo } from 'react';



const SomeComponent = memo(function SomeComponent(props) {

  // ...

});
```

[See more examples below.](#usage)

#### Parameters[](#parameters "Link for Parameters ")

* `Component`: The component that you want to memoize. The `memo` does not modify this component, but returns a new, memoized component instead. Any valid React component, including functions and [`forwardRef`](/reference/react/forwardRef) components, is accepted.

* **optional** `arePropsEqual`: A function that accepts two arguments: the component’s previous props, and its new props. It should return `true` if the old and new props are equal: that is, if the component will render the same output and behave in the same way with the new props as with the old. Otherwise it should return `false`. Usually, you will not specify this function. By default, React will compare each prop with [`Object.is`.](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is)

#### Returns[](#returns "Link for Returns ")

`memo` returns a new React component. It behaves the same as the component provided to `memo` except that React will not always re-render it when its parent is being re-rendered unless its props have changed.

***

## Usage[](#usage "Link for Usage ")

### Skipping re-rendering when props are unchanged[](#skipping-re-rendering-when-props-are-unchanged "Link for Skipping re-rendering when props are unchanged ")

React normally re-renders a component whenever its parent re-renders. With `memo`, you can create a component that React will not re-render when its parent re-renders so long as its new props are the same as the old props. Such a component is said to be *memoized*.

To memoize a component, wrap it in `memo` and use the value that it returns in place of your original component:

```
const Greeting = memo(function Greeting({ name }) {

  return <h1>Hello, {name}!</h1>;

});



export default Greeting;
```

A React component should always have [pure rendering logic.](/learn/keeping-components-pure) This means that it must return the same output if its props, state, and context haven’t changed. By using `memo`, you are telling React that your component complies with this requirement, so React doesn’t need to re-render as long as its props haven’t changed. Even with `memo`, your component will re-render if its own state changes or if a context that it’s using changes.

In this example, notice that the `Greeting` component re-renders whenever `name` is changed (because that’s one of its props), but not when `address` is changed (because it’s not passed to `Greeting` as a prop):

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { memo, useState } from 'react';

export default function MyApp() {
  const [name, setName] = useState('');
  const [address, setAddress] = useState('');
  return (
    <>
      <label>
        Name{': '}
        <input value={name} onChange={e => setName(e.target.value)} />
      </label>
      <label>
        Address{': '}
        <input value={address} onChange={e => setAddress(e.target.value)} />
      </label>
      <Greeting name={name} />
    </>
  );
}

const Greeting = memo(function Greeting({ name }) {
  console.log("Greeting was rendered at", new Date().toLocaleTimeString());
  return <h3>Hello{name && ', '}{name}!</h3>;
});
```

***

### Updating a memoized component using state[](#updating-a-memoized-component-using-state "Link for Updating a memoized component using state ")

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

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { memo, useState } from 'react';

export default function MyApp() {
  const [name, setName] = useState('');
  const [address, setAddress] = useState('');
  return (
    <>
      <label>
        Name{': '}
        <input value={name} onChange={e => setName(e.target.value)} />
      </label>
      <label>
        Address{': '}
        <input value={address} onChange={e => setAddress(e.target.value)} />
      </label>
      <Greeting name={name} />
    </>
  );
}

const Greeting = memo(function Greeting({ name }) {
  console.log('Greeting was rendered at', new Date().toLocaleTimeString());
  const [greeting, setGreeting] = useState('Hello');
  return (
    <>
      <h3>{greeting}{name && ', '}{name}!</h3>
      <GreetingSelector value={greeting} onChange={setGreeting} />
    </>
  );
});

function GreetingSelector({ value, onChange }) {
  return (
    <>
      <label>
        <input
          type="radio"
          checked={value === 'Hello'}
          onChange={e => onChange('Hello')}
        />
        Regular greeting
      </label>
      <label>
        <input
          type="radio"
          checked={value === 'Hello and welcome'}
          onChange={e => onChange('Hello and welcome')}
        />
        Enthusiastic greeting
      </label>
    </>
  );
}
```

If you set a state variable to its current value, React will skip re-rendering your component even without `memo`. You may still see your component function being called an extra time, but the result will be discarded.

***

### Updating a memoized component using a context[](#updating-a-memoized-component-using-a-context "Link for Updating a memoized component using a context ")

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

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { createContext, memo, useContext, useState } from 'react';

const ThemeContext = createContext(null);

export default function MyApp() {
  const [theme, setTheme] = useState('dark');

  function handleClick() {
    setTheme(theme === 'dark' ? 'light' : 'dark');
  }

  return (
    <ThemeContext value={theme}>
      <button onClick={handleClick}>
        Switch theme
      </button>
      <Greeting name="Taylor" />
    </ThemeContext>
  );
}

const Greeting = memo(function Greeting({ name }) {
  console.log("Greeting was rendered at", new Date().toLocaleTimeString());
  const theme = useContext(ThemeContext);
  return (
    <h3 className={theme}>Hello, {name}!</h3>
  );
});
```

To make your component re-render only when a *part* of some context changes, split your component in two. Read what you need from the context in the outer component, and pass it down to a memoized child as a prop.

***

### Minimizing props changes[](#minimizing-props-changes "Link for Minimizing props changes ")

When you use `memo`, your component re-renders whenever any prop is not *shallowly equal* to what it was previously. This means that React compares every prop in your component with its previous value using the [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) comparison. Note that `Object.is(3, 3)` is `true`, but `Object.is({}, {})` is `false`.

To get the most out of `memo`, minimize the times that the props change. For example, if the prop is an object, prevent the parent component from re-creating that object every time by using [`useMemo`:](/reference/react/useMemo)

```
function Page() {

  const [name, setName] = useState('Taylor');

  const [age, setAge] = useState(42);



  const person = useMemo(

    () => ({ name, age }),

    [name, age]

  );



  return <Profile person={person} />;

}



const Profile = memo(function Profile({ person }) {

  // ...

});
```

A better way to minimize props changes is to make sure the component accepts the minimum necessary information in its props. For example, it could accept individual values instead of a whole object:

```
function Page() {

  const [name, setName] = useState('Taylor');

  const [age, setAge] = useState(42);

  return <Profile name={name} age={age} />;

}



const Profile = memo(function Profile({ name, age }) {

  // ...

});
```

Even individual values can sometimes be projected to ones that change less frequently. For example, here a component accepts a boolean indicating the presence of a value rather than the value itself:

```
function GroupsLanding({ person }) {

  const hasGroups = person.groups !== null;

  return <CallToAction hasGroups={hasGroups} />;

}



const CallToAction = memo(function CallToAction({ hasGroups }) {

  // ...

});
```

When you need to pass a function to memoized component, either declare it outside your component so that it never changes, or [`useCallback`](/reference/react/useCallback#skipping-re-rendering-of-components) to cache its definition between re-renders.

***

### Specifying a custom comparison function[](#specifying-a-custom-comparison-function "Link for Specifying a custom comparison function ")

In rare cases it may be infeasible to minimize the props changes of a memoized component. In that case, you can provide a custom comparison function, which React will use to compare the old and new props instead of using shallow equality. This function is passed as a second argument to `memo`. It should return `true` only if the new props would result in the same output as the old props; otherwise it should return `false`.

```
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;

    })

  );

}
```

If you do this, use the Performance panel in your browser developer tools to make sure that your comparison function is actually faster than re-rendering the component. You might be surprised.

When you do performance measurements, make sure that React is running in the production mode.

### Pitfall

If you provide a custom `arePropsEqual` implementation, **you must compare every prop, including functions.** Functions often [close over](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures) the props and state of parent components. If you return `true` when `oldProps.onClick !== newProps.onClick`, your component will keep “seeing” the props and state from a previous render inside its `onClick` handler, leading to very confusing bugs.

Avoid doing deep equality checks inside `arePropsEqual` unless you are 100% sure that the data structure you’re working with has a known limited depth. **Deep equality checks can become incredibly slow** and can freeze your app for many seconds if someone changes the data structure later.

***

### Do I still need React.memo if I use React Compiler?[](#react-compiler-memo "Link for Do I still need React.memo if I use React Compiler? ")

When you enable [React Compiler](/learn/react-compiler), you typically don’t need `React.memo` anymore. The compiler automatically optimizes component re-rendering for you.

Here’s how it works:

**Without React Compiler**, you need `React.memo` to prevent unnecessary re-renders:

```
// Parent re-renders every second

function Parent() {

  const [seconds, setSeconds] = useState(0);



  useEffect(() => {

    const interval = setInterval(() => {

      setSeconds(s => s + 1);

    }, 1000);

    return () => clearInterval(interval);

  }, []);



  return (

    <>

      <h1>Seconds: {seconds}</h1>

      <ExpensiveChild name="John" />

    </>

  );

}



// Without memo, this re-renders every second even though props don't change

const ExpensiveChild = memo(function ExpensiveChild({ name }) {

  console.log('ExpensiveChild rendered');

  return <div>Hello, {name}!</div>;

});
```

**With React Compiler enabled**, the same optimization happens automatically:

```
// No memo needed - compiler prevents re-renders automatically

function ExpensiveChild({ name }) {

  console.log('ExpensiveChild rendered');

  return <div>Hello, {name}!</div>;

}
```

Here’s the key part of what the React Compiler generates:

```
function Parent() {

  const $ = _c(7);

  const [seconds, setSeconds] = useState(0);

  // ... other code ...



  let t3;

  if ($[4] === Symbol.for("react.memo_cache_sentinel")) {

    t3 = <ExpensiveChild name="John" />;

    $[4] = t3;

  } else {

    t3 = $[4];

  }

  // ... return statement ...

}
```

Notice the highlighted lines: The compiler wraps `<ExpensiveChild name="John" />` in a cache check. Since the `name` prop is always `"John"`, this JSX is created once and reused on every parent re-render. This is exactly what `React.memo` does - it prevents the child from re-rendering when its props haven’t changed.

The React Compiler automatically:

1. Tracks that the `name` prop passed to `ExpensiveChild` hasn’t changed
2. Reuses the previously created JSX for `<ExpensiveChild name="John" />`
3. Skips re-rendering `ExpensiveChild` entirely

This means **you can safely remove `React.memo` from your components when using React Compiler**. The compiler provides the same optimization automatically, making your code cleaner and easier to maintain.

### Note

The compiler’s optimization is actually more comprehensive than `React.memo`. It also memoizes intermediate values and expensive computations within your components, similar to combining `React.memo` with `useMemo` throughout your component tree.

***

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### My component re-renders when a prop is an object, array, or function[](#my-component-rerenders-when-a-prop-is-an-object-or-array "Link for My component re-renders when a prop is an object, array, or function ")

React compares old and new props by shallow equality: that is, it considers whether each new prop is reference-equal to the old prop. If you create a new object or array each time the parent is re-rendered, even if the individual elements are each the same, React will still consider it to be changed. Similarly, if you create a new function when rendering the parent component, React will consider it to have changed even if the function has the same definition. To avoid this, [simplify props or memoize props in the parent component](#minimizing-props-changes).

[Previouslazy](/reference/react/lazy)

[NextstartTransition](/reference/react/startTransition)

***

----
url: https://react.dev/reference/react-dom/server/renderToPipeableStream
----

[API Reference](/reference/react)

[Server APIs](/reference/react-dom/server)

# renderToPipeableStream[](#undefined "Link for this heading")

`renderToPipeableStream` renders a React tree to a pipeable [Node.js Stream.](https://nodejs.org/api/stream.html)

```
const { pipe, abort } = renderToPipeableStream(reactNode, options?)
```

***

## Reference[](#reference "Link for Reference ")

### `renderToPipeableStream(reactNode, options?)`[](#rendertopipeablestream "Link for this heading")

Call `renderToPipeableStream` to render your React tree as HTML into a [Node.js Stream.](https://nodejs.org/api/stream.html#writable-streams)

```
import { renderToPipeableStream } from 'react-dom/server';



const { pipe } = renderToPipeableStream(<App />, {

  bootstrapScripts: ['/main.js'],

  onShellReady() {

    response.setHeader('content-type', 'text/html');

    pipe(response);

  }

});
```

***

## Usage[](#usage "Link for Usage ")

### Rendering a React tree as HTML to a Node.js Stream[](#rendering-a-react-tree-as-html-to-a-nodejs-stream "Link for Rendering a React tree as HTML to a Node.js Stream ")

Call `renderToPipeableStream` to render your React tree as HTML into a [Node.js Stream:](https://nodejs.org/api/stream.html#writable-streams)

```
import { renderToPipeableStream } from 'react-dom/server';



// The route handler syntax depends on your backend framework

app.use('/', (request, response) => {

  const { pipe } = renderToPipeableStream(<App />, {

    bootstrapScripts: ['/main.js'],

    onShellReady() {

      response.setHeader('content-type', 'text/html');

      pipe(response);

    }

  });

});
```

Along with the root component, you need to provide a list of bootstrap `<script>` paths. Your root component should return **the entire document including the root `<html>` tag.**

For example, it might look like this:

```
export default function App() {

  return (

    <html>

      <head>

        <meta charSet="utf-8" />

        <meta name="viewport" content="width=device-width, initial-scale=1" />

        <link rel="stylesheet" href="/styles.css"></link>

        <title>My app</title>

      </head>

      <body>

        <Router />

      </body>

    </html>

  );

}
```

React will inject the [doctype](https://developer.mozilla.org/en-US/docs/Glossary/Doctype) and your bootstrap `<script>` tags into the resulting HTML stream:

```
<!DOCTYPE html>

<html>

  <!-- ... HTML from your components ... -->

</html>

<script src="/main.js" async=""></script>
```

On the client, your bootstrap script should [hydrate the entire `document` with a call to `hydrateRoot`:](/reference/react-dom/client/hydrateRoot#hydrating-an-entire-document)

```
import { hydrateRoot } from 'react-dom/client';

import App from './App.js';



hydrateRoot(document, <App />);
```

This will attach event listeners to the server-generated HTML and make it interactive.

##### Deep Dive#### Reading CSS and JS asset paths from the build output[](#reading-css-and-js-asset-paths-from-the-build-output "Link for Reading CSS and JS asset paths from the build output ")

The final asset URLs (like JavaScript and CSS files) are often hashed after the build. For example, instead of `styles.css` you might end up with `styles.123456.css`. Hashing static asset filenames guarantees that every distinct build of the same asset will have a different filename. This is useful because it lets you safely enable long-term caching for static assets: a file with a certain name would never change content.

However, if you don’t know the asset URLs until after the build, there’s no way for you to put them in the source code. For example, hardcoding `"/styles.css"` into JSX like earlier wouldn’t work. To keep them out of your source code, your root component can read the real filenames from a map passed as a prop:

```
export default function App({ assetMap }) {

  return (

    <html>

      <head>

        ...

        <link rel="stylesheet" href={assetMap['styles.css']}></link>

        ...

      </head>

      ...

    </html>

  );

}
```

On the server, render `<App assetMap={assetMap} />` and pass your `assetMap` with the asset URLs:

```
// You'd need to get this JSON from your build tooling, e.g. read it from the build output.

const assetMap = {

  'styles.css': '/styles.123456.css',

  'main.js': '/main.123456.js'

};



app.use('/', (request, response) => {

  const { pipe } = renderToPipeableStream(<App assetMap={assetMap} />, {

    bootstrapScripts: [assetMap['main.js']],

    onShellReady() {

      response.setHeader('content-type', 'text/html');

      pipe(response);

    }

  });

});
```

Since your server is now rendering `<App assetMap={assetMap} />`, you need to render it with `assetMap` on the client too to avoid hydration errors. You can serialize and pass `assetMap` to the client like this:

```
// You'd need to get this JSON from your build tooling.

const assetMap = {

  'styles.css': '/styles.123456.css',

  'main.js': '/main.123456.js'

};



app.use('/', (request, response) => {

  const { pipe } = renderToPipeableStream(<App assetMap={assetMap} />, {

    // Careful: It's safe to stringify() this because this data isn't user-generated.

    bootstrapScriptContent: `window.assetMap = ${JSON.stringify(assetMap)};`,

    bootstrapScripts: [assetMap['main.js']],

    onShellReady() {

      response.setHeader('content-type', 'text/html');

      pipe(response);

    }

  });

});
```

In the example above, the `bootstrapScriptContent` option adds an extra inline `<script>` tag that sets the global `window.assetMap` variable on the client. This lets the client code read the same `assetMap`:

```
import { hydrateRoot } from 'react-dom/client';

import App from './App.js';



hydrateRoot(document, <App assetMap={window.assetMap} />);
```

Both client and server render `App` with the same `assetMap` prop, so there are no hydration errors.

***

### Streaming more content as it loads[](#streaming-more-content-as-it-loads "Link for Streaming more content as it loads ")

Streaming allows the user to start seeing the content even before all the data has loaded on the server. For example, consider a profile page that shows a cover, a sidebar with friends and photos, and a list of posts:

```
function ProfilePage() {

  return (

    <ProfileLayout>

      <ProfileCover />

      <Sidebar>

        <Friends />

        <Photos />

      </Sidebar>

      <Posts />

    </ProfileLayout>

  );

}
```

Imagine that loading data for `<Posts />` takes some time. Ideally, you’d want to show the rest of the profile page content to the user without waiting for the posts. To do this, [wrap `Posts` in a `<Suspense>` boundary:](/reference/react/Suspense#displaying-a-fallback-while-content-is-loading)

```
function ProfilePage() {

  return (

    <ProfileLayout>

      <ProfileCover />

      <Sidebar>

        <Friends />

        <Photos />

      </Sidebar>

      <Suspense fallback={<PostsGlimmer />}>

        <Posts />

      </Suspense>

    </ProfileLayout>

  );

}
```

This tells React to start streaming the HTML before `Posts` loads its data. React will send the HTML for the loading fallback (`PostsGlimmer`) first, and then, when `Posts` finishes loading its data, React will send the remaining HTML along with an inline `<script>` tag that replaces the loading fallback with that HTML. From the user’s perspective, the page will first appear with the `PostsGlimmer`, later replaced by the `Posts`.

You can further [nest `<Suspense>` boundaries](/reference/react/Suspense#revealing-nested-content-as-it-loads) to create a more granular loading sequence:

```
function ProfilePage() {

  return (

    <ProfileLayout>

      <ProfileCover />

      <Suspense fallback={<BigSpinner />}>

        <Sidebar>

          <Friends />

          <Photos />

        </Sidebar>

        <Suspense fallback={<PostsGlimmer />}>

          <Posts />

        </Suspense>

      </Suspense>

    </ProfileLayout>

  );

}
```

***

### Specifying what goes into the shell[](#specifying-what-goes-into-the-shell "Link for Specifying what goes into the shell ")

The part of your app outside of any `<Suspense>` boundaries is called *the shell:*

```
function ProfilePage() {

  return (

    <ProfileLayout>

      <ProfileCover />

      <Suspense fallback={<BigSpinner />}>

        <Sidebar>

          <Friends />

          <Photos />

        </Sidebar>

        <Suspense fallback={<PostsGlimmer />}>

          <Posts />

        </Suspense>

      </Suspense>

    </ProfileLayout>

  );

}
```

It determines the earliest loading state that the user may see:

```
<ProfileLayout>

  <ProfileCover />

  <BigSpinner />

</ProfileLayout>
```

If you wrap the whole app into a `<Suspense>` boundary at the root, the shell will only contain that spinner. However, that’s not a pleasant user experience because seeing a big spinner on the screen can feel slower and more annoying than waiting a bit more and seeing the real layout. This is why usually you’ll want to place the `<Suspense>` boundaries so that the shell feels *minimal but complete*—like a skeleton of the entire page layout.

The `onShellReady` callback fires when the entire shell has been rendered. Usually, you’ll start streaming then:

```
const { pipe } = renderToPipeableStream(<App />, {

  bootstrapScripts: ['/main.js'],

  onShellReady() {

    response.setHeader('content-type', 'text/html');

    pipe(response);

  }

});
```

By the time `onShellReady` fires, components in nested `<Suspense>` boundaries might still be loading data.

***

### Logging crashes on the server[](#logging-crashes-on-the-server "Link for Logging crashes on the server ")

By default, all errors on the server are logged to console. You can override this behavior to log crash reports:

```
const { pipe } = renderToPipeableStream(<App />, {

  bootstrapScripts: ['/main.js'],

  onShellReady() {

    response.setHeader('content-type', 'text/html');

    pipe(response);

  },

  onError(error) {

    console.error(error);

    logServerCrashReport(error);

  }

});
```

If you provide a custom `onError` implementation, don’t forget to also log errors to the console like above.

***

### Recovering from errors inside the shell[](#recovering-from-errors-inside-the-shell "Link for Recovering from errors inside the shell ")

In this example, the shell contains `ProfileLayout`, `ProfileCover`, and `PostsGlimmer`:

```
function ProfilePage() {

  return (

    <ProfileLayout>

      <ProfileCover />

      <Suspense fallback={<PostsGlimmer />}>

        <Posts />

      </Suspense>

    </ProfileLayout>

  );

}
```

If an error occurs while rendering those components, React won’t have any meaningful HTML to send to the client. Override `onShellError` to send a fallback HTML that doesn’t rely on server rendering as the last resort:

```
const { pipe } = renderToPipeableStream(<App />, {

  bootstrapScripts: ['/main.js'],

  onShellReady() {

    response.setHeader('content-type', 'text/html');

    pipe(response);

  },

  onShellError(error) {

    response.statusCode = 500;

    response.setHeader('content-type', 'text/html');

    response.send('<h1>Something went wrong</h1>');

  },

  onError(error) {

    console.error(error);

    logServerCrashReport(error);

  }

});
```

If there is an error while generating the shell, both `onError` and `onShellError` will fire. Use `onError` for error reporting and use `onShellError` to send the fallback HTML document. Your fallback HTML does not have to be an error page. Instead, you may include an alternative shell that renders your app on the client only.

***

### Recovering from errors outside the shell[](#recovering-from-errors-outside-the-shell "Link for Recovering from errors outside the shell ")

In this example, the `<Posts />` component is wrapped in `<Suspense>` so it is *not* a part of the shell:

```
function ProfilePage() {

  return (

    <ProfileLayout>

      <ProfileCover />

      <Suspense fallback={<PostsGlimmer />}>

        <Posts />

      </Suspense>

    </ProfileLayout>

  );

}
```

If an error happens in the `Posts` component or somewhere inside it, React will [try to recover from it:](/reference/react/Suspense#providing-a-fallback-for-server-errors-and-client-only-content)

1. It will emit the loading fallback for the closest `<Suspense>` boundary (`PostsGlimmer`) into the HTML.
2. It will “give up” on trying to render the `Posts` content on the server anymore.
3. When the JavaScript code loads on the client, React will *retry* rendering `Posts` on the client.

If retrying rendering `Posts` on the client *also* fails, React will throw the error on the client. As with all the errors thrown during rendering, the [closest parent error boundary](/reference/react/Component#static-getderivedstatefromerror) determines how to present the error to the user. In practice, this means that the user will see a loading indicator until it is certain that the error is not recoverable.

If retrying rendering `Posts` on the client succeeds, the loading fallback from the server will be replaced with the client rendering output. The user will not know that there was a server error. However, the server `onError` callback and the client [`onRecoverableError`](/reference/react-dom/client/hydrateRoot#hydrateroot) callbacks will fire so that you can get notified about the error.

***

### Setting the status code[](#setting-the-status-code "Link for Setting the status code ")

Streaming introduces a tradeoff. You want to start streaming the page as early as possible so that the user can see the content sooner. However, once you start streaming, you can no longer set the response status code.

By [dividing your app](#specifying-what-goes-into-the-shell) into the shell (above all `<Suspense>` boundaries) and the rest of the content, you’ve already solved a part of this problem. If the shell errors, you’ll get the `onShellError` callback which lets you set the error status code. Otherwise, you know that the app may recover on the client, so you can send “OK”.

```
const { pipe } = renderToPipeableStream(<App />, {

  bootstrapScripts: ['/main.js'],

  onShellReady() {

    response.statusCode = 200;

    response.setHeader('content-type', 'text/html');

    pipe(response);

  },

  onShellError(error) {

    response.statusCode = 500;

    response.setHeader('content-type', 'text/html');

    response.send('<h1>Something went wrong</h1>');

  },

  onError(error) {

    console.error(error);

    logServerCrashReport(error);

  }

});
```

If a component *outside* the shell (i.e. inside a `<Suspense>` boundary) throws an error, React will not stop rendering. This means that the `onError` callback will fire, but you will still get `onShellReady` instead of `onShellError`. This is because React will try to recover from that error on the client, [as described above.](#recovering-from-errors-outside-the-shell)

However, if you’d like, you can use the fact that something has errored to set the status code:

```
let didError = false;



const { pipe } = renderToPipeableStream(<App />, {

  bootstrapScripts: ['/main.js'],

  onShellReady() {

    response.statusCode = didError ? 500 : 200;

    response.setHeader('content-type', 'text/html');

    pipe(response);

  },

  onShellError(error) {

    response.statusCode = 500;

    response.setHeader('content-type', 'text/html');

    response.send('<h1>Something went wrong</h1>');

  },

  onError(error) {

    didError = true;

    console.error(error);

    logServerCrashReport(error);

  }

});
```

This will only catch errors outside the shell that happened while generating the initial shell content, so it’s not exhaustive. If knowing whether an error occurred for some content is critical, you can move it up into the shell.

***

### Handling different errors in different ways[](#handling-different-errors-in-different-ways "Link for Handling different errors in different ways ")

You can [create your own `Error` subclasses](https://javascript.info/custom-errors) and use the [`instanceof`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/instanceof) operator to check which error is thrown. For example, you can define a custom `NotFoundError` and throw it from your component. Then your `onError`, `onShellReady`, and `onShellError` callbacks can do something different depending on the error type:

```
let didError = false;

let caughtError = null;



function getStatusCode() {

  if (didError) {

    if (caughtError instanceof NotFoundError) {

      return 404;

    } else {

      return 500;

    }

  } else {

    return 200;

  }

}



const { pipe } = renderToPipeableStream(<App />, {

  bootstrapScripts: ['/main.js'],

  onShellReady() {

    response.statusCode = getStatusCode();

    response.setHeader('content-type', 'text/html');

    pipe(response);

  },

  onShellError(error) {

   response.statusCode = getStatusCode();

   response.setHeader('content-type', 'text/html');

   response.send('<h1>Something went wrong</h1>');

  },

  onError(error) {

    didError = true;

    caughtError = error;

    console.error(error);

    logServerCrashReport(error);

  }

});
```

Keep in mind that once you emit the shell and start streaming, you can’t change the status code.

***

### Waiting for all content to load for crawlers and static generation[](#waiting-for-all-content-to-load-for-crawlers-and-static-generation "Link for Waiting for all content to load for crawlers and static generation ")

Streaming offers a better user experience because the user can see the content as it becomes available.

However, when a crawler visits your page, or if you’re generating the pages at the build time, you might want to let all of the content load first and then produce the final HTML output instead of revealing it progressively.

You can wait for all the content to load using the `onAllReady` callback:

```
let didError = false;

let isCrawler = // ... depends on your bot detection strategy ...



const { pipe } = renderToPipeableStream(<App />, {

  bootstrapScripts: ['/main.js'],

  onShellReady() {

    if (!isCrawler) {

      response.statusCode = didError ? 500 : 200;

      response.setHeader('content-type', 'text/html');

      pipe(response);

    }

  },

  onShellError(error) {

    response.statusCode = 500;

    response.setHeader('content-type', 'text/html');

    response.send('<h1>Something went wrong</h1>');

  },

  onAllReady() {

    if (isCrawler) {

      response.statusCode = didError ? 500 : 200;

      response.setHeader('content-type', 'text/html');

      pipe(response);

    }

  },

  onError(error) {

    didError = true;

    console.error(error);

    logServerCrashReport(error);

  }

});
```

A regular visitor will get a stream of progressively loaded content. A crawler will receive the final HTML output after all the data loads. However, this also means that the crawler will have to wait for *all* data, some of which might be slow to load or error. Depending on your app, you could choose to send the shell to the crawlers too.

***

### Aborting server rendering[](#aborting-server-rendering "Link for Aborting server rendering ")

You can force the server rendering to “give up” after a timeout:

```
const { pipe, abort } = renderToPipeableStream(<App />, {

  // ...

});



setTimeout(() => {

  abort();

}, 10000);
```

React will flush the remaining loading fallbacks as HTML, and will attempt to render the rest on the client.

[PreviousServer APIs](/reference/react-dom/server)

[NextrenderToReadableStream](/reference/react-dom/server/renderToReadableStream)

***

----
url: https://18.react.dev/reference/react-dom/components/common
----

***

## Reference[](#reference "Link for Reference ")

### Common components (e.g. `<div>`)[](#common "Link for this heading")

```
<div className="wrapper">Some content</div>
```

***

### `ref` callback function[](#ref-callback "Link for this heading")

Instead of a ref object (like the one returned by [`useRef`](/reference/react/useRef#manipulating-the-dom-with-a-ref)), you may pass a function to the `ref` attribute.

```
<div ref={(node) => console.log(node)} />
```

[See an example of using the `ref` callback.](/learn/manipulating-the-dom-with-refs#how-to-manage-a-list-of-refs-using-a-ref-callback)

When the `<div>` DOM node is added to the screen, React will call your `ref` callback with the DOM `node` as the argument. When that `<div>` DOM node is removed, React will call your `ref` callback with `null`.

React will also call your `ref` callback whenever you pass a *different* `ref` callback. In the above example, `(node) => { ... }` is a different function on every render. When your component re-renders, the *previous* function will be called with `null` as the argument, and the *next* function will be called with the DOM node.

#### Parameters[](#ref-callback-parameters "Link for Parameters ")

* `node`: A DOM node or `null`. React will pass you the DOM node when the ref gets attached, and `null` when the `ref` gets detached. Unless you pass the same function reference for the `ref` callback on every render, the callback will get temporarily detached and re-attached during every re-render of the component.

### Canary

#### Returns[](#returns "Link for Returns ")

* **optional** `cleanup function`: When the `ref` is detached, React will call the cleanup function. If a function is not returned by the `ref` callback, React will call the callback again with `null` as the argument when the `ref` gets detached.

```


<div ref={(node) => {

  console.log(node);



  return () => {

    console.log('Clean up', node)

  }

}}>
```

#### Caveats[](#caveats "Link for Caveats ")

* When Strict Mode is on, React will **run one extra development-only setup+cleanup cycle** before the first real setup. This is a stress-test that ensures that your cleanup logic “mirrors” your setup logic and that it stops or undoes whatever the setup is doing. If this causes a problem, implement the cleanup function.
* When you pass a *different* `ref` callback, React will call the *previous* callback’s cleanup function if provided. If not cleanup function is defined, the `ref` callback will be called with `null` as the argument. The *next* function will be called with the DOM node.

***

### React event object[](#react-event-object "Link for React event object ")

Your event handlers will receive a *React event object.* It is also sometimes known as a “synthetic event”.

```
<button onClick={e => {

  console.log(e); // React event object

}} />
```

***

### `AnimationEvent` handler function[](#animationevent-handler "Link for this heading")

An event handler type for the [CSS animation](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Animations/Using_CSS_animations) events.

```
<div

  onAnimationStart={e => console.log('onAnimationStart')}

  onAnimationIteration={e => console.log('onAnimationIteration')}

  onAnimationEnd={e => console.log('onAnimationEnd')}

/>
```

#### Parameters[](#animationevent-handler-parameters "Link for Parameters ")

* `e`: A [React event object](#react-event-object) with these extra [`AnimationEvent`](https://developer.mozilla.org/en-US/docs/Web/API/AnimationEvent) properties:

  * [`animationName`](https://developer.mozilla.org/en-US/docs/Web/API/AnimationEvent/animationName)
  * [`elapsedTime`](https://developer.mozilla.org/en-US/docs/Web/API/AnimationEvent/elapsedTime)
  * [`pseudoElement`](https://developer.mozilla.org/en-US/docs/Web/API/AnimationEvent/pseudoElement)

***

### `ClipboardEvent` handler function[](#clipboadevent-handler "Link for this heading")

An event handler type for the [Clipboard API](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard_API) events.

```
<input

  onCopy={e => console.log('onCopy')}

  onCut={e => console.log('onCut')}

  onPaste={e => console.log('onPaste')}

/>
```

#### Parameters[](#clipboadevent-handler-parameters "Link for Parameters ")

* `e`: A [React event object](#react-event-object) with these extra [`ClipboardEvent`](https://developer.mozilla.org/en-US/docs/Web/API/ClipboardEvent) properties:

  * [`clipboardData`](https://developer.mozilla.org/en-US/docs/Web/API/ClipboardEvent/clipboardData)

***

### `CompositionEvent` handler function[](#compositionevent-handler "Link for this heading")

An event handler type for the [input method editor (IME)](https://developer.mozilla.org/en-US/docs/Glossary/Input_method_editor) events.

```
<input

  onCompositionStart={e => console.log('onCompositionStart')}

  onCompositionUpdate={e => console.log('onCompositionUpdate')}

  onCompositionEnd={e => console.log('onCompositionEnd')}

/>
```

#### Parameters[](#compositionevent-handler-parameters "Link for Parameters ")

* `e`: A [React event object](#react-event-object) with these extra [`CompositionEvent`](https://developer.mozilla.org/en-US/docs/Web/API/CompositionEvent) properties:
  * [`data`](https://developer.mozilla.org/en-US/docs/Web/API/CompositionEvent/data)

***

### `DragEvent` handler function[](#dragevent-handler "Link for this heading")

An event handler type for the [HTML Drag and Drop API](https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API) events.

```
<>

  <div

    draggable={true}

    onDragStart={e => console.log('onDragStart')}

    onDragEnd={e => console.log('onDragEnd')}

  >

    Drag source

  </div>



  <div

    onDragEnter={e => console.log('onDragEnter')}

    onDragLeave={e => console.log('onDragLeave')}

    onDragOver={e => { e.preventDefault(); console.log('onDragOver'); }}

    onDrop={e => console.log('onDrop')}

  >

    Drop target

  </div>

</>
```

***

### `FocusEvent` handler function[](#focusevent-handler "Link for this heading")

An event handler type for the focus events.

```
<input

  onFocus={e => console.log('onFocus')}

  onBlur={e => console.log('onBlur')}

/>
```

***

### `Event` handler function[](#event-handler "Link for this heading")

An event handler type for generic events.

#### Parameters[](#event-handler-parameters "Link for Parameters ")

* `e`: A [React event object](#react-event-object) with no additional properties.

***

### `InputEvent` handler function[](#inputevent-handler "Link for this heading")

An event handler type for the `onBeforeInput` event.

```
<input onBeforeInput={e => console.log('onBeforeInput')} />
```

#### Parameters[](#inputevent-handler-parameters "Link for Parameters ")

* `e`: A [React event object](#react-event-object) with these extra [`InputEvent`](https://developer.mozilla.org/en-US/docs/Web/API/InputEvent) properties:
  * [`data`](https://developer.mozilla.org/en-US/docs/Web/API/InputEvent/data)

***

### `KeyboardEvent` handler function[](#keyboardevent-handler "Link for this heading")

An event handler type for keyboard events.

```
<input

  onKeyDown={e => console.log('onKeyDown')}

  onKeyUp={e => console.log('onKeyUp')}

/>
```

***

### `MouseEvent` handler function[](#mouseevent-handler "Link for this heading")

An event handler type for mouse events.

```
<div

  onClick={e => console.log('onClick')}

  onMouseEnter={e => console.log('onMouseEnter')}

  onMouseOver={e => console.log('onMouseOver')}

  onMouseDown={e => console.log('onMouseDown')}

  onMouseUp={e => console.log('onMouseUp')}

  onMouseLeave={e => console.log('onMouseLeave')}

/>
```

***

### `PointerEvent` handler function[](#pointerevent-handler "Link for this heading")

An event handler type for [pointer events.](https://developer.mozilla.org/en-US/docs/Web/API/Pointer_events)

```
<div

  onPointerEnter={e => console.log('onPointerEnter')}

  onPointerMove={e => console.log('onPointerMove')}

  onPointerDown={e => console.log('onPointerDown')}

  onPointerUp={e => console.log('onPointerUp')}

  onPointerLeave={e => console.log('onPointerLeave')}

/>
```

***

### `TouchEvent` handler function[](#touchevent-handler "Link for this heading")

An event handler type for [touch events.](https://developer.mozilla.org/en-US/docs/Web/API/Touch_events)

```
<div

  onTouchStart={e => console.log('onTouchStart')}

  onTouchMove={e => console.log('onTouchMove')}

  onTouchEnd={e => console.log('onTouchEnd')}

  onTouchCancel={e => console.log('onTouchCancel')}

/>
```

***

### `TransitionEvent` handler function[](#transitionevent-handler "Link for this heading")

An event handler type for the CSS transition events.

```
<div

  onTransitionEnd={e => console.log('onTransitionEnd')}

/>
```

#### Parameters[](#transitionevent-handler-parameters "Link for Parameters ")

* `e`: A [React event object](#react-event-object) with these extra [`TransitionEvent`](https://developer.mozilla.org/en-US/docs/Web/API/TransitionEvent) properties:

  * [`elapsedTime`](https://developer.mozilla.org/en-US/docs/Web/API/TransitionEvent/elapsedTime)
  * [`propertyName`](https://developer.mozilla.org/en-US/docs/Web/API/TransitionEvent/propertyName)
  * [`pseudoElement`](https://developer.mozilla.org/en-US/docs/Web/API/TransitionEvent/pseudoElement)

***

### `UIEvent` handler function[](#uievent-handler "Link for this heading")

An event handler type for generic UI events.

```
<div

  onScroll={e => console.log('onScroll')}

/>
```

#### Parameters[](#uievent-handler-parameters "Link for Parameters ")

* `e`: A [React event object](#react-event-object) with these extra [`UIEvent`](https://developer.mozilla.org/en-US/docs/Web/API/UIEvent) properties:

  * [`detail`](https://developer.mozilla.org/en-US/docs/Web/API/UIEvent/detail)
  * [`view`](https://developer.mozilla.org/en-US/docs/Web/API/UIEvent/view)

***

### `WheelEvent` handler function[](#wheelevent-handler "Link for this heading")

An event handler type for the `onWheel` event.

```
<div

  onWheel={e => console.log('onWheel')}

/>
```

***

## Usage[](#usage "Link for Usage ")

### Applying CSS styles[](#applying-css-styles "Link for Applying CSS styles ")

In React, you specify a CSS class with [`className`.](https://developer.mozilla.org/en-US/docs/Web/API/Element/className) It works like the `class` attribute in HTML:

```
<img className="avatar" />
```

Then you write the CSS rules for it in a separate CSS file:

```
/* In your CSS */

.avatar {

  border-radius: 50%;

}
```

React does not prescribe how you add CSS files. In the simplest case, you’ll add a [`<link>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link) tag to your HTML. If you use a build tool or a framework, consult its documentation to learn how to add a CSS file to your project.

Sometimes, the style values depend on data. Use the `style` attribute to pass some styles dynamically:

```
<img

  className="avatar"

  style={{

    width: user.imageSize,

    height: user.imageSize

  }}

/>
```

In the above example, `style={{}}` is not a special syntax, but a regular `{}` object inside the `style={ }` [JSX curly braces.](/learn/javascript-in-jsx-with-curly-braces) We recommend only using the `style` attribute when your styles depend on JavaScript variables.

```
export default function Avatar({ user }) {
  return (
    <img
      src={user.imageUrl}
      alt={'Photo of ' + user.name}
      className="avatar"
      style={{
        width: user.imageSize,
        height: user.imageSize
      }}
    />
  );
}
```

##### Deep Dive#### How to apply multiple CSS classes conditionally?[](#how-to-apply-multiple-css-classes-conditionally "Link for How to apply multiple CSS classes conditionally? ")

To apply CSS classes conditionally, you need to produce the `className` string yourself using JavaScript.

For example, `className={'row ' + (isSelected ? 'selected': '')}` will produce either `className="row"` or `className="row selected"` depending on whether `isSelected` is `true`.

To make this more readable, you can use a tiny helper library like [`classnames`:](https://github.com/JedWatson/classnames)

```
import cn from 'classnames';



function Row({ isSelected }) {

  return (

    <div className={cn('row', isSelected && 'selected')}>

      ...

    </div>

  );

}
```

It is especially convenient if you have multiple conditional classes:

```
import cn from 'classnames';



function Row({ isSelected, size }) {

  return (

    <div className={cn('row', {

      selected: isSelected,

      large: size === 'large',

      small: size === 'small',

    })}>

      ...

    </div>

  );

}
```

***

### Manipulating a DOM node with a ref[](#manipulating-a-dom-node-with-a-ref "Link for Manipulating a DOM node with a ref ")

Sometimes, you’ll need to get the browser DOM node associated with a tag in JSX. For example, if you want to focus an `<input>` when a button is clicked, you need to call [`focus()`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus) on the browser `<input>` DOM node.

To obtain the browser DOM node for a tag, [declare a ref](/reference/react/useRef) and pass it as the `ref` attribute to that tag:

```
import { useRef } from 'react';



export default function Form() {

  const inputRef = useRef(null);

  // ...

  return (

    <input ref={inputRef} />

    // ...
```

React will put the DOM node into `inputRef.current` after it’s been rendered to the screen.

```
import { useRef } from 'react';

export default function Form() {
  const inputRef = useRef(null);

  function handleClick() {
    inputRef.current.focus();
  }

  return (
    <>
      <input ref={inputRef} />
      <button onClick={handleClick}>
        Focus the input
      </button>
    </>
  );
}
```

Read more about [manipulating DOM with refs](/learn/manipulating-the-dom-with-refs) and [check out more examples.](/reference/react/useRef#examples-dom)

For more advanced use cases, the `ref` attribute also accepts a [callback function.](#ref-callback)

***

### Dangerously setting the inner HTML[](#dangerously-setting-the-inner-html "Link for Dangerously setting the inner HTML ")

You can pass a raw HTML string to an element like so:

```
const markup = { __html: '<p>some raw html</p>' };

return <div dangerouslySetInnerHTML={markup} />;
```

**This is dangerous. As with the underlying DOM [`innerHTML`](https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML) property, you must exercise extreme caution! Unless the markup is coming from a completely trusted source, it is trivial to introduce an [XSS](https://en.wikipedia.org/wiki/Cross-site_scripting) vulnerability this way.**

For example, if you use a Markdown library that converts Markdown to HTML, you trust that its parser doesn’t contain bugs, and the user only sees their own input, you can display the resulting HTML like this:

```
import { Remarkable } from 'remarkable';

const md = new Remarkable();

function renderMarkdownToHTML(markdown) {
  // This is ONLY safe because the output HTML
  // is shown to the same user, and because you
  // trust this Markdown parser to not have bugs.
  const renderedHTML = md.render(markdown);
  return {__html: renderedHTML};
}

export default function MarkdownPreview({ markdown }) {
  const markup = renderMarkdownToHTML(markdown);
  return <div dangerouslySetInnerHTML={markup} />;
}
```

The `{__html}` object should be created as close to where the HTML is generated as possible, like the above example does in the `renderMarkdownToHTML` function. This ensures that all raw HTML being used in your code is explicitly marked as such, and that only variables that you expect to contain HTML are passed to `dangerouslySetInnerHTML`. It is not recommended to create the object inline like `<div dangerouslySetInnerHTML={{__html: markup}} />`.

To see why rendering arbitrary HTML is dangerous, replace the code above with this:

```
const post = {

  // Imagine this content is stored in the database.

  content: `<img src="" onerror='alert("you were hacked")'>`

};



export default function MarkdownPreview() {

  // 🔴 SECURITY HOLE: passing untrusted input to dangerouslySetInnerHTML

  const markup = { __html: post.content };

  return <div dangerouslySetInnerHTML={markup} />;

}
```

The code embedded in the HTML will run. A hacker could use this security hole to steal user information or to perform actions on their behalf. **Only use `dangerouslySetInnerHTML` with trusted and sanitized data.**

***

### Handling mouse events[](#handling-mouse-events "Link for Handling mouse events ")

This example shows some common [mouse events](#mouseevent-handler) and when they fire.

```
export default function MouseExample() {
  return (
    <div
      onMouseEnter={e => console.log('onMouseEnter (parent)')}
      onMouseLeave={e => console.log('onMouseLeave (parent)')}
    >
      <button
        onClick={e => console.log('onClick (first button)')}
        onMouseDown={e => console.log('onMouseDown (first button)')}
        onMouseEnter={e => console.log('onMouseEnter (first button)')}
        onMouseLeave={e => console.log('onMouseLeave (first button)')}
        onMouseOver={e => console.log('onMouseOver (first button)')}
        onMouseUp={e => console.log('onMouseUp (first button)')}
      >
        First button
      </button>
      <button
        onClick={e => console.log('onClick (second button)')}
        onMouseDown={e => console.log('onMouseDown (second button)')}
        onMouseEnter={e => console.log('onMouseEnter (second button)')}
        onMouseLeave={e => console.log('onMouseLeave (second button)')}
        onMouseOver={e => console.log('onMouseOver (second button)')}
        onMouseUp={e => console.log('onMouseUp (second button)')}
      >
        Second button
      </button>
    </div>
  );
}
```

***

### Handling pointer events[](#handling-pointer-events "Link for Handling pointer events ")

This example shows some common [pointer events](#pointerevent-handler) and when they fire.

```
export default function PointerExample() {
  return (
    <div
      onPointerEnter={e => console.log('onPointerEnter (parent)')}
      onPointerLeave={e => console.log('onPointerLeave (parent)')}
      style={{ padding: 20, backgroundColor: '#ddd' }}
    >
      <div
        onPointerDown={e => console.log('onPointerDown (first child)')}
        onPointerEnter={e => console.log('onPointerEnter (first child)')}
        onPointerLeave={e => console.log('onPointerLeave (first child)')}
        onPointerMove={e => console.log('onPointerMove (first child)')}
        onPointerUp={e => console.log('onPointerUp (first child)')}
        style={{ padding: 20, backgroundColor: 'lightyellow' }}
      >
        First child
      </div>
      <div
        onPointerDown={e => console.log('onPointerDown (second child)')}
        onPointerEnter={e => console.log('onPointerEnter (second child)')}
        onPointerLeave={e => console.log('onPointerLeave (second child)')}
        onPointerMove={e => console.log('onPointerMove (second child)')}
        onPointerUp={e => console.log('onPointerUp (second child)')}
        style={{ padding: 20, backgroundColor: 'lightblue' }}
      >
        Second child
      </div>
    </div>
  );
}
```

***

### Handling focus events[](#handling-focus-events "Link for Handling focus events ")

In React, [focus events](#focusevent-handler) bubble. You can use the `currentTarget` and `relatedTarget` to differentiate if the focusing or blurring events originated from outside of the parent element. The example shows how to detect focusing a child, focusing the parent element, and how to detect focus entering or leaving the whole subtree.

```
export default function FocusExample() {
  return (
    <div
      tabIndex={1}
      onFocus={(e) => {
        if (e.currentTarget === e.target) {
          console.log('focused parent');
        } else {
          console.log('focused child', e.target.name);
        }
        if (!e.currentTarget.contains(e.relatedTarget)) {
          // Not triggered when swapping focus between children
          console.log('focus entered parent');
        }
      }}
      onBlur={(e) => {
        if (e.currentTarget === e.target) {
          console.log('unfocused parent');
        } else {
          console.log('unfocused child', e.target.name);
        }
        if (!e.currentTarget.contains(e.relatedTarget)) {
          // Not triggered when swapping focus between children
          console.log('focus left parent');
        }
      }}
    >
      <label>
        First name:
        <input name="firstName" />
      </label>
      <label>
        Last name:
        <input name="lastName" />
      </label>
    </div>
  );
}
```

***

### Handling keyboard events[](#handling-keyboard-events "Link for Handling keyboard events ")

This example shows some common [keyboard events](#keyboardevent-handler) and when they fire.

```
export default function KeyboardExample() {
  return (
    <label>
      First name:
      <input
        name="firstName"
        onKeyDown={e => console.log('onKeyDown:', e.key, e.code)}
        onKeyUp={e => console.log('onKeyUp:', e.key, e.code)}
      />
    </label>
  );
}
```

[PreviousComponents](/reference/react-dom/components)

[Next\<form>](/reference/react-dom/components/form)

***

----
url: https://react.dev/blog/2024/05/22/react-conf-2024-recap
----

[Blog](/blog)

# React Conf 2024 Recap[](#undefined "Link for this heading")

May 22, 2024 by [Ricky Hanlon](https://twitter.com/rickhanlonii).

***

Last week we hosted React Conf 2024, a two-day conference in Henderson, Nevada where 700+ attendees gathered in-person to discuss the latest in UI engineering. This was our first in-person conference since 2019, and we were thrilled to be able to bring the community together again.

***

At React Conf 2024, we announced the [React 19 RC](/blog/2024/12/05/react-19), the [React Native New Architecture Beta](https://github.com/reactwg/react-native-new-architecture/discussions/189), and an experimental release of the [React Compiler](/learn/react-compiler). The community also took the stage to announce [React Router v7](https://remix.run/blog/merging-remix-and-react-router), [Universal Server Components](https://www.youtube.com/watch?v=T8TZQ6k4SLE\&t=20765s) in Expo Router, React Server Components in [RedwoodJS](https://redwoodjs.com/blog/rsc-now-in-redwoodjs), and much more.

The entire [day 1](https://www.youtube.com/watch?v=T8TZQ6k4SLE) and [day 2](https://www.youtube.com/watch?v=0ckOUBiuxVY) streams are available online. In this post, we’ll summarize the talks and announcements from the event.

## Day 1[](#day-1 "Link for Day 1 ")

*[Watch the full day 1 stream here.](https://www.youtube.com/watch?v=T8TZQ6k4SLE\&t=973s)*

To kick off day 1, Meta CTO [Andrew “Boz” Bosworth](https://www.threads.net/@boztank) shared a welcome message followed by an introduction by [Seth Webster](https://twitter.com/sethwebster), who manages the React Org at Meta, and our MC [Ashley Narcisse](https://twitter.com/_darkfadr).

In the day 1 keynote, [Joe Savona](https://twitter.com/en_JS) shared our goals and vision for React to make it easy for anyone to build great user experiences. [Lauren Tan](https://twitter.com/potetotes) followed with a State of React, where she shared that React was downloaded over 1 billion times in 2023, and that 37% of new developers learn to program with React. Finally, she highlighted the work of the React community to make React, React.

For more, check out these talks from the community later in the conference:

* [Vanilla React](https://www.youtube.com/watch?v=T8TZQ6k4SLE\&t=5542s) by [Ryan Florence](https://twitter.com/ryanflorence)
* [React Rhythm & Blues](https://www.youtube.com/watch?v=0ckOUBiuxVY\&t=12728s) by [Lee Robinson](https://twitter.com/leeerob)
* [RedwoodJS, now with React Server Components](https://www.youtube.com/watch?v=T8TZQ6k4SLE\&t=26815s) by [Amy Dutton](https://twitter.com/selfteachme)
* [Introducing Universal React Server Components in Expo Router](https://www.youtube.com/watch?v=T8TZQ6k4SLE\&t=20765s) by [Evan Bacon](https://twitter.com/Baconbrix)

Next in the keynote, [Josh Story](https://twitter.com/joshcstory) and [Andrew Clark](https://twitter.com/acdlite) shared new features coming in React 19, and announced the React 19 RC which is ready for testing in production. Check out all the features in the [React 19 release post](/blog/2024/12/05/react-19), and see these talks for deep dives on the new features:

* [What’s new in React 19](https://www.youtube.com/watch?v=T8TZQ6k4SLE\&t=8880s) by [Lydia Hallie](https://twitter.com/lydiahallie)
* [React Unpacked: A Roadmap to React 19](https://www.youtube.com/watch?v=T8TZQ6k4SLE\&t=10112s) by [Sam Selikoff](https://twitter.com/samselikoff)
* [React 19 Deep Dive: Coordinating HTML](https://www.youtube.com/watch?v=T8TZQ6k4SLE\&t=24916s) by [Josh Story](https://twitter.com/joshcstory)
* [Enhancing Forms with React Server Components](https://www.youtube.com/watch?v=0ckOUBiuxVY\&t=25280s) by [Aurora Walberg Scharff](https://twitter.com/aurorascharff)
* [React for Two Computers](https://www.youtube.com/watch?v=T8TZQ6k4SLE\&t=18825s) by [Dan Abramov](https://bsky.app/profile/danabra.mov)
* [And Now You Understand React Server Components](https://www.youtube.com/watch?v=0ckOUBiuxVY\&t=11256s) by [Kent C. Dodds](https://twitter.com/kentcdodds)

Finally, we ended the keynote with [Joe Savona](https://twitter.com/en_JS), [Sathya Gunasekaran](https://twitter.com/_gsathya), and [Mofei Zhang](https://twitter.com/zmofei) announcing that the React Compiler is now [Open Source](https://github.com/facebook/react/pull/29061), and sharing an experimental version of the React Compiler to try out.

For more information on using the Compiler and how it works, check out [the docs](/learn/react-compiler) and these talks:

* [Forget About Memo](https://www.youtube.com/watch?v=T8TZQ6k4SLE\&t=12020s) by [Lauren Tan](https://twitter.com/potetotes)
* [React Compiler Deep Dive](https://www.youtube.com/watch?v=0ckOUBiuxVY\&t=9313s) by [Sathya Gunasekaran](https://twitter.com/_gsathya) and [Mofei Zhang](https://twitter.com/zmofei)

Watch the full day 1 keynote here:

## Day 2[](#day-2 "Link for Day 2 ")

*[Watch the full day 2 stream here.](https://www.youtube.com/watch?v=0ckOUBiuxVY\&t=1720s)*

To kick off day 2, [Seth Webster](https://twitter.com/sethwebster) shared a welcome message, followed by a Thank You from [Eli White](https://x.com/Eli_White) and an introduction by our Chief Vibes Officer [Ashley Narcisse](https://twitter.com/_darkfadr).

In the day 2 keynote, [Nicola Corti](https://twitter.com/cortinico) shared the State of React Native, including 78 million downloads in 2023. He also highlighted apps using React Native including 2000+ screens used inside of Meta; the product details page in Facebook Marketplace, which is visited more than 2 billion times per day; and part of the Microsoft Windows Start Menu and some features in almost every Microsoft Office product across mobile and desktop.

Nicola also highlighted all the work the community does to support React Native including libraries, frameworks, and multiple platforms. For more, check out these talks from the community:

* [Extending React Native beyond Mobile and Desktop Apps](https://www.youtube.com/watch?v=0ckOUBiuxVY\&t=5798s) by [Chris Traganos](https://twitter.com/chris_trag) and [Anisha Malde](https://twitter.com/anisha_malde)
* [Spatial computing with React](https://www.youtube.com/watch?v=0ckOUBiuxVY\&t=22525s) by [Michał Pierzchała](https://twitter.com/thymikee)

[Riccardo Cipolleschi](https://twitter.com/cipolleschir) continued the day 2 keynote by announcing that the React Native New Architecture is now in Beta and ready for apps to adopt in production. He shared new features and improvements in the new architecture, and shared the roadmap for the future of React Native. For more check out:

* [Cross Platform React](https://www.youtube.com/watch?v=0ckOUBiuxVY\&t=26569s) by [Olga Zinoveva](https://github.com/SlyCaptainFlint) and [Naman Goel](https://twitter.com/naman34)

Next in the keynote, Nicola announced that we are now recommending starting with a framework like Expo for all new apps created with React Native. With the change, he also announced a new React Native homepage and new Getting Started docs. You can view the new Getting Started guide in the [React Native docs](https://reactnative.dev/docs/next/environment-setup).

Finally, to end the keynote, [Kadi Kraman](https://twitter.com/kadikraman) shared the latest features and improvements in Expo, and how to get started developing with React Native using Expo.

Watch the full day 2 keynote here:

## Q\&A[](#q-and-a "Link for Q\&A ")

The React and React Native teams also ended each day with a Q\&A session:

* [React Q\&A](https://www.youtube.com/watch?v=T8TZQ6k4SLE\&t=27518s) hosted by [Michael Chan](https://twitter.com/chantastic)
* [React Native Q\&A](https://www.youtube.com/watch?v=0ckOUBiuxVY\&t=27935s) hosted by [Jamon Holmgren](https://twitter.com/jamonholmgren)

## And more…[](#and-more "Link for And more… ")

We also heard talks on accessibility, error reporting, css, and more:

* [Demystifying accessibility in React apps](https://www.youtube.com/watch?v=0ckOUBiuxVY\&t=20655s) by [Kateryna Porshnieva](https://twitter.com/krambertech)
* [Pigment CSS, CSS in the server component age](https://www.youtube.com/watch?v=0ckOUBiuxVY\&t=21696s) by [Olivier Tassinari](https://twitter.com/olivtassinari)
* [Real-time React Server Components](https://www.youtube.com/watch?v=T8TZQ6k4SLE\&t=24070s) by [Sunil Pai](https://twitter.com/threepointone)
* [Let’s break React Rules](https://www.youtube.com/watch?v=T8TZQ6k4SLE\&t=25862s) by [Charlotte Isambert](https://twitter.com/c_isambert)
* [Solve 100% of your errors](https://www.youtube.com/watch?v=0ckOUBiuxVY\&t=19881s) by [Ryan Albrecht](https://github.com/ryan953)

## Thank you[](#thank-you "Link for Thank you ")

Thank you to all the staff, speakers, and participants who made React Conf 2024 possible. There are too many to list, but we want to thank a few in particular.

Thank you to [Barbara Markiewicz](https://twitter.com/barbara_markie), the team at [Callstack](https://www.callstack.com/), and our React Team Developer Advocate [Matt Carroll](https://twitter.com/mattcarrollcode) for helping to plan the entire event; and to [Sunny Leggett](https://zeroslopeevents.com/about) and everyone from [Zero Slope](https://zeroslopeevents.com) for helping to organize the event.

Thank you [Ashley Narcisse](https://twitter.com/_darkfadr) for being our MC and Chief Vibes Officer; and to [Michael Chan](https://twitter.com/chantastic) and [Jamon Holmgren](https://twitter.com/jamonholmgren) for hosting the Q\&A sessions.

Thank you [Seth Webster](https://twitter.com/sethwebster) and [Eli White](https://x.com/Eli_White) for welcoming us each day and providing direction on structure and content; and to [Tom Occhino](https://twitter.com/tomocchino) for joining us with a special message during the after-party.

Thank you [Ricky Hanlon](https://www.youtube.com/watch?v=FxTZL2U-uKg\&t=1263s) for providing detailed feedback on talks, working on slide designs, and generally filling in the gaps to sweat the details.

Thank you [Callstack](https://www.callstack.com/) for building the conference website; and to [Kadi Kraman](https://twitter.com/kadikraman) and the [Expo](https://expo.dev/) team for building the conference mobile app.

Thank you to all the sponsors who made the event possible: [Remix](https://remix.run/), [Amazon](https://developer.amazon.com/apps-and-games?cmp=US_2024_05_3P_React-Conf-2024\&ch=prtnr\&chlast=prtnr\&pub=ref\&publast=ref\&type=org\&typelast=org), [MUI](https://mui.com/), [Sentry](https://sentry.io/for/react/?utm_source=sponsored-conf\&utm_medium=sponsored-event\&utm_campaign=frontend-fy25q2-evergreen\&utm_content=logo-reactconf2024-learnmore), [Abbott](https://www.jobs.abbott/software), [Expo](https://expo.dev/), [RedwoodJS](https://rwsdk.com/), and [Vercel](https://vercel.com).

Thank you to the AV Team for the visuals, stage, and sound; and to the Westin Hotel for hosting us.

Thank you to all the speakers who shared their knowledge and experiences with the community.

Finally, thank you to everyone who attended in person and online to show what makes React, React. React is more than a library, it is a community, and it was inspiring to see everyone come together to share and learn together.

See you next time!

[PreviousReact Compiler Beta Release and Roadmap](/blog/2024/10/21/react-compiler-beta-release)

[NextReact 19 RC](/blog/2024/04/25/react-19)

***

----
url: https://18.react.dev/reference/react/useContext
----

[API Reference](/reference/react)

[Hooks](/reference/react/hooks)

# useContext[](#undefined "Link for this heading")

`useContext` is a React Hook that lets you read and subscribe to [context](/learn/passing-data-deeply-with-context) from your component.

```
const value = useContext(SomeContext)
```

***

## Reference[](#reference "Link for Reference ")

### `useContext(SomeContext)`[](#usecontext "Link for this heading")

Call `useContext` at the top level of your component to read and subscribe to [context.](/learn/passing-data-deeply-with-context)

```
import { useContext } from 'react';



function MyComponent() {

  const theme = useContext(ThemeContext);

  // ...
```

[See more examples below.](#usage)

#### Parameters[](#parameters "Link for Parameters ")

* `SomeContext`: The context that you’ve previously created with [`createContext`](/reference/react/createContext). The context itself does not hold the information, it only represents the kind of information you can provide or read from components.

#### Returns[](#returns "Link for Returns ")

`useContext` returns the context value for the calling component. It is determined as the `value` passed to the closest `SomeContext.Provider` above the calling component in the tree. If there is no such provider, then the returned value will be the `defaultValue` you have passed to [`createContext`](/reference/react/createContext) for that context. The returned value is always up-to-date. React automatically re-renders components that read some context if it changes.

#### Caveats[](#caveats "Link for Caveats ")

* `useContext()` call in a component is not affected by providers returned from the *same* component. The corresponding `<Context.Provider>` **needs to be *above*** the component doing the `useContext()` call.
* React **automatically re-renders** all the children that use a particular context starting from the provider that receives a different `value`. The previous and the next values are compared with the [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) comparison. Skipping re-renders with [`memo`](/reference/react/memo) does not prevent the children receiving fresh context values.
* If your build system produces duplicates modules in the output (which can happen with symlinks), this can break context. Passing something via context only works if `SomeContext` that you use to provide context and `SomeContext` that you use to read it are ***exactly* the same object**, as determined by a `===` comparison.

***

## Usage[](#usage "Link for Usage ")

### Passing data deeply into the tree[](#passing-data-deeply-into-the-tree "Link for Passing data deeply into the tree ")

Call `useContext` at the top level of your component to read and subscribe to [context.](/learn/passing-data-deeply-with-context)

```
import { useContext } from 'react';



function Button() {

  const theme = useContext(ThemeContext);

  // ...
```

`useContext` returns the context value for the context you passed. To determine the context value, React searches the component tree and finds **the closest context provider above** for that particular context.

To pass context to a `Button`, wrap it or one of its parent components into the corresponding context provider:

```
function MyPage() {

  return (

    <ThemeContext.Provider value="dark">

      <Form />

    </ThemeContext.Provider>

  );

}



function Form() {

  // ... renders buttons inside ...

}
```

It doesn’t matter how many layers of components there are between the provider and the `Button`. When a `Button` *anywhere* inside of `Form` calls `useContext(ThemeContext)`, it will receive `"dark"` as the value.

### Pitfall

`useContext()` always looks for the closest provider *above* the component that calls it. It searches upwards and **does not** consider providers in the component from which you’re calling `useContext()`.

```
import { createContext, useContext } from 'react';

const ThemeContext = createContext(null);

export default function MyApp() {
  return (
    <ThemeContext.Provider value="dark">
      <Form />
    </ThemeContext.Provider>
  )
}

function Form() {
  return (
    <Panel title="Welcome">
      <Button>Sign up</Button>
      <Button>Log in</Button>
    </Panel>
  );
}

function Panel({ title, children }) {
  const theme = useContext(ThemeContext);
  const className = 'panel-' + theme;
  return (
    <section className={className}>
      <h1>{title}</h1>
      {children}
    </section>
  )
}

function Button({ children }) {
  const theme = useContext(ThemeContext);
  const className = 'button-' + theme;
  return (
    <button className={className}>
      {children}
    </button>
  );
}
```

***

### Updating data passed via context[](#updating-data-passed-via-context "Link for Updating data passed via context ")

Often, you’ll want the context to change over time. To update context, combine it with [state.](/reference/react/useState) Declare a state variable in the parent component, and pass the current state down as the context value to the provider.

```
function MyPage() {

  const [theme, setTheme] = useState('dark');

  return (

    <ThemeContext.Provider value={theme}>

      <Form />

      <Button onClick={() => {

        setTheme('light');

      }}>

        Switch to light theme

      </Button>

    </ThemeContext.Provider>

  );

}
```

Now any `Button` inside of the provider will receive the current `theme` value. If you call `setTheme` to update the `theme` value that you pass to the provider, all `Button` components will re-render with the new `'light'` value.

#### Examples of updating context[](#examples-basic "Link for Examples of updating context")

#### Example 1 of 5:Updating a value via context[](#updating-a-value-via-context "Link for this heading")

In this example, the `MyApp` component holds a state variable which is then passed to the `ThemeContext` provider. Checking the “Dark mode” checkbox updates the state. Changing the provided value re-renders all the components using that context.

```
import { createContext, useContext, useState } from 'react';

const ThemeContext = createContext(null);

export default function MyApp() {
  const [theme, setTheme] = useState('light');
  return (
    <ThemeContext.Provider value={theme}>
      <Form />
      <label>
        <input
          type="checkbox"
          checked={theme === 'dark'}
          onChange={(e) => {
            setTheme(e.target.checked ? 'dark' : 'light')
          }}
        />
        Use dark mode
      </label>
    </ThemeContext.Provider>
  )
}

function Form({ children }) {
  return (
    <Panel title="Welcome">
      <Button>Sign up</Button>
      <Button>Log in</Button>
    </Panel>
  );
}

function Panel({ title, children }) {
  const theme = useContext(ThemeContext);
  const className = 'panel-' + theme;
  return (
    <section className={className}>
      <h1>{title}</h1>
      {children}
    </section>
  )
}

function Button({ children }) {
  const theme = useContext(ThemeContext);
  const className = 'button-' + theme;
  return (
    <button className={className}>
      {children}
    </button>
  );
}
```

Note that `value="dark"` passes the `"dark"` string, but `value={theme}` passes the value of the JavaScript `theme` variable with [JSX curly braces.](/learn/javascript-in-jsx-with-curly-braces) Curly braces also let you pass context values that aren’t strings.

***

### Specifying a fallback default value[](#specifying-a-fallback-default-value "Link for Specifying a fallback default value ")

If React can’t find any providers of that particular context in the parent tree, the context value returned by `useContext()` will be equal to the default value that you specified when you [created that context](/reference/react/createContext):

```
const ThemeContext = createContext(null);
```

The default value **never changes**. If you want to update context, use it with state as [described above.](#updating-data-passed-via-context)

Often, instead of `null`, there is some more meaningful value you can use as a default, for example:

```
const ThemeContext = createContext('light');
```

This way, if you accidentally render some component without a corresponding provider, it won’t break. This also helps your components work well in a test environment without setting up a lot of providers in the tests.

In the example below, the “Toggle theme” button is always light because it’s **outside any theme context provider** and the default context theme value is `'light'`. Try editing the default theme to be `'dark'`.

```
import { createContext, useContext, useState } from 'react';

const ThemeContext = createContext('light');

export default function MyApp() {
  const [theme, setTheme] = useState('light');
  return (
    <>
      <ThemeContext.Provider value={theme}>
        <Form />
      </ThemeContext.Provider>
      <Button onClick={() => {
        setTheme(theme === 'dark' ? 'light' : 'dark');
      }}>
        Toggle theme
      </Button>
    </>
  )
}

function Form({ children }) {
  return (
    <Panel title="Welcome">
      <Button>Sign up</Button>
      <Button>Log in</Button>
    </Panel>
  );
}

function Panel({ title, children }) {
  const theme = useContext(ThemeContext);
  const className = 'panel-' + theme;
  return (
    <section className={className}>
      <h1>{title}</h1>
      {children}
    </section>
  )
}

function Button({ children, onClick }) {
  const theme = useContext(ThemeContext);
  const className = 'button-' + theme;
  return (
    <button className={className} onClick={onClick}>
      {children}
    </button>
  );
}
```

***

### Overriding context for a part of the tree[](#overriding-context-for-a-part-of-the-tree "Link for Overriding context for a part of the tree ")

You can override the context for a part of the tree by wrapping that part in a provider with a different value.

```
<ThemeContext.Provider value="dark">

  ...

  <ThemeContext.Provider value="light">

    <Footer />

  </ThemeContext.Provider>

  ...

</ThemeContext.Provider>
```

You can nest and override providers as many times as you need.

#### Examples of overriding context[](#examples "Link for Examples of overriding context")

#### Example 1 of 2:Overriding a theme[](#overriding-a-theme "Link for this heading")

Here, the button *inside* the `Footer` receives a different context value (`"light"`) than the buttons outside (`"dark"`).

```
import { createContext, useContext } from 'react';

const ThemeContext = createContext(null);

export default function MyApp() {
  return (
    <ThemeContext.Provider value="dark">
      <Form />
    </ThemeContext.Provider>
  )
}

function Form() {
  return (
    <Panel title="Welcome">
      <Button>Sign up</Button>
      <Button>Log in</Button>
      <ThemeContext.Provider value="light">
        <Footer />
      </ThemeContext.Provider>
    </Panel>
  );
}

function Footer() {
  return (
    <footer>
      <Button>Settings</Button>
    </footer>
  );
}

function Panel({ title, children }) {
  const theme = useContext(ThemeContext);
  const className = 'panel-' + theme;
  return (
    <section className={className}>
      {title && <h1>{title}</h1>}
      {children}
    </section>
  )
}

function Button({ children }) {
  const theme = useContext(ThemeContext);
  const className = 'button-' + theme;
  return (
    <button className={className}>
      {children}
    </button>
  );
}
```

***

### Optimizing re-renders when passing objects and functions[](#optimizing-re-renders-when-passing-objects-and-functions "Link for Optimizing re-renders when passing objects and functions ")

You can pass any values via context, including objects and functions.

```
function MyApp() {

  const [currentUser, setCurrentUser] = useState(null);



  function login(response) {

    storeCredentials(response.credentials);

    setCurrentUser(response.user);

  }



  return (

    <AuthContext.Provider value={{ currentUser, login }}>

      <Page />

    </AuthContext.Provider>

  );

}
```

Here, the context value is a JavaScript object with two properties, one of which is a function. Whenever `MyApp` re-renders (for example, on a route update), this will be a *different* object pointing at a *different* function, so React will also have to re-render all components deep in the tree that call `useContext(AuthContext)`.

In smaller apps, this is not a problem. However, there is no need to re-render them if the underlying data, like `currentUser`, has not changed. To help React take advantage of that fact, you may wrap the `login` function with [`useCallback`](/reference/react/useCallback) and wrap the object creation into [`useMemo`](/reference/react/useMemo). This is a performance optimization:

```
import { useCallback, useMemo } from 'react';



function MyApp() {

  const [currentUser, setCurrentUser] = useState(null);



  const login = useCallback((response) => {

    storeCredentials(response.credentials);

    setCurrentUser(response.user);

  }, []);



  const contextValue = useMemo(() => ({

    currentUser,

    login

  }), [currentUser, login]);



  return (

    <AuthContext.Provider value={contextValue}>

      <Page />

    </AuthContext.Provider>

  );

}
```

As a result of this change, even if `MyApp` needs to re-render, the components calling `useContext(AuthContext)` won’t need to re-render unless `currentUser` has changed.

Read more about [`useMemo`](/reference/react/useMemo#skipping-re-rendering-of-components) and [`useCallback`.](/reference/react/useCallback#skipping-re-rendering-of-components)

***

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### My component doesn’t see the value from my provider[](#my-component-doesnt-see-the-value-from-my-provider "Link for My component doesn’t see the value from my provider ")

There are a few common ways that this can happen:

1. You’re rendering `<SomeContext.Provider>` in the same component (or below) as where you’re calling `useContext()`. Move `<SomeContext.Provider>` *above and outside* the component calling `useContext()`.
2. You may have forgotten to wrap your component with `<SomeContext.Provider>`, or you might have put it in a different part of the tree than you thought. Check whether the hierarchy is right using [React DevTools.](/learn/react-developer-tools)
3. You might be running into some build issue with your tooling that causes `SomeContext` as seen from the providing component and `SomeContext` as seen by the reading component to be two different objects. This can happen if you use symlinks, for example. You can verify this by assigning them to globals like `window.SomeContext1` and `window.SomeContext2` and then checking whether `window.SomeContext1 === window.SomeContext2` in the console. If they’re not the same, fix that issue on the build tool level.

### I am always getting `undefined` from my context although the default value is different[](#i-am-always-getting-undefined-from-my-context-although-the-default-value-is-different "Link for this heading")

You might have a provider without a `value` in the tree:

```
// 🚩 Doesn't work: no value prop

<ThemeContext.Provider>

   <Button />

</ThemeContext.Provider>
```

If you forget to specify `value`, it’s like passing `value={undefined}`.

You may have also mistakingly used a different prop name by mistake:

```
// 🚩 Doesn't work: prop should be called "value"

<ThemeContext.Provider theme={theme}>

   <Button />

</ThemeContext.Provider>
```

In both of these cases you should see a warning from React in the console. To fix them, call the prop `value`:

```
// ✅ Passing the value prop

<ThemeContext.Provider value={theme}>

   <Button />

</ThemeContext.Provider>
```

Note that the [default value from your `createContext(defaultValue)` call](#specifying-a-fallback-default-value) is only used **if there is no matching provider above at all.** If there is a `<SomeContext.Provider value={undefined}>` component somewhere in the parent tree, the component calling `useContext(SomeContext)` *will* receive `undefined` as the context value.

[PrevioususeCallback](/reference/react/useCallback)

[NextuseDebugValue](/reference/react/useDebugValue)

***

----
url: https://legacy.reactjs.org/blog/2014/07/13/react-v0.11-rc1.html
----

July 13, 2014 by [Paul O’Shannessy](https://twitter.com/zpao)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

It’s that time again… we’re just about ready to ship a new React release! v0.11 includes a wide array of bug fixes and features. We highlighted some of the most important changes below, along with the full changelog.

The release candidate is available for download from the CDN:

* **React**\
  Dev build with warnings: <https://fb.me/react-0.11.0-rc1.js>\
  Minified build for production: <https://fb.me/react-0.11.0-rc1.min.js>
* **React with Add-Ons**\
  Dev build with warnings: <https://fb.me/react-with-addons-0.11.0-rc1.js>\
  Minified build for production: <https://fb.me/react-with-addons-0.11.0-rc1.min.js>
* **In-Browser JSX transformer**\
  <https://fb.me/JSXTransformer-0.11.0-rc1.js>

We’ve also published version `0.11.0-rc1` of the `react` and `react-tools` packages on npm and the `react` package on bower.

Please try these builds out and [file an issue on GitHub](https://github.com/facebook/react/issues/new) if you see anything awry.

## [](#getdefaultprops)`getDefaultProps`

Starting in React 0.11, `getDefaultProps()` is called only once when `React.createClass()` is called, instead of each time a component is rendered. This means that `getDefaultProps()` can no longer vary its return value based on `this.props` and any objects will be shared across all instances. This change improves performance and will make it possible in the future to do PropTypes checks earlier in the rendering process, allowing us to give better error messages.

## [](#rendering-to-null)Rendering to `null`

Since React’s release, people have been using work arounds to “render nothing”. Usually this means returning an empty `<div/>` or `<span/>`. Some people even got clever and started returning `<noscript/>` to avoid extraneous DOM nodes. We finally provided a “blessed” solution that allows developers to write meaningful code. Returning `null` is an explicit indication to React that you do not want anything rendered. Behind the scenes we make this work with a `<noscript>` element, though in the future we hope to not put anything in the document. In the mean time, `<noscript>` elements do not affect layout in any way, so you can feel safe using `null` today!

```
// Before
render: function() {
  if (!this.state.visible) {
    return <span/>;
  }
  // ...
}

// After
render: function() {
  if (!this.state.visible) {
    return null;
  }
  // ...
}
```

## [](#jsx-namespacing)JSX Namespacing

Another feature request we’ve been hearing for a long time is the ability to have namespaces in JSX. Given that JSX is just JavaScript, we didn’t want to use XML namespacing. Instead we opted for a standard JS approach: object property access. Instead of assigning variables to access components stored in an object (such as a component library), you can now use the component directly as `<Namespace.Component/>`.

```
// Before
var UI = require('UI');
var UILayout = UI.Layout;
var UIButton = UI.Button;
var UILabel = UI.Label;

render: function() {
  return <UILayout><UIButton /><UILabel>text</UILabel></UILayout>;
}

// After
var UI = require('UI');

render: function() {
  return <UI.Layout><UI.Button /><UI.Label>text</UI.Label></UI.Layout>;
}
```

## [](#improved-keyboard-event-normalization)Improved keyboard event normalization

Keyboard events now contain a normalized `e.key` value according to the [DOM Level 3 Events spec](http://www.w3.org/TR/DOM-Level-3-Events/#keys-special), allowing you to write simpler key handling code that works in all browsers, such as:

```
handleKeyDown: function(e) {
  if (e.key === 'Enter') {
    // Handle enter key
  } else if (e.key === ' ') {
    // Handle spacebar
  } else if (e.key === 'ArrowLeft') {
    // Handle left arrow
  }
},
```

Keyboard and mouse events also now include a normalized `e.getModifierState()` that works consistently across browsers.

## [](#changelog)Changelog

### [](#react-core)React Core

#### [](#breaking-changes)Breaking Changes

* `getDefaultProps()` is now called once per class and shared across all instances

* PureRenderMixin

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2014-07-13-react-v0.11-rc1.md)

----
url: https://react.dev/learn
----

[Learn React](/learn)

# Quick Start[](#undefined "Link for this heading")

Welcome to the React documentation! This page will give you an introduction to 80% of the React concepts that you will use on a daily basis.

```
function MyButton() {

  return (

    <button>I'm a button</button>

  );

}
```

Now that you’ve declared `MyButton`, you can nest it into another component:

```
export default function MyApp() {

  return (

    <div>

      <h1>Welcome to my app</h1>

      <MyButton />

    </div>

  );

}
```

Notice that `<MyButton />` starts with a capital letter. That’s how you know it’s a React component. React component names must always start with a capital letter, while HTML tags must be lowercase.

Have a look at the result:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
function MyButton() {
  return (
    <button>
      I'm a button
    </button>
  );
}

export default function MyApp() {
  return (
    <div>
      <h1>Welcome to my app</h1>
      <MyButton />
    </div>
  );
}
```

The `export default` keywords specify the main component in the file. If you’re not familiar with some piece of JavaScript syntax, [MDN](https://developer.mozilla.org/en-US/docs/web/javascript/reference/statements/export) and [javascript.info](https://javascript.info/import-export) have great references.

## Writing markup with JSX[](#writing-markup-with-jsx "Link for Writing markup with JSX ")

The markup syntax you’ve seen above is called *JSX*. It is optional, but most React projects use JSX for its convenience. All of the [tools we recommend for local development](/learn/installation) support JSX out of the box.

JSX is stricter than HTML. You have to close tags like `<br />`. Your component also can’t return multiple JSX tags. You have to wrap them into a shared parent, like a `<div>...</div>` or an empty `<>...</>` wrapper:

```
function AboutPage() {

  return (

    <>

      <h1>About</h1>

      <p>Hello there.<br />How do you do?</p>

    </>

  );

}
```

If you have a lot of HTML to port to JSX, you can use an [online converter.](https://transform.tools/html-to-jsx)

## Adding styles[](#adding-styles "Link for Adding styles ")

In React, you specify a CSS class with `className`. It works the same way as the HTML [`class`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/class) attribute:

```
<img className="avatar" />
```

Then you write the CSS rules for it in a separate CSS file:

```
/* In your CSS */

.avatar {

  border-radius: 50%;

}
```

React does not prescribe how you add CSS files. In the simplest case, you’ll add a [`<link>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link) tag to your HTML. If you use a build tool or a framework, consult its documentation to learn how to add a CSS file to your project.

## Displaying data[](#displaying-data "Link for Displaying data ")

JSX lets you put markup into JavaScript. Curly braces let you “escape back” into JavaScript so that you can embed some variable from your code and display it to the user. For example, this will display `user.name`:

```
return (

  <h1>

    {user.name}

  </h1>

);
```

You can also “escape into JavaScript” from JSX attributes, but you have to use curly braces *instead of* quotes. For example, `className="avatar"` passes the `"avatar"` string as the CSS class, but `src={user.imageUrl}` reads the JavaScript `user.imageUrl` variable value, and then passes that value as the `src` attribute:

```
return (

  <img

    className="avatar"

    src={user.imageUrl}

  />

);
```

You can put more complex expressions inside the JSX curly braces too, for example, [string concatenation](https://javascript.info/operators#string-concatenation-with-binary):

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
const user = {
  name: 'Hedy Lamarr',
  imageUrl: 'https://react.dev/images/docs/scientists/yXOvdOSs.jpg',
  imageSize: 90,
};

export default function Profile() {
  return (
    <>
      <h1>{user.name}</h1>
      <img
        className="avatar"
        src={user.imageUrl}
        alt={'Photo of ' + user.name}
        style={{
          width: user.imageSize,
          height: user.imageSize
        }}
      />
    </>
  );
}
```

In the above example, `style={{}}` is not a special syntax, but a regular `{}` object inside the `style={ }` JSX curly braces. You can use the `style` attribute when your styles depend on JavaScript variables.

## Conditional rendering[](#conditional-rendering "Link for Conditional rendering ")

In React, there is no special syntax for writing conditions. Instead, you’ll use the same techniques as you use when writing regular JavaScript code. For example, you can use an [`if`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/if...else) statement to conditionally include JSX:

```
let content;

if (isLoggedIn) {

  content = <AdminPanel />;

} else {

  content = <LoginForm />;

}

return (

  <div>

    {content}

  </div>

);
```

If you prefer more compact code, you can use the [conditional `?` operator.](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator) Unlike `if`, it works inside JSX:

```
<div>

  {isLoggedIn ? (

    <AdminPanel />

  ) : (

    <LoginForm />

  )}

</div>
```

When you don’t need the `else` branch, you can also use a shorter [logical `&&` syntax](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_AND#short-circuit_evaluation):

```
<div>

  {isLoggedIn && <AdminPanel />}

</div>
```

All of these approaches also work for conditionally specifying attributes. If you’re unfamiliar with some of this JavaScript syntax, you can start by always using `if...else`.

## Rendering lists[](#rendering-lists "Link for Rendering lists ")

You will rely on JavaScript features like [`for` loop](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for) and the [array `map()` function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) to render lists of components.

For example, let’s say you have an array of products:

```
const products = [

  { title: 'Cabbage', id: 1 },

  { title: 'Garlic', id: 2 },

  { title: 'Apple', id: 3 },

];
```

Inside your component, use the `map()` function to transform an array of products into an array of `<li>` items:

```
const listItems = products.map(product =>

  <li key={product.id}>

    {product.title}

  </li>

);



return (

  <ul>{listItems}</ul>

);
```

Notice how `<li>` has a `key` attribute. For each item in a list, you should pass a string or a number that uniquely identifies that item among its siblings. Usually, a key should be coming from your data, such as a database ID. React uses your keys to know what happened if you later insert, delete, or reorder the items.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
const products = [
  { title: 'Cabbage', isFruit: false, id: 1 },
  { title: 'Garlic', isFruit: false, id: 2 },
  { title: 'Apple', isFruit: true, id: 3 },
];

export default function ShoppingList() {
  const listItems = products.map(product =>
    <li
      key={product.id}
      style={{
        color: product.isFruit ? 'magenta' : 'darkgreen'
      }}
    >
      {product.title}
    </li>
  );

  return (
    <ul>{listItems}</ul>
  );
}
```

## Responding to events[](#responding-to-events "Link for Responding to events ")

You can respond to events by declaring *event handler* functions inside your components:

```
function MyButton() {

  function handleClick() {

    alert('You clicked me!');

  }



  return (

    <button onClick={handleClick}>

      Click me

    </button>

  );

}
```

Notice how `onClick={handleClick}` has no parentheses at the end! Do not *call* the event handler function: you only need to *pass it down*. React will call your event handler when the user clicks the button.

## Updating the screen[](#updating-the-screen "Link for Updating the screen ")

Often, you’ll want your component to “remember” some information and display it. For example, maybe you want to count the number of times a button is clicked. To do this, add *state* to your component.

First, import [`useState`](/reference/react/useState) from React:

```
import { useState } from 'react';
```

Now you can declare a *state variable* inside your component:

```
function MyButton() {

  const [count, setCount] = useState(0);

  // ...
```

You’ll get two things from `useState`: the current state (`count`), and the function that lets you update it (`setCount`). You can give them any names, but the convention is to write `[something, setSomething]`.

The first time the button is displayed, `count` will be `0` because you passed `0` to `useState()`. When you want to change state, call `setCount()` and pass the new value to it. Clicking this button will increment the counter:

```
function MyButton() {

  const [count, setCount] = useState(0);



  function handleClick() {

    setCount(count + 1);

  }



  return (

    <button onClick={handleClick}>

      Clicked {count} times

    </button>

  );

}
```

React will call your component function again. This time, `count` will be `1`. Then it will be `2`. And so on.

If you render the same component multiple times, each will get its own state. Click each button separately:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function MyApp() {
  return (
    <div>
      <h1>Counters that update separately</h1>
      <MyButton />
      <MyButton />
    </div>
  );
}

function MyButton() {
  const [count, setCount] = useState(0);

  function handleClick() {
    setCount(count + 1);
  }

  return (
    <button onClick={handleClick}>
      Clicked {count} times
    </button>
  );
}
```

```
export default function MyApp() {

  const [count, setCount] = useState(0);



  function handleClick() {

    setCount(count + 1);

  }



  return (

    <div>

      <h1>Counters that update separately</h1>

      <MyButton />

      <MyButton />

    </div>

  );

}



function MyButton() {

  // ... we're moving code from here ...

}
```

Then, *pass the state down* from `MyApp` to each `MyButton`, together with the shared click handler. You can pass information to `MyButton` using the JSX curly braces, just like you previously did with built-in tags like `<img>`:

```
export default function MyApp() {

  const [count, setCount] = useState(0);



  function handleClick() {

    setCount(count + 1);

  }



  return (

    <div>

      <h1>Counters that update together</h1>

      <MyButton count={count} onClick={handleClick} />

      <MyButton count={count} onClick={handleClick} />

    </div>

  );

}
```

The information you pass down like this is called *props*. Now the `MyApp` component contains the `count` state and the `handleClick` event handler, and *passes both of them down as props* to each of the buttons.

Finally, change `MyButton` to *read* the props you have passed from its parent component:

```
function MyButton({ count, onClick }) {

  return (

    <button onClick={onClick}>

      Clicked {count} times

    </button>

  );

}
```

When you click the button, the `onClick` handler fires. Each button’s `onClick` prop was set to the `handleClick` function inside `MyApp`, so the code inside of it runs. That code calls `setCount(count + 1)`, incrementing the `count` state variable. The new `count` value is passed as a prop to each button, so they all show the new value. This is called “lifting state up”. By moving state up, you’ve shared it between components.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function MyApp() {
  const [count, setCount] = useState(0);

  function handleClick() {
    setCount(count + 1);
  }

  return (
    <div>
      <h1>Counters that update together</h1>
      <MyButton count={count} onClick={handleClick} />
      <MyButton count={count} onClick={handleClick} />
    </div>
  );
}

function MyButton({ count, onClick }) {
  return (
    <button onClick={onClick}>
      Clicked {count} times
    </button>
  );
}
```

## Next Steps[](#next-steps "Link for Next Steps ")

By now, you know the basics of how to write React code!

Check out the [Tutorial](/learn/tutorial-tic-tac-toe) to put them into practice and build your first mini-app with React.

[NextTutorial: Tic-Tac-Toe](/learn/tutorial-tic-tac-toe)

***

----
url: https://react.dev/community/docs-contributors
----

[Community](/community)

# Docs Contributors[](#undefined "Link for this heading")

React documentation is written and maintained by the [React team](/community/team) and [external contributors.](https://github.com/reactjs/react.dev/graphs/contributors) On this page, we’d like to thank a few people who’ve made significant contributions to this site.

## Content[](#content "Link for Content ")

* [Rachel Nabors](https://twitter.com/RachelNabors): editing, writing, illustrating
* [Dan Abramov](https://bsky.app/profile/danabra.mov): writing, curriculum design

* [Dan Abramov](https://bsky.app/profile/danabra.mov): site development
* [Rick Hanlon](https://twitter.com/rickhanlonii): site development
* [Harish Kumar](https://www.strek.in/): development and maintenance
* [Luna Ruan](https://twitter.com/lunaruan): sandbox improvements

We’d also like to thank countless alpha testers and community members who gave us feedback along the way.

[PreviousMeet the Team](/community/team)

[NextTranslations](/community/translations)

***

----
url: https://react.dev/reference/react/components
----

[API Reference](/reference/react)

# Built-in React Components[](#undefined "Link for this heading")

React exposes a few built-in components that you can use in your JSX.

***

## Built-in components[](#built-in-components "Link for Built-in components ")

* [`<Fragment>`](/reference/react/Fragment), alternatively written as `<>...</>`, lets you group multiple JSX nodes together.
* [`<Profiler>`](/reference/react/Profiler) lets you measure rendering performance of a React tree programmatically.
* [`<Suspense>`](/reference/react/Suspense) lets you display a fallback while the child components are loading.
* [`<StrictMode>`](/reference/react/StrictMode) enables extra development-only checks that help you find bugs early.
* [`<Activity>`](/reference/react/Activity) lets you hide and restore the UI and internal state of its children.

***

## Your own components[](#your-own-components "Link for Your own components ")

You can also [define your own components](/learn/your-first-component) as JavaScript functions.

[PrevioususeTransition](/reference/react/useTransition)

[Next\<Fragment> (<>)](/reference/react/Fragment)

***

----
url: https://18.react.dev/reference/react-dom/findDOMNode
----

[API Reference](/reference/react)

[APIs](/reference/react-dom)

# findDOMNode[](#undefined "Link for this heading")

### Deprecated

This API will be removed in a future major version of React. [See the alternatives.](#alternatives)

`findDOMNode` finds the browser DOM node for a React [class component](/reference/react/Component) instance.

```
const domNode = findDOMNode(componentInstance)
```

***

## Reference[](#reference "Link for Reference ")

### `findDOMNode(componentInstance)`[](#finddomnode "Link for this heading")

Call `findDOMNode` to find the browser DOM node for a given React [class component](/reference/react/Component) instance.

```
import { findDOMNode } from 'react-dom';



const domNode = findDOMNode(componentInstance);
```

***

## Usage[](#usage "Link for Usage ")

### Finding the root DOM node of a class component[](#finding-the-root-dom-node-of-a-class-component "Link for Finding the root DOM node of a class component ")

Call `findDOMNode` with a [class component](/reference/react/Component) instance (usually, `this`) to find the DOM node it has rendered.

```
class AutoselectingInput extends Component {

  componentDidMount() {

    const input = findDOMNode(this);

    input.select()

  }



  render() {

    return <input defaultValue="Hello" />

  }

}
```

Here, the `input` variable will be set to the `<input>` DOM element. This lets you do something with it. For example, when clicking “Show example” below mounts the input, [`input.select()`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/select) selects all text in the input:

```
import { Component } from 'react';
import { findDOMNode } from 'react-dom';

class AutoselectingInput extends Component {
  componentDidMount() {
    const input = findDOMNode(this);
    input.select()
  }

  render() {
    return <input defaultValue="Hello" />
  }
}

export default AutoselectingInput;
```

***

## Alternatives[](#alternatives "Link for Alternatives ")

### Reading component’s own DOM node from a ref[](#reading-components-own-dom-node-from-a-ref "Link for Reading component’s own DOM node from a ref ")

Code using `findDOMNode` is fragile because the connection between the JSX node and the code manipulating the corresponding DOM node is not explicit. For example, try wrapping this `<input />` into a `<div>`:

```
import { Component } from 'react';
import { findDOMNode } from 'react-dom';

class AutoselectingInput extends Component {
  componentDidMount() {
    const input = findDOMNode(this);
    input.select()
  }
  render() {
    return <input defaultValue="Hello" />
  }
}

export default AutoselectingInput;
```

This will break the code because now, `findDOMNode(this)` finds the `<div>` DOM node, but the code expects an `<input>` DOM node. To avoid these kinds of problems, use [`createRef`](/reference/react/createRef) to manage a specific DOM node.

In this example, `findDOMNode` is no longer used. Instead, `inputRef = createRef(null)` is defined as an instance field on the class. To read the DOM node from it, you can use `this.inputRef.current`. To attach it to the JSX, you render `<input ref={this.inputRef} />`. This connects the code using the DOM node to its JSX:

```
import { createRef, Component } from 'react';

class AutoselectingInput extends Component {
  inputRef = createRef(null);

  componentDidMount() {
    const input = this.inputRef.current;
    input.select()
  }

  render() {
    return (
      <input ref={this.inputRef} defaultValue="Hello" />
    );
  }
}

export default AutoselectingInput;
```

In modern React without class components, the equivalent code would call [`useRef`](/reference/react/useRef) instead:

```
import { useRef, useEffect } from 'react';

export default function AutoselectingInput() {
  const inputRef = useRef(null);

  useEffect(() => {
    const input = inputRef.current;
    input.select();
  }, []);

  return <input ref={inputRef} defaultValue="Hello" />
}
```

[Read more about manipulating the DOM with refs.](/learn/manipulating-the-dom-with-refs)

***

### Reading a child component’s DOM node from a forwarded ref[](#reading-a-child-components-dom-node-from-a-forwarded-ref "Link for Reading a child component’s DOM node from a forwarded ref ")

In this example, `findDOMNode(this)` finds a DOM node that belongs to another component. The `AutoselectingInput` renders `MyInput`, which is your own component that renders a browser `<input>`.

```
import { Component } from 'react';
import { findDOMNode } from 'react-dom';
import MyInput from './MyInput.js';

class AutoselectingInput extends Component {
  componentDidMount() {
    const input = findDOMNode(this);
    input.select()
  }
  render() {
    return <MyInput />;
  }
}

export default AutoselectingInput;
```

Notice that calling `findDOMNode(this)` inside `AutoselectingInput` still gives you the DOM `<input>`—even though the JSX for this `<input>` is hidden inside the `MyInput` component. This seems convenient for the above example, but it leads to fragile code. Imagine that you wanted to edit `MyInput` later and add a wrapper `<div>` around it. This would break the code of `AutoselectingInput` (which expects to find an `<input>`).

To replace `findDOMNode` in this example, the two components need to coordinate:

1. `AutoSelectingInput` should declare a ref, like [in the earlier example](#reading-components-own-dom-node-from-a-ref), and pass it to `<MyInput>`.
2. `MyInput` should be declared with [`forwardRef`](/reference/react/forwardRef) to take that ref and forward it down to the `<input>` node.

This version does that, so it no longer needs `findDOMNode`:

```
import { createRef, Component } from 'react';
import MyInput from './MyInput.js';

class AutoselectingInput extends Component {
  inputRef = createRef(null);

  componentDidMount() {
    const input = this.inputRef.current;
    input.select()
  }

  render() {
    return (
      <MyInput ref={this.inputRef} />
    );
  }
}

export default AutoselectingInput;
```

Here is how this code would look like with function components instead of classes:

```
import { useRef, useEffect } from 'react';
import MyInput from './MyInput.js';

export default function AutoselectingInput() {
  const inputRef = useRef(null);

  useEffect(() => {
    const input = inputRef.current;
    input.select();
  }, []);

  return <MyInput ref={inputRef} defaultValue="Hello" />
}
```

***

### Adding a wrapper `<div>` element[](#adding-a-wrapper-div-element "Link for this heading")

Sometimes a component needs to know the position and size of its children. This makes it tempting to find the children with `findDOMNode(this)`, and then use DOM methods like [`getBoundingClientRect`](https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect) for measurements.

There is currently no direct equivalent for this use case, which is why `findDOMNode` is deprecated but is not yet removed completely from React. In the meantime, you can try rendering a wrapper `<div>` node around the content as a workaround, and getting a ref to that node. However, extra wrappers can break styling.

```
<div ref={someRef}>

  {children}

</div>
```

This also applies to focusing and scrolling to arbitrary children.

[PreviousflushSync](/reference/react-dom/flushSync)

[Nexthydrate](/reference/react-dom/hydrate)

***

----
url: https://legacy.reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html
----

June 07, 2018 by [Brian Vaughn](https://github.com/bvaughn)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

React 16.4 included a [bugfix for getDerivedStateFromProps](/blog/2018/05/23/react-v-16-4.html#bugfix-for-getderivedstatefromprops) which caused some existing bugs in React components to reproduce more consistently. If this release exposed a case where your application was using an anti-pattern and didn’t work properly after the fix, we’re sorry for the churn. In this post, we will explain some common anti-patterns with derived state and our preferred alternatives.

For a long time, the lifecycle `componentWillReceiveProps` was the only way to update state in response to a change in props without an additional render. In version 16.3, [we introduced a replacement lifecycle, `getDerivedStateFromProps`](/blog/2018/03/29/react-v-16-3.html#component-lifecycle-changes) to solve the same use cases in a safer way. At the same time, we’ve realized that people have many misconceptions about how to use both methods, and we’ve found anti-patterns that result in subtle and confusing bugs. The `getDerivedStateFromProps` bugfix in 16.4 [makes derived state more predictable](https://github.com/facebook/react/issues/12898), so the results of misusing it are easier to notice.

> Note
>
> All of the anti-patterns described in this post apply to both the older `componentWillReceiveProps` and the newer `getDerivedStateFromProps`.

This blog post will cover the following topics:

* [When to use derived state](#when-to-use-derived-state)

* [Common bugs when using derived state](#common-bugs-when-using-derived-state)

  * [Anti-pattern: Unconditionally copying props to state](#anti-pattern-unconditionally-copying-props-to-state)
  * [Anti-pattern: Erasing state when props change](#anti-pattern-erasing-state-when-props-change)

* [Preferred solutions](#preferred-solutions)

* [What about memoization?](#what-about-memoization)

## [](#when-to-use-derived-state)When to Use Derived State

`getDerivedStateFromProps` exists for only one purpose. It enables a component to update its internal state as the result of **changes in props**. Our previous blog post provided some examples, like [recording the current scroll direction based on a changing offset prop](/blog/2018/03/27/update-on-async-rendering.html#updating-state-based-on-props) or [loading external data specified by a source prop](/blog/2018/03/27/update-on-async-rendering.html#fetching-external-data-when-props-change).

We did not provide many examples, because as a general rule, **derived state should be used sparingly**. All problems with derived state that we have seen can be ultimately reduced to either (1) unconditionally updating state from props or (2) updating state whenever props and state don’t match. (We’ll go over both in more detail below.)

* If you’re using derived state to memoize some computation based only on the current props, you don’t need derived state. See [What about memoization?](#what-about-memoization) below.
* If you’re updating derived state unconditionally or updating it whenever props and state don’t match, your component likely resets its state too frequently. Read on for more details.

## [](#common-bugs-when-using-derived-state)Common Bugs When Using Derived State

The terms [“controlled”](/docs/forms.html#controlled-components) and [“uncontrolled”](/docs/uncontrolled-components.html) usually refer to form inputs, but they can also describe where any component’s data lives. Data passed in as props can be thought of as **controlled** (because the parent component *controls* that data). Data that exists only in internal state can be thought of as **uncontrolled** (because the parent can’t directly change it).

The most common mistake with derived state is mixing these two; when a derived state value is also updated by `setState` calls, there isn’t a single source of truth for the data. The [external data loading example](/blog/2018/03/27/update-on-async-rendering.html#fetching-external-data-when-props-change) mentioned above may sound similar, but it’s different in a few important ways. In the loading example, there is a clear source of truth for both the “source” prop and the “loading” state. When the source prop changes, the loading state should **always** be overridden. Conversely, the state is overridden only when the prop **changes** and is otherwise managed by the component.

Problems arise when any of these constraints are changed. This typically comes in two forms. Let’s take a look at both.

### [](#anti-pattern-unconditionally-copying-props-to-state)Anti-pattern: Unconditionally copying props to state

A common misconception is that `getDerivedStateFromProps` and `componentWillReceiveProps` are only called when props “change”. These lifecycles are called any time a parent component rerenders, regardless of whether the props are “different” from before. Because of this, it has always been unsafe to *unconditionally* override state using either of these lifecycles. **Doing so will cause state updates to be lost.**

Let’s consider an example to demonstrate the problem. Here is an `EmailInput` component that “mirrors” an email prop in state:

```
class EmailInput extends Component {
  state = { email: this.props.email };

  render() {
    return <input onChange={this.handleChange} value={this.state.email} />;
  }

  handleChange = event => {
    this.setState({ email: event.target.value });
  };

  componentWillReceiveProps(nextProps) {
    // This will erase any local state updates!
    // Do not do this.
    this.setState({ email: nextProps.email });
  }
}
```

At first, this component might look okay. State is initialized to the value specified by props and updated when we type into the `<input>`. But if our component’s parent rerenders, anything we’ve typed into the `<input>` will be lost! ([See this demo for an example.](https://codesandbox.io/s/m3w9zn1z8x)) This holds true even if we were to compare `nextProps.email !== this.state.email` before resetting.

In this simple example, adding `shouldComponentUpdate` to rerender only when the email prop has changed could fix this. However in practice, components usually accept multiple props; another prop changing would still cause a rerender and improper reset. Function and object props are also often created inline, making it hard to implement a `shouldComponentUpdate` that reliably returns true only when a material change has happened. [Here is a demo that shows that happening.](https://codesandbox.io/s/jl0w6r9w59) As a result, `shouldComponentUpdate` is best used as a performance optimization, not to ensure correctness of derived state.

Hopefully it’s clear by now why **it is a bad idea to unconditionally copy props to state**. Before reviewing possible solutions, let’s look at a related problematic pattern: what if we were to only update the state when the email prop changes?

### [](#anti-pattern-erasing-state-when-props-change)Anti-pattern: Erasing state when props change

Continuing the example above, we could avoid accidentally erasing state by only updating it when `props.email` changes:

```
class EmailInput extends Component {
  state = {
    email: this.props.email
  };

  componentWillReceiveProps(nextProps) {
    // Any time props.email changes, update state.
    if (nextProps.email !== this.props.email) {
      this.setState({
        email: nextProps.email
      });
    }
  }
  
  // ...
}
```

> Note
>
> Even though the example above shows `componentWillReceiveProps`, the same anti-pattern applies to `getDerivedStateFromProps`.

We’ve just made a big improvement. Now our component will erase what we’ve typed only when the props actually change.

There is still a subtle problem. Imagine a password manager app using the above input component. When navigating between details for two accounts with the same email, the input would fail to reset. This is because the prop value passed to the component would be the same for both accounts! This would be a surprise to the user, as an unsaved change to one account would appear to affect other accounts that happened to share the same email. ([See demo here.](https://codesandbox.io/s/mz2lnkjkrx))

This design is fundamentally flawed, but it’s also an easy mistake to make. ([I’ve made it myself!](https://twitter.com/brian_d_vaughn/status/959600888242307072)) Fortunately there are two alternatives that work better. The key to both is that **for any piece of data, you need to pick a single component that owns it as the source of truth, and avoid duplicating it in other components.** Let’s take a look at each of the alternatives.

## [](#preferred-solutions)Preferred Solutions

### [](#recommendation-fully-controlled-component)Recommendation: Fully controlled component

One way to avoid the problems mentioned above is to remove state from our component entirely. If the email address only exists as a prop, then we don’t have to worry about conflicts with state. We could even convert `EmailInput` to a lighter-weight function component:

```
function EmailInput(props) {
  return <input onChange={props.onChange} value={props.email} />;
}
```

This approach simplifies the implementation of our component, but if we still want to store a draft value, the parent form component will now need to do that manually. ([Click here to see a demo of this pattern.](https://codesandbox.io/s/7154w1l551))

### [](#recommendation-fully-uncontrolled-component-with-a-key)Recommendation: Fully uncontrolled component with a `key`

Another alternative would be for our component to fully own the “draft” email state. In that case, our component could still accept a prop for the *initial* value, but it would ignore subsequent changes to that prop:

```
class EmailInput extends Component {
  state = { email: this.props.defaultEmail };

  handleChange = event => {
    this.setState({ email: event.target.value });
  };

  render() {
    return <input onChange={this.handleChange} value={this.state.email} />;
  }
}
```

In order to reset the value when moving to a different item (as in our password manager scenario), we can use the special React attribute called `key`. When a `key` changes, React will [*create* a new component instance rather than *update* the current one](/docs/reconciliation.html#keys). Keys are usually used for dynamic lists but are also useful here. In our case, we could use the user ID to recreate the email input any time a new user is selected:

```
<EmailInput
  defaultEmail={this.props.user.email}
  key={this.props.user.id}
/>
```

Each time the ID changes, the `EmailInput` will be recreated and its state will be reset to the latest `defaultEmail` value. ([Click here to see a demo of this pattern.](https://codesandbox.io/s/6v1znlxyxn)) With this approach, you don’t have to add `key` to every input. It might make more sense to put a `key` on the whole form instead. Every time the key changes, all components within the form will be recreated with a freshly initialized state.

In most cases, this is the best way to handle state that needs to be reset.

> Note
>
> While this may sound slow, the performance difference is usually insignificant. Using a key can even be faster if the components have heavy logic that runs on updates since diffing gets bypassed for that subtree.

#### [](#alternative-1-reset-uncontrolled-component-with-an-id-prop)Alternative 1: Reset uncontrolled component with an ID prop

If `key` doesn’t work for some reason (perhaps the component is very expensive to initialize), a workable but cumbersome solution would be to watch for changes to “userID” in `getDerivedStateFromProps`:

```
class EmailInput extends Component {
  state = {
    email: this.props.defaultEmail,
    prevPropsUserID: this.props.userID
  };

  static getDerivedStateFromProps(props, state) {
    // Any time the current user changes,
    // Reset any parts of state that are tied to that user.
    // In this simple example, that's just the email.
    if (props.userID !== state.prevPropsUserID) {
      return {
        prevPropsUserID: props.userID,
        email: props.defaultEmail
      };
    }
    return null;
  }

  // ...
}
```

This also provides the flexibility to only reset parts of our component’s internal state if we so choose. ([Click here to see a demo of this pattern.](https://codesandbox.io/s/rjyvp7l3rq))

> Note
>
> Even though the example above shows `getDerivedStateFromProps`, the same technique can be used with `componentWillReceiveProps`.

#### [](#alternative-2-reset-uncontrolled-component-with-an-instance-method)Alternative 2: Reset uncontrolled component with an instance method

More rarely, you may need to reset state even if there’s no appropriate ID to use as `key`. One solution is to reset the key to a random value or autoincrementing number each time you want to reset. One other viable alternative is to expose an instance method to imperatively reset the internal state:

```
class EmailInput extends Component {
  state = {
    email: this.props.defaultEmail
  };

  resetEmailForNewUser(newEmail) {
    this.setState({ email: newEmail });
  }

  // ...
}
```

The parent form component could then [use a `ref` to call this method](/docs/glossary.html#refs). ([Click here to see a demo of this pattern.](https://codesandbox.io/s/l70krvpykl))

Refs can be useful in certain cases like this one, but generally we recommend you use them sparingly. Even in the demo, this imperative method is nonideal because two renders will occur instead of one.

***

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

### [](#recap)Recap

To recap, when designing a component, it is important to decide whether its data will be controlled or uncontrolled.

Instead of trying to **“mirror” a prop value in state**, make the component **controlled**, and consolidate the two diverging values in the state of some parent component. For example, rather than a child accepting a “committed” `props.value` and tracking a “draft” `state.value`, have the parent manage both `state.draftValue` and `state.committedValue` and control the child’s value directly. This makes the data flow more explicit and predictable.

For **uncontrolled** components, if you’re trying to reset state when a particular prop (usually an ID) changes, you have a few options:

* **Recommendation: To reset *all internal state*, use the `key` attribute.**
* Alternative 1: To reset *only certain state fields*, watch for changes in a special property (e.g. `props.userID`).
* Alternative 2: You can also consider fall back to an imperative instance method using refs.

## [](#what-about-memoization)What about memoization?

We’ve also seen derived state used to ensure an expensive value used in `render` is recomputed only when the inputs change. This technique is known as [memoization](https://en.wikipedia.org/wiki/Memoization).

Using derived state for memoization isn’t necessarily bad, but it’s usually not the best solution. There is inherent complexity in managing derived state, and this complexity increases with each additional property. For example, if we add a second derived field to our component state then our implementation would need to separately track changes to both.

Let’s look at an example of one component that takes one prop—a list of items—and renders the items that match a search query entered by the user. We could use derived state to store the filtered list:

```
class Example extends Component {
  state = {
    filterText: "",
  };

  // *******************************************************
  // NOTE: this example is NOT the recommended approach.
  // See the examples below for our recommendations instead.
  // *******************************************************

  static getDerivedStateFromProps(props, state) {
    // Re-run the filter whenever the list array or filter text change.
    // Note we need to store prevPropsList and prevFilterText to detect changes.
    if (
      props.list !== state.prevPropsList ||
      state.prevFilterText !== state.filterText
    ) {
      return {
        prevPropsList: props.list,
        prevFilterText: state.filterText,
        filteredList: props.list.filter(item => item.text.includes(state.filterText))
      };
    }
    return null;
  }

  handleChange = event => {
    this.setState({ filterText: event.target.value });
  };

  render() {
    return (
      <Fragment>
        <input onChange={this.handleChange} value={this.state.filterText} />
        <ul>{this.state.filteredList.map(item => <li key={item.id}>{item.text}</li>)}</ul>
      </Fragment>
    );
  }
}
```

This implementation avoids recalculating `filteredList` more often than necessary. But it is more complicated than it needs to be, because it has to separately track and detect changes in both props and state in order to properly update the filtered list. In this example, we could simplify things by using `PureComponent` and moving the filter operation into the render method:

```
// PureComponents only rerender if at least one state or prop value changes.
// Change is determined by doing a shallow comparison of state and prop keys.
class Example extends PureComponent {
  // State only needs to hold the current filter text value:
  state = {
    filterText: ""
  };

  handleChange = event => {
    this.setState({ filterText: event.target.value });
  };

  render() {
    // The render method on this PureComponent is called only if
    // props.list or state.filterText has changed.
    const filteredList = this.props.list.filter(
      item => item.text.includes(this.state.filterText)
    )

    return (
      <Fragment>
        <input onChange={this.handleChange} value={this.state.filterText} />
        <ul>{filteredList.map(item => <li key={item.id}>{item.text}</li>)}</ul>
      </Fragment>
    );
  }
}
```

The above approach is much cleaner and simpler than the derived state version. Occasionally, this won’t be good enough—filtering may be slow for large lists, and `PureComponent` won’t prevent rerenders if another prop were to change. To address both of these concerns, we could add a memoization helper to avoid unnecessarily re-filtering our list:

```
import memoize from "memoize-one";

class Example extends Component {
  // State only needs to hold the current filter text value:
  state = { filterText: "" };

  // Re-run the filter whenever the list array or filter text changes:
  filter = memoize(
    (list, filterText) => list.filter(item => item.text.includes(filterText))
  );

  handleChange = event => {
    this.setState({ filterText: event.target.value });
  };

  render() {
    // Calculate the latest filtered list. If these arguments haven't changed
    // since the last render, `memoize-one` will reuse the last return value.
    const filteredList = this.filter(this.props.list, this.state.filterText);

    return (
      <Fragment>
        <input onChange={this.handleChange} value={this.state.filterText} />
        <ul>{filteredList.map(item => <li key={item.id}>{item.text}</li>)}</ul>
      </Fragment>
    );
  }
}
```

This is much simpler and performs just as well as the derived state version!

When using memoization, remember a couple of constraints:

1. In most cases, you’ll want to **attach the memoized function to a component instance**. This prevents multiple instances of a component from resetting each other’s memoized keys.
2. Typically you’ll want to use a memoization helper with a **limited cache size** in order to prevent memory leaks over time. (In the example above, we used `memoize-one` because it only caches the most recent arguments and result.)
3. None of the implementations shown in this section will work if `props.list` is recreated each time the parent component renders. But in most cases, this setup is appropriate.

## [](#in-closing)In closing

In real world applications, components often contain a mix of controlled and uncontrolled behaviors. This is okay! If each value has a clear source of truth, you can avoid the anti-patterns mentioned above.

It is also worth re-iterating that `getDerivedStateFromProps` (and derived state in general) is an advanced feature and should be used sparingly because of this complexity. If your use case falls outside of these patterns, please share it with us on [GitHub](https://github.com/reactjs/reactjs.org/issues/new) or [Twitter](https://twitter.com/reactjs)!

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2018-06-07-you-probably-dont-need-derived-state.md)

----
url: https://legacy.reactjs.org/blog/2014/02/24/community-roundup-17.html
----

February 24, 2014 by [Jonas Gebhardt](https://twitter.com/jonasgebhardt)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

It’s exciting to see the number of real-world React applications and components skyrocket over the past months! This community round-up features a few examples of inspiring React applications and components.

## [](#react-in-the-real-world)React in the Real World

### [](#facebook-lookback-video-editor)Facebook Lookback video editor

Large parts of Facebook’s web frontend are already powered by React. The recently released Facebook [Lookback video and its corresponding editor](https://www.facebook.com/lookback/edit/) are great examples of a complex, real-world React app.

### [](#russias-largest-bank-is-now-powered-by-react)Russia’s largest bank is now powered by React

Sberbank, Russia’s largest bank, recently switched large parts of their site to use React, as detailed in [this post by Vyacheslav Slinko](https://groups.google.com/forum/#!topic/reactjs/Kj6WATX0atg).

### [](#relato)Relato

[Relato](https://bripkens.github.io/relato/) by [Ben Ripkens](https://github.com/bripkens) shows Open Source Statistics based on npm data. It features a filterable and sortable table built in React. Check it out – it’s super fast!

### [](#makona-editor)Makona Editor

John Lynch ([@johnrlynch](https://twitter.com/johnrlynch)) created Makona, a block-style document editor for the web. Blocks of different content types comprise documents, authored using plain markup. At the switch of a toggle, block contents are then rendered on the page. While not quite a WYSIWYG editor, Makona uses plain textareas for input. This makes it compatible with a wider range of platforms than traditional rich text editors.[](https://johnthethird.github.io/makona-editor/)

### [](#create-chrome-extensions-using-react)Create Chrome extensions using React

React is in no way limited to just web pages. Brandon Tilley ([@BinaryMuse](https://twitter.com/BinaryMuse)) just released a detailed walk-through of [how he built his Chrome extension “Fast Tab Switcher” using React](http://brandontilley.com/2014/02/24/creating-chrome-extensions-with-react.html).

### [](#twitter-streaming-client)Twitter Streaming Client

Javier Aguirre ([@javaguirre](https://twitter.com/javaguirre)) put together a simple [twitter streaming client using node, socket.io and React](http://javaguirre.net/2014/02/11/twitter-streaming-api-with-node-socket-io-and-reactjs/).

### [](#sproutsheet)Sproutsheet

[Sproutsheet](http://sproutsheet.com/) is a gardening calendar. You can use it to track certain events that happen in the life of your plants. It’s currently in beta and supports localStorage, and data/image import and export.

### [](#instant-domain-search)Instant Domain Search

[Instant Domain Search](https://instantdomainsearch.com/) also uses React. It sure is instant!

### [](#svg-based-graphical-node-editor)SVG-based graphical node editor

[NoFlo](http://noflojs.org/) and [Meemoo](http://meemoo.org/) developer [Forresto Oliphant](http://www.forresto.com/) built an awesome SVG-based [node editor](https://forresto.github.io/prototyping/react/) in React.[](https://forresto.github.io/prototyping/react/)

### [](#ultimate-tic-tac-toe-game-in-react)Ultimate Tic-Tac-Toe Game in React

Rafał Cieślak ([@Ravicious](https://twitter.com/Ravicious)) wrote a [React version](https://ravicious.github.io/ultimate-ttt/) of [Ultimate Tic Tac Toe](http://mathwithbaddrawings.com/2013/06/16/ultimate-tic-tac-toe/). Find the source [here](https://github.com/ravicious/ultimate-ttt).

### [](#reactjs-gallery)ReactJS Gallery

[Emanuele Rampichini](https://github.com/lele85)’s [ReactJS Gallery](https://github.com/lele85/ReactGallery) is a cool demo app that shows fullscreen images from a folder on the server. If the folder content changes, the gallery app updates via websockets.

Emanuele shared this awesome demo video with us:

## [](#react-components)React Components

### [](#table-sorter)Table Sorter

[Table Sorter](https://bgerm.github.io/react-table-sorter-demo/) by [bgerm](https://github.com/bgerm) \[[source](https://github.com/bgerm/react-table-sorter-demo)] is another helpful React component.

### [](#static-search)Static-search

Dmitry Chestnykh [@dchest](https://twitter.com/dchest) wrote a [static search indexer](https://github.com/dchest/static-search) in Go, along with a [React-based web front-end](http://www.codingrobots.com/search/) that consumes search result via JSON.

### [](#lorem-ipsum-component)Lorem Ipsum component

[Martin Andert](https://github.com/martinandert) created [react-lorem-component](https://github.com/martinandert/react-lorem-component), a simple component for all your placeholding needs.

### [](#input-with-placeholder-shim)Input with placeholder shim

[react-input-placeholder](enigma-io/react-input-placeholder) by [enigma-io](@enigma-io) is a small wrapper around React.DOM.input that shims in placeholder functionality for browsers that don’t natively support it.

### [](#dicontainer)diContainer

[dicontainer](https://github.com/SpektrumFM/dicontainer) provides a dependency container that lets you inject Angular-style providers and services as simple React.js Mixins.

## [](#react-server-rendering)React server rendering

Ever wonder how to pre-render React components on the server? [react-server-example](https://github.com/mhart/react-server-example) by Michael Hart ([@hichaelmart](https://twitter.com/hichaelmart)) walks through the necessary steps.

Similarly, Alan deLevie ([@adelevie](https://twitter.com/adelevie)) created [react-client-server-starter](https://github.com/adelevie/react-client-server-starter), another detailed walk-through of how to server-render your app.

## [](#random-tweet)Random Tweet

> Recent changes: web ui is being upgraded to \[#reactjs]\(https\://twitter.com/search?q=%23reactjs\&src=hash), HEAD\~4 at \[https\://camlistore.googlesource.com/camlistore/]\(https\://camlistore.googlesource.com/camlistore/)
>
> — Camlistore (@Camlistore) [January 16, 2014](https://twitter.com/Camlistore/status/423925795820539904)

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2014-02-24-community-roundup-17.md)

----
url: https://react.dev/
----

# React

The library for web and native user interfaces

[Learn React](/learn)[API Reference](/reference/react)

## Create user interfaces from components

React lets you build user interfaces out of individual pieces called components. Create your own React components like `Thumbnail`, `LikeButton`, and `Video`. Then combine them into entire screens, pages, and apps.

### Video.js

```
function Video({ video }) {

  return (

    <div>

      <Thumbnail video={video} />

      <a href={video.url}>

        <h3>{video.title}</h3>

        <p>{video.description}</p>

      </a>

      <LikeButton video={video} />

    </div>

  );

}
```

```
function VideoList({ videos, emptyHeading }) {

  const count = videos.length;

  let heading = emptyHeading;

  if (count > 0) {

    const noun = count > 1 ? 'Videos' : 'Video';

    heading = count + ' ' + noun;

  }

  return (

    <section>

      <h2>{heading}</h2>

      {videos.map(video =>

        <Video key={video.id} video={video} />

      )}

    </section>

  );

}
```

```
import { useState } from 'react';



function SearchableVideoList({ videos }) {

  const [searchText, setSearchText] = useState('');

  const foundVideos = filterVideos(videos, searchText);

  return (

    <>

      <SearchInput

        value={searchText}

        onChange={newText => setSearchText(newText)} />

      <VideoList

        videos={foundVideos}

        emptyHeading={`No matches for “${searchText}”`} />

    </>

  );

}
```

----------------

React is a library. It lets you put components together, but it doesn’t prescribe how to do routing and data fetching. To build an entire app with React, we recommend a full-stack React framework like [Next.js](https://nextjs.org) or [React Router](https://reactrouter.com).

### confs/\[slug].js

```
import { db } from './database.js';

import { Suspense } from 'react';



async function ConferencePage({ slug }) {

  const conf = await db.Confs.find({ slug });

  return (

    <ConferenceLayout conf={conf}>

      <Suspense fallback={<TalksLoading />}>

        <Talks confId={conf.id} />

      </Suspense>

    </ConferenceLayout>

  );

}



async function Talks({ confId }) {

  const talks = await db.Talks.findAll({ confId });

  const videos = talks.map(talk => talk.video);

  return <SearchableVideoList videos={videos} />;

}
```

[Get started with a framework](/learn/creating-a-react-app)

## Use the best from every platform

People love web and native apps for different reasons. React lets you build both web apps and native apps using the same skills. It leans upon each platform’s unique strengths to let your interfaces feel just right on every platform.

example.com

#### Stay true to the web

People expect web app pages to load fast. On the server, React lets you start streaming HTML while you’re still fetching data, progressively filling in the remaining content before any JavaScript code loads. On the client, React can use standard web APIs to keep your UI responsive even in the middle of rendering.

6:34 AM

## [The React Foundation: A New Home for React Hosted by the Linux Foundation](/blog/2026/02/24/the-react-foundation)

[February 24, 2026](/blog/2026/02/24/the-react-foundation)

## [Additional Vulnerabilities in RSC](/blog/2025/12/11/denial-of-service-and-source-code-exposure-in-react-server-components)

[December 11, 2025](/blog/2025/12/11/denial-of-service-and-source-code-exposure-in-react-server-components)

## [Vulnerability in React Server Components](/blog/2025/12/03/critical-security-vulnerability-in-react-server-components)

[December 3, 2025](/blog/2025/12/03/critical-security-vulnerability-in-react-server-components)

## [React Conf 2025 Recap](/blog/2025/10/16/react-conf-2025-recap)

[October 16, 2025](/blog/2025/10/16/react-conf-2025-recap)

[Read more React news](/blog)

Join a community\
of millions
-----------

You’re not alone. Two million developers from all over the world visit the React docs every month. React is something that people and teams can agree on.

This is why React is more than a library, an architecture, or even an ecosystem. React is a community. It’s a place where you can ask for help, find opportunities, and meet new friends. You will meet both developers and designers, beginners and experts, researchers and artists, teachers and students. Our backgrounds may be very different, but React lets us all create user interfaces together.

Welcome to the\
React community
---------------

[Get Started](/learn)

----
url: https://react.dev/learn/react-compiler
----

[Learn React](/learn)

# React Compiler[](#undefined "Link for this heading")

## Introduction[](#introduction "Link for Introduction ")

Learn [what React Compiler does](/learn/react-compiler/introduction) and how it automatically optimizes your React application by handling memoization for you, eliminating the need for manual `useMemo`, `useCallback`, and `React.memo`.

## Installation[](#installation "Link for Installation ")

Get started with [installing React Compiler](/learn/react-compiler/installation) and learn how to configure it with your build tools.

## Incremental Adoption[](#incremental-adoption "Link for Incremental Adoption ")

Learn [strategies for gradually adopting React Compiler](/learn/react-compiler/incremental-adoption) in your existing codebase if you’re not ready to enable it everywhere yet.

## Debugging and Troubleshooting[](#debugging-and-troubleshooting "Link for Debugging and Troubleshooting ")

When things don’t work as expected, use our [debugging guide](/learn/react-compiler/debugging) to understand the difference between compiler errors and runtime issues, identify common breaking patterns, and follow a systematic debugging workflow.

## Configuration and Reference[](#configuration-and-reference "Link for Configuration and Reference ")

For detailed configuration options and API reference:

* [Configuration Options](/reference/react-compiler/configuration) - All compiler configuration options including React version compatibility
* [Directives](/reference/react-compiler/directives) - Function-level compilation control
* [Compiling Libraries](/reference/react-compiler/compiling-libraries) - Shipping pre-compiled libraries

## Additional resources[](#additional-resources "Link for Additional resources ")

In addition to these docs, we recommend checking the [React Compiler Working Group](https://github.com/reactwg/react-compiler) for additional information and discussion about the compiler.

[PreviousReact Developer Tools](/learn/react-developer-tools)

[NextIntroduction](/learn/react-compiler/introduction)

***

----
url: https://react.dev/reference/react-dom/server/renderToString
----

[API Reference](/reference/react)

[Server APIs](/reference/react-dom/server)

# renderToString[](#undefined "Link for this heading")

### Pitfall

`renderToString` does not support streaming or waiting for data. [See the alternatives.](#alternatives)

`renderToString` renders a React tree to an HTML string.

```
const html = renderToString(reactNode, options?)
```

* [Reference](#reference)
  * [`renderToString(reactNode, options?)`](#rendertostring)

* [Usage](#usage)
  * [Rendering a React tree as HTML to a string](#rendering-a-react-tree-as-html-to-a-string)

* [Alternatives](#alternatives)

  * [Migrating from `renderToString` to a streaming render on the server](#migrating-from-rendertostring-to-a-streaming-method-on-the-server)
  * [Migrating from `renderToString` to a static prerender on the server](#migrating-from-rendertostring-to-a-static-prerender-on-the-server)
  * [Removing `renderToString` from the client code](#removing-rendertostring-from-the-client-code)

* [Troubleshooting](#troubleshooting)
  * [When a component suspends, the HTML always contains a fallback](#when-a-component-suspends-the-html-always-contains-a-fallback)

***

## Reference[](#reference "Link for Reference ")

### `renderToString(reactNode, options?)`[](#rendertostring "Link for this heading")

On the server, call `renderToString` to render your app to HTML.

```
import { renderToString } from 'react-dom/server';



const html = renderToString(<App />);
```

***

## Usage[](#usage "Link for Usage ")

### Rendering a React tree as HTML to a string[](#rendering-a-react-tree-as-html-to-a-string "Link for Rendering a React tree as HTML to a string ")

Call `renderToString` to render your app to an HTML string which you can send with your server response:

```
import { renderToString } from 'react-dom/server';



// The route handler syntax depends on your backend framework

app.use('/', (request, response) => {

  const html = renderToString(<App />);

  response.send(html);

});
```

This will produce the initial non-interactive HTML output of your React components. On the client, you will need to call [`hydrateRoot`](/reference/react-dom/client/hydrateRoot) to *hydrate* that server-generated HTML and make it interactive.

### Pitfall

`renderToString` does not support streaming or waiting for data. [See the alternatives.](#alternatives)

***

## Alternatives[](#alternatives "Link for Alternatives ")

### Migrating from `renderToString` to a streaming render on the server[](#migrating-from-rendertostring-to-a-streaming-method-on-the-server "Link for this heading")

`renderToString` returns a string immediately, so it does not support streaming content as it loads.

When possible, we recommend using these fully-featured alternatives:

* If you use Node.js, use [`renderToPipeableStream`.](/reference/react-dom/server/renderToPipeableStream)
* If you use Deno or a modern edge runtime with [Web Streams](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API), use [`renderToReadableStream`.](/reference/react-dom/server/renderToReadableStream)

You can continue using `renderToString` if your server environment does not support streams.

***

### Migrating from `renderToString` to a static prerender on the server[](#migrating-from-rendertostring-to-a-static-prerender-on-the-server "Link for this heading")

`renderToString` returns a string immediately, so it does not support waiting for data to load for static HTML generation.

We recommend using these fully-featured alternatives:

* If you use Node.js, use [`prerenderToNodeStream`.](/reference/react-dom/static/prerenderToNodeStream)
* If you use Deno or a modern edge runtime with [Web Streams](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API), use [`prerender`.](/reference/react-dom/static/prerender)

You can continue using `renderToString` if your static site generation environment does not support streams.

***

### Removing `renderToString` from the client code[](#removing-rendertostring-from-the-client-code "Link for this heading")

Sometimes, `renderToString` is used on the client to convert some component to HTML.

```
// 🚩 Unnecessary: using renderToString on the client

import { renderToString } from 'react-dom/server';



const html = renderToString(<MyIcon />);

console.log(html); // For example, "<svg>...</svg>"
```

Importing `react-dom/server` **on the client** unnecessarily increases your bundle size and should be avoided. If you need to render some component to HTML in the browser, use [`createRoot`](/reference/react-dom/client/createRoot) and read HTML from the DOM:

```
import { createRoot } from 'react-dom/client';

import { flushSync } from 'react-dom';



const div = document.createElement('div');

const root = createRoot(div);

flushSync(() => {

  root.render(<MyIcon />);

});

console.log(div.innerHTML); // For example, "<svg>...</svg>"
```

The [`flushSync`](/reference/react-dom/flushSync) call is necessary so that the DOM is updated before reading its [`innerHTML`](https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML) property.

***

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### When a component suspends, the HTML always contains a fallback[](#when-a-component-suspends-the-html-always-contains-a-fallback "Link for When a component suspends, the HTML always contains a fallback ")

`renderToString` does not fully support Suspense.

If some component suspends (for example, because it’s defined with [`lazy`](/reference/react/lazy) or fetches data), `renderToString` will not wait for its content to resolve. Instead, `renderToString` will find the closest [`<Suspense>`](/reference/react/Suspense) boundary above it and render its `fallback` prop in the HTML. The content will not appear until the client code loads.

To solve this, use one of the [recommended streaming solutions.](#alternatives) For server side rendering, they can stream content in chunks as it resolves on the server so that the user sees the page being progressively filled in before the client code loads. For static site generation, they can wait for all the content to resolve before generating the static HTML.

[PreviousrenderToStaticMarkup](/reference/react-dom/server/renderToStaticMarkup)

[Nextresume](/reference/react-dom/server/resume)

***

----
url: https://18.react.dev/reference/react-dom/createPortal
----

[API Reference](/reference/react)

[APIs](/reference/react-dom)

# createPortal[](#undefined "Link for this heading")

`createPortal` lets you render some children into a different part of the DOM.

```
<div>

  <SomeComponent />

  {createPortal(children, domNode, key?)}

</div>
```

***

## Reference[](#reference "Link for Reference ")

### `createPortal(children, domNode, key?)`[](#createportal "Link for this heading")

To create a portal, call `createPortal`, passing some JSX, and the DOM node where it should be rendered:

```
import { createPortal } from 'react-dom';



// ...



<div>

  <p>This child is placed in the parent div.</p>

  {createPortal(

    <p>This child is placed in the document body.</p>,

    document.body

  )}

</div>
```

***

## Usage[](#usage "Link for Usage ")

### Rendering to a different part of the DOM[](#rendering-to-a-different-part-of-the-dom "Link for Rendering to a different part of the DOM ")

*Portals* let your components render some of their children into a different place in the DOM. This lets a part of your component “escape” from whatever containers it may be in. For example, a component can display a modal dialog or a tooltip that appears above and outside of the rest of the page.

To create a portal, render the result of `createPortal` with some JSX and the DOM node where it should go:

```
import { createPortal } from 'react-dom';



function MyComponent() {

  return (

    <div style={{ border: '2px solid black' }}>

      <p>This child is placed in the parent div.</p>

      {createPortal(

        <p>This child is placed in the document body.</p>,

        document.body

      )}

    </div>

  );

}
```

React will put the DOM nodes for the JSX you passed inside of the DOM node you provided.

Without a portal, the second `<p>` would be placed inside the parent `<div>`, but the portal “teleported” it into the [`document.body`:](https://developer.mozilla.org/en-US/docs/Web/API/Document/body)

```
import { createPortal } from 'react-dom';

export default function MyComponent() {
  return (
    <div style={{ border: '2px solid black' }}>
      <p>This child is placed in the parent div.</p>
      {createPortal(
        <p>This child is placed in the document body.</p>,
        document.body
      )}
    </div>
  );
}
```

Notice how the second paragraph visually appears outside the parent `<div>` with the border. If you inspect the DOM structure with developer tools, you’ll see that the second `<p>` got placed directly into the `<body>`:

```
<body>

  <div id="root">

    ...

      <div style="border: 2px solid black">

        <p>This child is placed inside the parent div.</p>

      </div>

    ...

  </div>

  <p>This child is placed in the document body.</p>

</body>
```

A portal only changes the physical placement of the DOM node. In every other way, the JSX you render into a portal acts as a child node of the React component that renders it. For example, the child can access the context provided by the parent tree, and events still bubble up from children to parents according to the React tree.

***

### Rendering a modal dialog with a portal[](#rendering-a-modal-dialog-with-a-portal "Link for Rendering a modal dialog with a portal ")

You can use a portal to create a modal dialog that floats above the rest of the page, even if the component that summons the dialog is inside a container with `overflow: hidden` or other styles that interfere with the dialog.

In this example, the two containers have styles that disrupt the modal dialog, but the one rendered into a portal is unaffected because, in the DOM, the modal is not contained within the parent JSX elements.

```
import NoPortalExample from './NoPortalExample';
import PortalExample from './PortalExample';

export default function App() {
  return (
    <>
      <div className="clipping-container">
        <NoPortalExample  />
      </div>
      <div className="clipping-container">
        <PortalExample />
      </div>
    </>
  );
}
```

### Pitfall

It’s important to make sure that your app is accessible when using portals. For instance, you may need to manage keyboard focus so that the user can move the focus in and out of the portal in a natural way.

Follow the [WAI-ARIA Modal Authoring Practices](https://www.w3.org/WAI/ARIA/apg/#dialog_modal) when creating modals. If you use a community package, ensure that it is accessible and follows these guidelines.

***

### Rendering React components into non-React server markup[](#rendering-react-components-into-non-react-server-markup "Link for Rendering React components into non-React server markup ")

Portals can be useful if your React root is only part of a static or server-rendered page that isn’t built with React. For example, if your page is built with a server framework like Rails, you can create areas of interactivity within static areas such as sidebars. Compared with having [multiple separate React roots,](/reference/react-dom/client/createRoot#rendering-a-page-partially-built-with-react) portals let you treat the app as a single React tree with shared state even though its parts render to different parts of the DOM.

```
import { createPortal } from 'react-dom';

const sidebarContentEl = document.getElementById('sidebar-content');

export default function App() {
  return (
    <>
      <MainContent />
      {createPortal(
        <SidebarContent />,
        sidebarContentEl
      )}
    </>
  );
}

function MainContent() {
  return <p>This part is rendered by React</p>;
}

function SidebarContent() {
  return <p>This part is also rendered by React!</p>;
}
```

***

### Rendering React components into non-React DOM nodes[](#rendering-react-components-into-non-react-dom-nodes "Link for Rendering React components into non-React DOM nodes ")

You can also use a portal to manage the content of a DOM node that’s managed outside of React. For example, suppose you’re integrating with a non-React map widget and you want to render React content inside a popup. To do this, declare a `popupContainer` state variable to store the DOM node you’re going to render into:

```
const [popupContainer, setPopupContainer] = useState(null);
```

When you create the third-party widget, store the DOM node returned by the widget so you can render into it:

```
useEffect(() => {

  if (mapRef.current === null) {

    const map = createMapWidget(containerRef.current);

    mapRef.current = map;

    const popupDiv = addPopupToMapWidget(map);

    setPopupContainer(popupDiv);

  }

}, []);
```

This lets you use `createPortal` to render React content into `popupContainer` once it becomes available:

```
return (

  <div style={{ width: 250, height: 250 }} ref={containerRef}>

    {popupContainer !== null && createPortal(

      <p>Hello from React!</p>,

      popupContainer

    )}

  </div>

);
```

Here is a complete example you can play with:

```
import { useRef, useEffect, useState } from 'react';
import { createPortal } from 'react-dom';
import { createMapWidget, addPopupToMapWidget } from './map-widget.js';

export default function Map() {
  const containerRef = useRef(null);
  const mapRef = useRef(null);
  const [popupContainer, setPopupContainer] = useState(null);

  useEffect(() => {
    if (mapRef.current === null) {
      const map = createMapWidget(containerRef.current);
      mapRef.current = map;
      const popupDiv = addPopupToMapWidget(map);
      setPopupContainer(popupDiv);
    }
  }, []);

  return (
    <div style={{ width: 250, height: 250 }} ref={containerRef}>
      {popupContainer !== null && createPortal(
        <p>Hello from React!</p>,
        popupContainer
      )}
    </div>
  );
}
```

[PreviousAPIs](/reference/react-dom)

[NextflushSync](/reference/react-dom/flushSync)

***

----
url: https://legacy.reactjs.org/blog/2014/05/06/flux.html
----

May 06, 2014 by [Bill Fisher](https://twitter.com/fisherwebdev) and [Jing Chen](https://twitter.com/jingc)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

We recently spoke at one of f8’s breakout session about Flux, a data flow architecture that works well with React. Check out the video here:

To summarize, Flux works well for us because the single directional data flow makes it easy to understand and modify an application as it becomes more complicated. We found that two-way data bindings lead to cascading updates, where changing one data model led to another data model updating, making it very difficult to predict what would change as the result of a single user interaction.

In Flux, the Dispatcher is a singleton that directs the flow of data and ensures that updates do not cascade. As an application grows, the Dispatcher becomes more vital, as it can also manage dependencies between stores by invoking the registered callbacks in a specific order.

When a user interacts with a React view, the view sends an action (usually represented as a JavaScript object with some fields) through the dispatcher, which notifies the various stores that hold the application’s data and business logic. When the stores change state, they notify the views that something has updated. This works especially well with React’s declarative model, which allows the stores to send updates without specifying how to transition views between states.

Flux is more of a pattern than a formal framework, so you can start using Flux immediately without a lot of new code. An [example of this architecture](https://github.com/facebook/flux/tree/master/examples/flux-todomvc) is available, along with more [detailed documentation](https://facebook.github.io/flux/docs/overview.html) and a [tutorial](https://github.com/facebook/flux/tree/main/examples/flux-todomvc). Look for more examples to come in the future.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2014-05-06-flux.md)

----
url: https://legacy.reactjs.org/blog/2014/02/05/community-roundup-15.html
----

February 05, 2014 by [Jonas Gebhardt](https://twitter.com/jonasgebhardt)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

Interest in React seems to have surged ever since David Nolen ([@swannodette](https://twitter.com/swannodette))‘s introduction of [Om](https://github.com/swannodette/om) in his post [“The Future of JavaScript MVC Frameworks”](https://swannodette.github.io/2013/12/17/the-future-of-javascript-mvcs/).

In this React Community Round-up, we are taking a closer look at React from a functional programming perspective.

## [](#react-another-level-of-indirection)“React: Another Level of Indirection”

To start things off, Eric Normand ([@ericnormand](https://twitter.com/ericnormand)) of [LispCast](http://lispcast.com) makes the case for [React from a general functional programming standpoint](http://www.lispcast.com/react-another-level-of-indirection) and explains how React’s “Virtual DOM provides the last piece of the Web Frontend Puzzle for ClojureScript”.

> The Virtual DOM is an indirection mechanism that solves the difficult problem of DOM programming: how to deal with incremental changes to a stateful tree structure. By abstracting away the statefulness, the Virtual DOM turns the real DOM into an immediate mode GUI, which is perfect for functional programming.
>
> [Read the full post…](http://www.lispcast.com/react-another-level-of-indirection)

## [](#reagent-minimalistic-react-for-clojurescript)Reagent: Minimalistic React for ClojureScript

Dan Holmsand ([@holmsand](https://twitter.com/holmsand)) created [Reagent](https://holmsand.github.io/reagent/), a simplistic ClojureScript API to React.

> It allows you to define efficient React components using nothing but plain ClojureScript functions and data, that describe your UI using a Hiccup-like syntax.
>
> The goal of Reagent is to make it possible to define arbitrarily complex UIs using just a couple of basic concepts, and to be fast enough by default that you rarely have to care about performance.
>
> [Check it out on GitHub…](https://holmsand.github.io/reagent/)

## [](#functional-dom-programming)Functional DOM programming

React’s one-way data-binding naturally lends itself to a functional programming approach. Facebook’s Pete Hunt ([@floydophone](https://twitter.com/floydophone)) explores how one would go about [writing web apps in a functional manner](https://medium.com/p/67d81637d43). Spoiler alert:

> This is React. It’s not about templates, or data binding, or DOM manipulation. It’s about using functional programming with a virtual DOM representation to build ambitious, high-performance apps with JavaScript.
>
> [Read the full post…](https://medium.com/p/67d81637d43)

Pete also explains this in detail at his #MeteorDevShop talk (about 30 Minutes):

## [](#kioo-separating-markup-and-logic)Kioo: Separating markup and logic

[Creighton Kirkendall](https://github.com/ckirkendall) created [Kioo](https://github.com/ckirkendall/kioo), which adds Enlive-style templating to React. HTML templates are separated from the application logic. Kioo comes with separate examples for both Om and Reagent.

A basic example from github:

```
<!DOCTYPE html>
<html lang="en">
  <body>
    <header>
      <h1>Header placeholder</h1>
      <ul id="navigation">
        <li class="nav-item"><a href="#">Placeholder</a></li>
      </ul>
    </header>
    <div class="content">place holder</div>
  </body>
</html>
```

```
...

(defn my-nav-item [[caption func]]
  (kioo/component "main.html" [:.nav-item]
    {[:a] (do-> (content caption)
                (set-attr :onClick func))}))

(defn my-header [heading nav-elms]
  (kioo/component "main.html" [:header]
    {[:h1] (content heading)
     [:ul] (content (map my-nav-item nav-elms))}))

(defn my-page [data]
  (kioo/component "main.html"
    {[:header] (substitute (my-header (:heading data)
                                      (:navigation data)))
     [:.content] (content (:content data))}))

(def app-state (atom {:heading    "main"
                      :content    "Hello World"
                      :navigation [["home" #(js/alert %)]
                                   ["next" #(js/alert %)]]}))

(om/root app-state my-page (.-body js/document))
```

## [](#om)Om

In an interview with David Nolen, Tom Coupland ([@tcoupland](https://twitter.com/tcoupland)) of InfoQ provides a nice summary of recent developments around Om (”[Om: Enhancing Facebook’s React with Immutability](http://www.infoq.com/news/2014/01/om-react)”).

> David \[Nolen]: I think people are starting to see the limitations of just JavaScript and jQuery and even more structured solutions like Backbone, Angular, Ember, etc. React is a fresh approach to the DOM problem that seems obvious in hindsight.
>
> [Read the full interview…](http://www.infoq.com/news/2014/01/om-react)

### [](#a-slice-of-react-clojurescript-and-om)A slice of React, ClojureScript and Om

Fredrik Dyrkell ([@lexicallyscoped](https://twitter.com/lexicallyscoped)) rewrote part of the [React tutorial in both ClojureScript and Om](http://www.lexicallyscoped.com/2013/12/25/slice-of-reactjs-and-cljs.html), along with short, helpful explanations.

> React has sparked a lot of interest in the Clojure community lately \[…]. At the very core, React lets you build up your DOM representation in a functional fashion by composing pure functions and you have a simple building block for everything: React components.
>
> [Read the full post…](http://www.lexicallyscoped.com/2013/12/25/slice-of-reactjs-and-cljs.html)

In a separate post, Dyrkell breaks down [how to build a binary clock component](http://www.lexicallyscoped.com/2014/01/23/ClojureScript-react-om-binary-clock.html) in Om.

\[[Demo](http://www.lexicallyscoped.com/demo/binclock/)] \[[Code](https://github.com/fredyr/binclock/blob/master/src/binclock/core.cljs)]

### [](#time-travel-implementing-undo-in-om)Time Travel: Implementing undo in Om

David Nolen shows how to leverage immutable data structures to [add global undo](https://swannodette.github.io/2013/12/31/time-travel/) functionality to an app – using just 13 lines of ClojureScript.

### [](#a-step-by-step-om-walkthrough)A Step-by-Step Om Walkthrough

[Josh Lehman](http://www.joshlehman.me) took the time to create an extensive [step-by-step walkthrough](http://www.joshlehman.me/rewriting-the-react-tutorial-in-om/) of the React tutorial in Om. The well-documented source is on [github](https://github.com/jalehman/omtut-starter).

### [](#omkara)Omkara

[brendanyounger](https://github.com/brendanyounger) created [omkara](https://github.com/brendanyounger/omkara), a starting point for ClojureScript web apps based on Om/React. It aims to take advantage of server-side rendering and comes with a few tips on getting started with Om/React projects.

### [](#om-experience-report)Om Experience Report

Adam Solove ([@asolove](https://twitter.com/asolove/)) [dives a little deeper into Om, React and ClojureScript](http://adamsolove.com/js/clojure/2014/01/06/om-experience-report.html). He shares some helpful tips he gathered while building his [CartoCrayon](https://github.com/asolove/carto-crayon) prototype.

## [](#not-so-random-tweet)Not-so-random Tweet

> \[@swannodette]\(https\://twitter.com/swannodette) No thank you! It's honestly a bit weird because Om is exactly what I didn't know I wanted for doing functional UI work.
>
> — Adam Solove (@asolove) [January 6, 2014](https://twitter.com/asolove/status/420294067637858304)

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2014-02-05-community-roundup-15.md)

----
url: https://react.dev/reference/react/Activity
----

[API Reference](/reference/react)

[Components](/reference/react/components)

# \<Activity>[](#undefined "Link for this heading")

`<Activity>` lets you hide and restore the UI and internal state of its children.

```
<Activity mode={visibility}>

  <Sidebar />

</Activity>
```

* [Reference](#reference)
  * [`<Activity>`](#activity)

* [Usage](#usage)

  * [Restoring the state of hidden components](#restoring-the-state-of-hidden-components)
  * [Restoring the DOM of hidden components](#restoring-the-dom-of-hidden-components)
  * [Pre-rendering content that’s likely to become visible](#pre-rendering-content-thats-likely-to-become-visible)
  * [Speeding up interactions during page load](#speeding-up-interactions-during-page-load)

* [Troubleshooting](#troubleshooting)

  * [My hidden components have unwanted side effects](#my-hidden-components-have-unwanted-side-effects)
  * [My hidden components have Effects that aren’t running](#my-hidden-components-have-effects-that-arent-running)

***

## Reference[](#reference "Link for Reference ")

### `<Activity>`[](#activity "Link for this heading")

You can use Activity to hide part of your application:

```
<Activity mode={isShowingSidebar ? "visible" : "hidden"}>

  <Sidebar />

</Activity>
```

When an Activity boundary is hidden, React will visually hide its children using the `display: "none"` CSS property. It will also destroy their Effects, cleaning up any active subscriptions.

While hidden, children still re-render in response to new props, albeit at a lower priority than the rest of the content.

When the boundary becomes visible again, React will reveal the children with their previous state restored, and re-create their Effects.

In this way, Activity can be thought of as a mechanism for rendering “background activity”. Rather than completely discarding content that’s likely to become visible again, you can use Activity to maintain and restore that content’s UI and internal state, while ensuring that your hidden content has no unwanted side effects.

[See more examples below.](#usage)

#### Props[](#props "Link for Props ")

* `children`: The UI you intend to show and hide.
* `mode`: A string value of either `'visible'` or `'hidden'`. If omitted, defaults to `'visible'`.

#### Caveats[](#caveats "Link for Caveats ")

* If an Activity is rendered inside of a [ViewTransition](/reference/react/ViewTransition), and it becomes visible as a result of an update caused by [startTransition](/reference/react/startTransition), it will activate the ViewTransition’s `enter` animation. If it becomes hidden, it will activate its `exit` animation.
* A *hidden* Activity that just renders text will not render anything rather than rendering hidden text, because there’s no corresponding DOM element to apply visibility changes to. For example, `<Activity mode="hidden"><ComponentThatJustReturnsText /></Activity>` will not produce any output in the DOM for `const ComponentThatJustReturnsText = () => "Hello, World!"`. `<Activity mode="visible"><ComponentThatJustReturnsText /></Activity>` will render visible text.

***

## Usage[](#usage "Link for Usage ")

### Restoring the state of hidden components[](#restoring-the-state-of-hidden-components "Link for Restoring the state of hidden components ")

In React, when you want to conditionally show or hide a component, you typically mount or unmount it based on that condition:

```
{isShowingSidebar && (

  <Sidebar />

)}
```

But unmounting a component destroys its internal state, which is not always what you want.

When you hide a component using an Activity boundary instead, React will “save” its state for later:

```
<Activity mode={isShowingSidebar ? "visible" : "hidden"}>

  <Sidebar />

</Activity>
```

This makes it possible to hide and then later restore components in the state they were previously in.

The following example has a sidebar with an expandable section. You can press “Overview” to reveal the three subitems below it. The main app area also has a button that hides and shows the sidebar.

Try expanding the Overview section, and then toggling the sidebar closed then open:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';
import Sidebar from './Sidebar.js';

export default function App() {
  const [isShowingSidebar, setIsShowingSidebar] = useState(true);

  return (
    <>
      {isShowingSidebar && (
        <Sidebar />
      )}

      <main>
        <button onClick={() => setIsShowingSidebar(!isShowingSidebar)}>
          Toggle sidebar
        </button>
        <h1>Main content</h1>
      </main>
    </>
  );
}
```

The Overview section always starts out collapsed. Because we unmount the sidebar when `isShowingSidebar` flips to `false`, all its internal state is lost.

This is a perfect use case for Activity. We can preserve the internal state of our sidebar, even when visually hiding it.

Let’s replace the conditional rendering of our sidebar with an Activity boundary:

```
// Before

{isShowingSidebar && (

  <Sidebar />

)}



// After

<Activity mode={isShowingSidebar ? 'visible' : 'hidden'}>

  <Sidebar />

</Activity>
```

and check out the new behavior:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { Activity, useState } from 'react';

import Sidebar from './Sidebar.js';

export default function App() {
  const [isShowingSidebar, setIsShowingSidebar] = useState(true);

  return (
    <>
      <Activity mode={isShowingSidebar ? 'visible' : 'hidden'}>
        <Sidebar />
      </Activity>

      <main>
        <button onClick={() => setIsShowingSidebar(!isShowingSidebar)}>
          Toggle sidebar
        </button>
        <h1>Main content</h1>
      </main>
    </>
  );
}
```

Our sidebar’s internal state is now restored, without any changes to its implementation.

***

### Restoring the DOM of hidden components[](#restoring-the-dom-of-hidden-components "Link for Restoring the DOM of hidden components ")

Since Activity boundaries hide their children using `display: none`, their children’s DOM is also preserved when hidden. This makes them great for maintaining ephemeral state in parts of the UI that the user is likely to interact with again.

In this example, the Contact tab has a `<textarea>` where the user can enter a message. If you enter some text, change to the Home tab, then change back to the Contact tab, the draft message is lost:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
export default function Contact() {
  return (
    <div>
      <p>Send me a message!</p>

      <textarea />

      <p>You can find me online here:</p>
      <ul>
        <li>admin@mysite.com</li>
        <li>+123456789</li>
      </ul>
    </div>
  );
}
```

This is because we’re fully unmounting `Contact` in `App`. When the Contact tab unmounts, the `<textarea>` element’s internal DOM state is lost.

If we switch to using an Activity boundary to show and hide the active tab, we can preserve the state of each tab’s DOM. Try entering text and switching tabs again, and you’ll see the draft message is no longer reset:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { Activity, useState } from 'react';
import TabButton from './TabButton.js';
import Home from './Home.js';
import Contact from './Contact.js';

export default function App() {
  const [activeTab, setActiveTab] = useState('contact');

  return (
    <>
      <TabButton
        isActive={activeTab === 'home'}
        onClick={() => setActiveTab('home')}
      >
        Home
      </TabButton>
      <TabButton
        isActive={activeTab === 'contact'}
        onClick={() => setActiveTab('contact')}
      >
        Contact
      </TabButton>

      <hr />

      <Activity mode={activeTab === 'home' ? 'visible' : 'hidden'}>
        <Home />
      </Activity>
      <Activity mode={activeTab === 'contact' ? 'visible' : 'hidden'}>
        <Contact />
      </Activity>
    </>
  );
}
```

Again, the Activity boundary let us preserve the Contact tab’s internal state without changing its implementation.

***

### Pre-rendering content that’s likely to become visible[](#pre-rendering-content-thats-likely-to-become-visible "Link for Pre-rendering content that’s likely to become visible ")

So far, we’ve seen how Activity can hide some content that the user has interacted with, without discarding that content’s ephemeral state.

But Activity boundaries can also be used to *prepare* content that the user has yet to see for the first time:

```
<Activity mode="hidden">

  <SlowComponent />

</Activity>
```

When an Activity boundary is hidden during its initial render, its children won’t be visible on the page — but they will *still be rendered*, albeit at a lower priority than the visible content, and without mounting their Effects.

This *pre-rendering* allows the children to load any code or data they need ahead of time, so that later, when the Activity boundary becomes visible, the children can appear faster with reduced loading times.

Let’s look at an example.

In this demo, the Posts tab loads some data. If you press it, you’ll see a Suspense fallback displayed while the data is being fetched:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, Suspense } from 'react';
import TabButton from './TabButton.js';
import Home from './Home.js';
import Posts from './Posts.js';

export default function App() {
  const [activeTab, setActiveTab] = useState('home');

  return (
    <>
      <TabButton
        isActive={activeTab === 'home'}
        onClick={() => setActiveTab('home')}
      >
        Home
      </TabButton>
      <TabButton
        isActive={activeTab === 'posts'}
        onClick={() => setActiveTab('posts')}
      >
        Posts
      </TabButton>

      <hr />

      <Suspense fallback={<h1>🌀 Loading...</h1>}>
        {activeTab === 'home' && <Home />}
        {activeTab === 'posts' && <Posts />}
      </Suspense>
    </>
  );
}
```

This is because `App` doesn’t mount `Posts` until its tab is active.

If we update `App` to use an Activity boundary to show and hide the active tab, `Posts` will be pre-rendered when the app first loads, allowing it to fetch its data before it becomes visible.

Try clicking the Posts tab now:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { Activity, useState, Suspense } from 'react';
import TabButton from './TabButton.js';
import Home from './Home.js';
import Posts from './Posts.js';

export default function App() {
  const [activeTab, setActiveTab] = useState('home');

  return (
    <>
      <TabButton
        isActive={activeTab === 'home'}
        onClick={() => setActiveTab('home')}
      >
        Home
      </TabButton>
      <TabButton
        isActive={activeTab === 'posts'}
        onClick={() => setActiveTab('posts')}
      >
        Posts
      </TabButton>

      <hr />

      <Suspense fallback={<h1>🌀 Loading...</h1>}>
        <Activity mode={activeTab === 'home' ? 'visible' : 'hidden'}>
          <Home />
        </Activity>
        <Activity mode={activeTab === 'posts' ? 'visible' : 'hidden'}>
          <Posts />
        </Activity>
      </Suspense>
    </>
  );
}
```

`Posts` was able to prepare itself for a faster render, thanks to the hidden Activity boundary.

***

Pre-rendering components with hidden Activity boundaries is a powerful way to reduce loading times for parts of the UI that the user is likely to interact with next.

### Note

**Only Suspense-enabled data sources will be fetched during pre-rendering.** They include:

* Data fetching with Suspense-enabled frameworks like [Relay](https://relay.dev/docs/guided-tour/rendering/loading-states/) and [Next.js](https://nextjs.org/docs/app/building-your-application/routing/loading-ui-and-streaming#streaming-with-suspense)
* Lazy-loading component code with [`lazy`](/reference/react/lazy)
* Reading the value of a cached Promise with [`use`](/reference/react/use)

Activity **does not** detect data that is fetched inside an Effect.

The exact way you would load data in the `Posts` component above depends on your framework. If you use a Suspense-enabled framework, you’ll find the details in its data fetching documentation.

Suspense-enabled data fetching without the use of an opinionated framework is not yet supported. The requirements for implementing a Suspense-enabled data source are unstable and undocumented. An official API for integrating data sources with Suspense will be released in a future version of React.

***

### Speeding up interactions during page load[](#speeding-up-interactions-during-page-load "Link for Speeding up interactions during page load ")

React includes an under-the-hood performance optimization called Selective Hydration. It works by hydrating your app’s initial HTML *in chunks*, enabling some components to become interactive even if other components on the page haven’t loaded their code or data yet.

Suspense boundaries participate in Selective Hydration, because they naturally divide your component tree into units that are independent from one another:

```
function Page() {

  return (

    <>

      <MessageComposer />



      <Suspense fallback="Loading chats...">

        <Chats />

      </Suspense>

    </>

  )

}
```

Here, `MessageComposer` can be fully hydrated during the initial render of the page, even before `Chats` is mounted and starts to fetch its data.

So by breaking up your component tree into discrete units, Suspense allows React to hydrate your app’s server-rendered HTML in chunks, enabling parts of your app to become interactive as fast as possible.

But what about pages that don’t use Suspense?

Take this tabs example:

```
function Page() {

  const [activeTab, setActiveTab] = useState('home');



  return (

    <>

      <TabButton onClick={() => setActiveTab('home')}>

        Home

      </TabButton>

      <TabButton onClick={() => setActiveTab('video')}>

        Video

      </TabButton>



      {activeTab === 'home' && (

        <Home />

      )}

      {activeTab === 'video' && (

        <Video />

      )}

    </>

  )

}
```

Here, React must hydrate the entire page all at once. If `Home` or `Video` are slower to render, they could make the tab buttons feel unresponsive during hydration.

Adding Suspense around the active tab would solve this:

```
function Page() {

  const [activeTab, setActiveTab] = useState('home');



  return (

    <>

      <TabButton onClick={() => setActiveTab('home')}>

        Home

      </TabButton>

      <TabButton onClick={() => setActiveTab('video')}>

        Video

      </TabButton>



      <Suspense fallback={<Placeholder />}>

        {activeTab === 'home' && (

          <Home />

        )}

        {activeTab === 'video' && (

          <Video />

        )}

      </Suspense>

    </>

  )

}
```

…but it would also change the UI, since the `Placeholder` fallback would be displayed on the initial render.

Instead, we can use Activity. Since Activity boundaries show and hide their children, they already naturally divide the component tree into independent units. And just like Suspense, this feature allows them to participate in Selective Hydration.

Let’s update our example to use Activity boundaries around the active tab:

```
function Page() {

  const [activeTab, setActiveTab] = useState('home');



  return (

    <>

      <TabButton onClick={() => setActiveTab('home')}>

        Home

      </TabButton>

      <TabButton onClick={() => setActiveTab('video')}>

        Video

      </TabButton>



      <Activity mode={activeTab === "home" ? "visible" : "hidden"}>

        <Home />

      </Activity>

      <Activity mode={activeTab === "video" ? "visible" : "hidden"}>

        <Video />

      </Activity>

    </>

  )

}
```

Now our initial server-rendered HTML looks the same as it did in the original version, but thanks to Activity, React can hydrate the tab buttons first, before it even mounts `Home` or `Video`.

***

Thus, in addition to hiding and showing content, Activity boundaries help improve your app’s performance during hydration by letting React know which parts of your page can become interactive in isolation.

And even if your page doesn’t ever hide part of its content, you can still add always-visible Activity boundaries to improve hydration performance:

```
function Page() {

  return (

    <>

      <Post />



      <Activity>

        <Comments />

      </Activity>

    </>

  );

}
```

***

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### My hidden components have unwanted side effects[](#my-hidden-components-have-unwanted-side-effects "Link for My hidden components have unwanted side effects ")

An Activity boundary hides its content by setting `display: none` on its children and cleaning up any of their Effects. So, most well-behaved React components that properly clean up their side effects will already be robust to being hidden by Activity.

But there *are* some situations where a hidden component behaves differently than an unmounted one. Most notably, since a hidden component’s DOM is not destroyed, any side effects from that DOM will persist, even after the component is hidden.

As an example, consider a `<video>` tag. Typically it doesn’t require any cleanup, because even if you’re playing a video, unmounting the tag stops the video and audio from playing in the browser. Try playing the video and then pressing Home in this demo:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';
import TabButton from './TabButton.js';
import Home from './Home.js';
import Video from './Video.js';

export default function App() {
  const [activeTab, setActiveTab] = useState('video');

  return (
    <>
      <TabButton
        isActive={activeTab === 'home'}
        onClick={() => setActiveTab('home')}
      >
        Home
      </TabButton>
      <TabButton
        isActive={activeTab === 'video'}
        onClick={() => setActiveTab('video')}
      >
        Video
      </TabButton>

      <hr />

      {activeTab === 'home' && <Home />}
      {activeTab === 'video' && <Video />}
    </>
  );
}
```

The video stops playing as expected.

Now, let’s say we wanted to preserve the timecode where the user last watched, so that when they tab back to the video, it doesn’t start over from the beginning again.

This is a great use case for Activity!

Let’s update `App` to hide the inactive tab with a hidden Activity boundary instead of unmounting it, and see how the demo behaves this time:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { Activity, useState } from 'react';
import TabButton from './TabButton.js';
import Home from './Home.js';
import Video from './Video.js';

export default function App() {
  const [activeTab, setActiveTab] = useState('video');

  return (
    <>
      <TabButton
        isActive={activeTab === 'home'}
        onClick={() => setActiveTab('home')}
      >
        Home
      </TabButton>
      <TabButton
        isActive={activeTab === 'video'}
        onClick={() => setActiveTab('video')}
      >
        Video
      </TabButton>

      <hr />

      <Activity mode={activeTab === 'home' ? 'visible' : 'hidden'}>
        <Home />
      </Activity>
      <Activity mode={activeTab === 'video' ? 'visible' : 'hidden'}>
        <Video />
      </Activity>
    </>
  );
}
```

Whoops! The video and audio continue to play even after it’s been hidden, because the tab’s `<video>` element is still in the DOM.

To fix this, we can add an Effect with a cleanup function that pauses the video:

```
export default function VideoTab() {

  const ref = useRef();



  useLayoutEffect(() => {

    const videoRef = ref.current;



    return () => {

      videoRef.pause()

    }

  }, []);



  return (

    <video

      ref={ref}

      controls

      playsInline

      src="..."

    />



  );

}
```

We call `useLayoutEffect` instead of `useEffect` because conceptually the clean-up code is tied to the component’s UI being visually hidden. If we used a regular effect, the code could be delayed by (say) a re-suspending Suspense boundary or a View Transition.

Let’s see the new behavior. Try playing the video, switching to the Home tab, then back to the Video tab:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { Activity, useState } from 'react';
import TabButton from './TabButton.js';
import Home from './Home.js';
import Video from './Video.js';

export default function App() {
  const [activeTab, setActiveTab] = useState('video');

  return (
    <>
      <TabButton
        isActive={activeTab === 'home'}
        onClick={() => setActiveTab('home')}
      >
        Home
      </TabButton>
      <TabButton
        isActive={activeTab === 'video'}
        onClick={() => setActiveTab('video')}
      >
        Video
      </TabButton>

      <hr />

      <Activity mode={activeTab === 'home' ? 'visible' : 'hidden'}>
        <Home />
      </Activity>
      <Activity mode={activeTab === 'video' ? 'visible' : 'hidden'}>
        <Video />
      </Activity>
    </>
  );
}
```

It works great! Our cleanup function ensures that the video stops playing if it’s ever hidden by an Activity boundary, and even better, because the `<video>` tag is never destroyed, the timecode is preserved, and the video itself doesn’t need to be initialized or downloaded again when the user switches back to keep watching it.

This is a great example of using Activity to preserve ephemeral DOM state for parts of the UI that become hidden, but the user is likely to interact with again soon.

***

Our example illustrates that for certain tags like `<video>`, unmounting and hiding have different behavior. If a component renders DOM that has a side effect, and you want to prevent that side effect when an Activity boundary hides it, add an Effect with a return function to clean it up.

The most common cases of this will be from the following tags:

* `<video>`
* `<audio>`
* `<iframe>`

Typically, though, most of your React components should already be robust to being hidden by an Activity boundary. And conceptually, you should think of “hidden” Activities as being unmounted.

To eagerly discover other Effects that don’t have proper cleanup, which is important not only for Activity boundaries but for many other behaviors in React, we recommend using [`<StrictMode>`](/reference/react/StrictMode).

***

### My hidden components have Effects that aren’t running[](#my-hidden-components-have-effects-that-arent-running "Link for My hidden components have Effects that aren’t running ")

When an `<Activity>` is “hidden”, all its children’s Effects are cleaned up. Conceptually, the children are unmounted, but React saves their state for later. This is a feature of Activity because it means subscriptions won’t be active for hidden parts of the UI, reducing the amount of work needed for hidden content.

If you’re relying on an Effect mounting to clean up a component’s side effects, refactor the Effect to do the work in the returned cleanup function instead.

To eagerly find problematic Effects, we recommend adding [`<StrictMode>`](/reference/react/StrictMode) which will eagerly perform Activity unmounts and mounts to catch any unexpected side-effects.

[Previous\<Suspense>](/reference/react/Suspense)

[Next\<ViewTransition>](/reference/react/ViewTransition)

***

----
url: https://react.dev/reference/eslint-plugin-react-hooks/lints/globals
----

[API Reference](/reference/react)

[Lints](/reference/eslint-plugin-react-hooks)

# globals[](#undefined "Link for this heading")

Validates against assignment/mutation of globals during render, part of ensuring that [side effects must run outside of render](/reference/rules/components-and-hooks-must-be-pure#side-effects-must-run-outside-of-render).

## Rule Details[](#rule-details "Link for Rule Details ")

Global variables exist outside React’s control. When you modify them during render, you break React’s assumption that rendering is pure. This can cause components to behave differently in development vs production, break Fast Refresh, and make your app impossible to optimize with features like React Compiler.

### Invalid[](#invalid "Link for Invalid ")

Examples of incorrect code for this rule:

```
// ❌ Global counter

let renderCount = 0;

function Component() {

  renderCount++; // Mutating global

  return <div>Count: {renderCount}</div>;

}



// ❌ Modifying window properties

function Component({userId}) {

  window.currentUser = userId; // Global mutation

  return <div>User: {userId}</div>;

}



// ❌ Global array push

const events = [];

function Component({event}) {

  events.push(event); // Mutating global array

  return <div>Events: {events.length}</div>;

}



// ❌ Cache manipulation

const cache = {};

function Component({id}) {

  if (!cache[id]) {

    cache[id] = fetchData(id); // Modifying cache during render

  }

  return <div>{cache[id]}</div>;

}
```

### Valid[](#valid "Link for Valid ")

Examples of correct code for this rule:

```
// ✅ Use state for counters

function Component() {

  const [clickCount, setClickCount] = useState(0);



  const handleClick = () => {

    setClickCount(c => c + 1);

  };



  return (

    <button onClick={handleClick}>

      Clicked: {clickCount} times

    </button>

  );

}



// ✅ Use context for global values

function Component() {

  const user = useContext(UserContext);

  return <div>User: {user.id}</div>;

}



// ✅ Synchronize external state with React

function Component({title}) {

  useEffect(() => {

    document.title = title; // OK in effect

  }, [title]);



  return <div>Page: {title}</div>;

}
```

[Previousgating](/reference/eslint-plugin-react-hooks/lints/gating)

[Nextimmutability](/reference/eslint-plugin-react-hooks/lints/immutability)

***

----
url: https://18.react.dev/learn/separating-events-from-effects
----

```
function ChatRoom({ roomId }) {

  const [message, setMessage] = useState('');

  // ...

  function handleSendClick() {

    sendMessage(message);

  }

  // ...

  return (

    <>

      <input value={message} onChange={e => setMessage(e.target.value)} />

      <button onClick={handleSendClick}>Send</button>

    </>

  );

}
```

With an event handler, you can be sure that `sendMessage(message)` will *only* run if the user presses the button.

### Effects run whenever synchronization is needed[](#effects-run-whenever-synchronization-is-needed "Link for Effects run whenever synchronization is needed ")

Recall that you also need to keep the component connected to the chat room. Where does that code go?

The *reason* to run this code is not some particular interaction. It doesn’t matter why or how the user navigated to the chat room screen. Now that they’re looking at it and could interact with it, the component needs to stay connected to the selected chat server. Even if the chat room component was the initial screen of your app, and the user has not performed any interactions at all, you would *still* need to connect. This is why it’s an Effect:

```
function ChatRoom({ roomId }) {

  // ...

  useEffect(() => {

    const connection = createConnection(serverUrl, roomId);

    connection.connect();

    return () => {

      connection.disconnect();

    };

  }, [roomId]);

  // ...

}
```

With this code, you can be sure that there is always an active connection to the currently selected chat server, *regardless* of the specific interactions performed by the user. Whether the user has only opened your app, selected a different room, or navigated to another screen and back, your Effect ensures that the component will *remain synchronized* with the currently selected room, and will [re-connect whenever it’s necessary.](/learn/lifecycle-of-reactive-effects#why-synchronization-may-need-to-happen-more-than-once)

```
import { useState, useEffect } from 'react';
import { createConnection, sendMessage } from './chat.js';

const serverUrl = 'https://localhost:1234';

function ChatRoom({ roomId }) {
  const [message, setMessage] = useState('');

  useEffect(() => {
    const connection = createConnection(serverUrl, roomId);
    connection.connect();
    return () => connection.disconnect();
  }, [roomId]);

  function handleSendClick() {
    sendMessage(message);
  }

  return (
    <>
      <h1>Welcome to the {roomId} room!</h1>
      <input value={message} onChange={e => setMessage(e.target.value)} />
      <button onClick={handleSendClick}>Send</button>
    </>
  );
}

export default function App() {
  const [roomId, setRoomId] = useState('general');
  const [show, setShow] = useState(false);
  return (
    <>
      <label>
        Choose the chat room:{' '}
        <select
          value={roomId}
          onChange={e => setRoomId(e.target.value)}
        >
          <option value="general">general</option>
          <option value="travel">travel</option>
          <option value="music">music</option>
        </select>
      </label>
      <button onClick={() => setShow(!show)}>
        {show ? 'Close chat' : 'Open chat'}
      </button>
      {show && <hr />}
      {show && <ChatRoom roomId={roomId} />}
    </>
  );
}
```

## Reactive values and reactive logic[](#reactive-values-and-reactive-logic "Link for Reactive values and reactive logic ")

Intuitively, you could say that event handlers are always triggered “manually”, for example by clicking a button. Effects, on the other hand, are “automatic”: they run and re-run as often as it’s needed to stay synchronized.

There is a more precise way to think about this.

Props, state, and variables declared inside your component’s body are called reactive values. In this example, `serverUrl` is not a reactive value, but `roomId` and `message` are. They participate in the rendering data flow:

```
const serverUrl = 'https://localhost:1234';



function ChatRoom({ roomId }) {

  const [message, setMessage] = useState('');



  // ...

}
```

Reactive values like these can change due to a re-render. For example, the user may edit the `message` or choose a different `roomId` in a dropdown. Event handlers and Effects respond to changes differently:

* **Logic inside event handlers is *not reactive.*** It will not run again unless the user performs the same interaction (e.g. a click) again. Event handlers can read reactive values without “reacting” to their changes.
* **Logic inside Effects is *reactive.*** If your Effect reads a reactive value, [you have to specify it as a dependency.](/learn/lifecycle-of-reactive-effects#effects-react-to-reactive-values) Then, if a re-render causes that value to change, React will re-run your Effect’s logic with the new value.

Let’s revisit the previous example to illustrate this difference.

### Logic inside event handlers is not reactive[](#logic-inside-event-handlers-is-not-reactive "Link for Logic inside event handlers is not reactive ")

Take a look at this line of code. Should this logic be reactive or not?

```
    // ...

    sendMessage(message);

    // ...
```

From the user’s perspective, **a change to the `message` does *not* mean that they want to send a message.** It only means that the user is typing. In other words, the logic that sends a message should not be reactive. It should not run again only because the reactive value has changed. That’s why it belongs in the event handler:

```
  function handleSendClick() {

    sendMessage(message);

  }
```

Event handlers aren’t reactive, so `sendMessage(message)` will only run when the user clicks the Send button.

### Logic inside Effects is reactive[](#logic-inside-effects-is-reactive "Link for Logic inside Effects is reactive ")

Now let’s return to these lines:

```
    // ...

    const connection = createConnection(serverUrl, roomId);

    connection.connect();

    // ...
```

From the user’s perspective, **a change to the `roomId` *does* mean that they want to connect to a different room.** In other words, the logic for connecting to the room should be reactive. You *want* these lines of code to “keep up” with the reactive value, and to run again if that value is different. That’s why it belongs in an Effect:

```
  useEffect(() => {

    const connection = createConnection(serverUrl, roomId);

    connection.connect();

    return () => {

      connection.disconnect()

    };

  }, [roomId]);
```

Effects are reactive, so `createConnection(serverUrl, roomId)` and `connection.connect()` will run for every distinct value of `roomId`. Your Effect keeps the chat connection synchronized to the currently selected room.

## Extracting non-reactive logic out of Effects[](#extracting-non-reactive-logic-out-of-effects "Link for Extracting non-reactive logic out of Effects ")

Things get more tricky when you want to mix reactive logic with non-reactive logic.

For example, imagine that you want to show a notification when the user connects to the chat. You read the current theme (dark or light) from the props so that you can show the notification in the correct color:

```
function ChatRoom({ roomId, theme }) {

  useEffect(() => {

    const connection = createConnection(serverUrl, roomId);

    connection.on('connected', () => {

      showNotification('Connected!', theme);

    });

    connection.connect();

    // ...
```

However, `theme` is a reactive value (it can change as a result of re-rendering), and [every reactive value read by an Effect must be declared as its dependency.](/learn/lifecycle-of-reactive-effects#react-verifies-that-you-specified-every-reactive-value-as-a-dependency) Now you have to specify `theme` as a dependency of your Effect:

```
function ChatRoom({ roomId, theme }) {

  useEffect(() => {

    const connection = createConnection(serverUrl, roomId);

    connection.on('connected', () => {

      showNotification('Connected!', theme);

    });

    connection.connect();

    return () => {

      connection.disconnect()

    };

  }, [roomId, theme]); // ✅ All dependencies declared

  // ...
```

Play with this example and see if you can spot the problem with this user experience:

```
import { useState, useEffect } from 'react';
import { createConnection, sendMessage } from './chat.js';
import { showNotification } from './notifications.js';

const serverUrl = 'https://localhost:1234';

function ChatRoom({ roomId, theme }) {
  useEffect(() => {
    const connection = createConnection(serverUrl, roomId);
    connection.on('connected', () => {
      showNotification('Connected!', theme);
    });
    connection.connect();
    return () => connection.disconnect();
  }, [roomId, theme]);

  return <h1>Welcome to the {roomId} room!</h1>
}

export default function App() {
  const [roomId, setRoomId] = useState('general');
  const [isDark, setIsDark] = useState(false);
  return (
    <>
      <label>
        Choose the chat room:{' '}
        <select
          value={roomId}
          onChange={e => setRoomId(e.target.value)}
        >
          <option value="general">general</option>
          <option value="travel">travel</option>
          <option value="music">music</option>
        </select>
      </label>
      <label>
        <input
          type="checkbox"
          checked={isDark}
          onChange={e => setIsDark(e.target.checked)}
        />
        Use dark theme
      </label>
      <hr />
      <ChatRoom
        roomId={roomId}
        theme={isDark ? 'dark' : 'light'}
      />
    </>
  );
}
```

When the `roomId` changes, the chat re-connects as you would expect. But since `theme` is also a dependency, the chat *also* re-connects every time you switch between the dark and the light theme. That’s not great!

In other words, you *don’t* want this line to be reactive, even though it is inside an Effect (which is reactive):

```
      // ...

      showNotification('Connected!', theme);

      // ...
```

You need a way to separate this non-reactive logic from the reactive Effect around it.

### Declaring an Effect Event[](#declaring-an-effect-event "Link for Declaring an Effect Event ")

### Under Construction

This section describes an **experimental API that has not yet been released** in a stable version of React.

Use a special Hook called [`useEffectEvent`](/reference/react/experimental_useEffectEvent) to extract this non-reactive logic out of your Effect:

```
import { useEffect, useEffectEvent } from 'react';



function ChatRoom({ roomId, theme }) {

  const onConnected = useEffectEvent(() => {

    showNotification('Connected!', theme);

  });

  // ...
```

Here, `onConnected` is called an *Effect Event.* It’s a part of your Effect logic, but it behaves a lot more like an event handler. The logic inside it is not reactive, and it always “sees” the latest values of your props and state.

Now you can call the `onConnected` Effect Event from inside your Effect:

```
function ChatRoom({ roomId, theme }) {

  const onConnected = useEffectEvent(() => {

    showNotification('Connected!', theme);

  });



  useEffect(() => {

    const connection = createConnection(serverUrl, roomId);

    connection.on('connected', () => {

      onConnected();

    });

    connection.connect();

    return () => connection.disconnect();

  }, [roomId]); // ✅ All dependencies declared

  // ...
```

This solves the problem. Note that you had to *remove* `onConnected` from the list of your Effect’s dependencies. **Effect Events are not reactive and must be omitted from dependencies.**

Verify that the new behavior works as you would expect:

```
import { useState, useEffect } from 'react';
import { experimental_useEffectEvent as useEffectEvent } from 'react';
import { createConnection, sendMessage } from './chat.js';
import { showNotification } from './notifications.js';

const serverUrl = 'https://localhost:1234';

function ChatRoom({ roomId, theme }) {
  const onConnected = useEffectEvent(() => {
    showNotification('Connected!', theme);
  });

  useEffect(() => {
    const connection = createConnection(serverUrl, roomId);
    connection.on('connected', () => {
      onConnected();
    });
    connection.connect();
    return () => connection.disconnect();
  }, [roomId]);

  return <h1>Welcome to the {roomId} room!</h1>
}

export default function App() {
  const [roomId, setRoomId] = useState('general');
  const [isDark, setIsDark] = useState(false);
  return (
    <>
      <label>
        Choose the chat room:{' '}
        <select
          value={roomId}
          onChange={e => setRoomId(e.target.value)}
        >
          <option value="general">general</option>
          <option value="travel">travel</option>
          <option value="music">music</option>
        </select>
      </label>
      <label>
        <input
          type="checkbox"
          checked={isDark}
          onChange={e => setIsDark(e.target.checked)}
        />
        Use dark theme
      </label>
      <hr />
      <ChatRoom
        roomId={roomId}
        theme={isDark ? 'dark' : 'light'}
      />
    </>
  );
}
```

You can think of Effect Events as being very similar to event handlers. The main difference is that event handlers run in response to a user interactions, whereas Effect Events are triggered by you from Effects. Effect Events let you “break the chain” between the reactivity of Effects and code that should not be reactive.

### Reading latest props and state with Effect Events[](#reading-latest-props-and-state-with-effect-events "Link for Reading latest props and state with Effect Events ")

### Under Construction

This section describes an **experimental API that has not yet been released** in a stable version of React.

Effect Events let you fix many patterns where you might be tempted to suppress the dependency linter.

For example, say you have an Effect to log the page visits:

```
function Page() {

  useEffect(() => {

    logVisit();

  }, []);

  // ...

}
```

Later, you add multiple routes to your site. Now your `Page` component receives a `url` prop with the current path. You want to pass the `url` as a part of your `logVisit` call, but the dependency linter complains:

```
function Page({ url }) {

  useEffect(() => {

    logVisit(url);

  }, []); // 🔴 React Hook useEffect has a missing dependency: 'url'

  // ...

}
```

Think about what you want the code to do. You *want* to log a separate visit for different URLs since each URL represents a different page. In other words, this `logVisit` call *should* be reactive with respect to the `url`. This is why, in this case, it makes sense to follow the dependency linter, and add `url` as a dependency:

```
function Page({ url }) {

  useEffect(() => {

    logVisit(url);

  }, [url]); // ✅ All dependencies declared

  // ...

}
```

Now let’s say you want to include the number of items in the shopping cart together with every page visit:

```
function Page({ url }) {

  const { items } = useContext(ShoppingCartContext);

  const numberOfItems = items.length;



  useEffect(() => {

    logVisit(url, numberOfItems);

  }, [url]); // 🔴 React Hook useEffect has a missing dependency: 'numberOfItems'

  // ...

}
```

You used `numberOfItems` inside the Effect, so the linter asks you to add it as a dependency. However, you *don’t* want the `logVisit` call to be reactive with respect to `numberOfItems`. If the user puts something into the shopping cart, and the `numberOfItems` changes, this *does not mean* that the user visited the page again. In other words, *visiting the page* is, in some sense, an “event”. It happens at a precise moment in time.

Split the code in two parts:

```
function Page({ url }) {

  const { items } = useContext(ShoppingCartContext);

  const numberOfItems = items.length;



  const onVisit = useEffectEvent(visitedUrl => {

    logVisit(visitedUrl, numberOfItems);

  });



  useEffect(() => {

    onVisit(url);

  }, [url]); // ✅ All dependencies declared

  // ...

}
```

Here, `onVisit` is an Effect Event. The code inside it isn’t reactive. This is why you can use `numberOfItems` (or any other reactive value!) without worrying that it will cause the surrounding code to re-execute on changes.

On the other hand, the Effect itself remains reactive. Code inside the Effect uses the `url` prop, so the Effect will re-run after every re-render with a different `url`. This, in turn, will call the `onVisit` Effect Event.

As a result, you will call `logVisit` for every change to the `url`, and always read the latest `numberOfItems`. However, if `numberOfItems` changes on its own, this will not cause any of the code to re-run.

### Note

You might be wondering if you could call `onVisit()` with no arguments, and read the `url` inside it:

```
  const onVisit = useEffectEvent(() => {

    logVisit(url, numberOfItems);

  });



  useEffect(() => {

    onVisit();

  }, [url]);
```

This would work, but it’s better to pass this `url` to the Effect Event explicitly. **By passing `url` as an argument to your Effect Event, you are saying that visiting a page with a different `url` constitutes a separate “event” from the user’s perspective.** The `visitedUrl` is a *part* of the “event” that happened:

```
  const onVisit = useEffectEvent(visitedUrl => {

    logVisit(visitedUrl, numberOfItems);

  });



  useEffect(() => {

    onVisit(url);

  }, [url]);
```

Since your Effect Event explicitly “asks” for the `visitedUrl`, now you can’t accidentally remove `url` from the Effect’s dependencies. If you remove the `url` dependency (causing distinct page visits to be counted as one), the linter will warn you about it. You want `onVisit` to be reactive with regards to the `url`, so instead of reading the `url` inside (where it wouldn’t be reactive), you pass it *from* your Effect.

This becomes especially important if there is some asynchronous logic inside the Effect:

```
  const onVisit = useEffectEvent(visitedUrl => {

    logVisit(visitedUrl, numberOfItems);

  });



  useEffect(() => {

    setTimeout(() => {

      onVisit(url);

    }, 5000); // Delay logging visits

  }, [url]);
```

Here, `url` inside `onVisit` corresponds to the *latest* `url` (which could have already changed), but `visitedUrl` corresponds to the `url` that originally caused this Effect (and this `onVisit` call) to run.

##### Deep Dive#### Is it okay to suppress the dependency linter instead?[](#is-it-okay-to-suppress-the-dependency-linter-instead "Link for Is it okay to suppress the dependency linter instead? ")

In the existing codebases, you may sometimes see the lint rule suppressed like this:

```
function Page({ url }) {

  const { items } = useContext(ShoppingCartContext);

  const numberOfItems = items.length;



  useEffect(() => {

    logVisit(url, numberOfItems);

    // 🔴 Avoid suppressing the linter like this:

    // eslint-disable-next-line react-hooks/exhaustive-deps

  }, [url]);

  // ...

}
```

After `useEffectEvent` becomes a stable part of React, we recommend **never suppressing the linter**.

The first downside of suppressing the rule is that React will no longer warn you when your Effect needs to “react” to a new reactive dependency you’ve introduced to your code. In the earlier example, you added `url` to the dependencies *because* React reminded you to do it. You will no longer get such reminders for any future edits to that Effect if you disable the linter. This leads to bugs.

Here is an example of a confusing bug caused by suppressing the linter. In this example, the `handleMove` function is supposed to read the current `canMove` state variable value in order to decide whether the dot should follow the cursor. However, `canMove` is always `true` inside `handleMove`.

Can you see why?

```
import { useState, useEffect } from 'react';

export default function App() {
  const [position, setPosition] = useState({ x: 0, y: 0 });
  const [canMove, setCanMove] = useState(true);

  function handleMove(e) {
    if (canMove) {
      setPosition({ x: e.clientX, y: e.clientY });
    }
  }

  useEffect(() => {
    window.addEventListener('pointermove', handleMove);
    return () => window.removeEventListener('pointermove', handleMove);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  return (
    <>
      <label>
        <input type="checkbox"
          checked={canMove}
          onChange={e => setCanMove(e.target.checked)}
        />
        The dot is allowed to move
      </label>
      <hr />
      <div style={{
        position: 'absolute',
        backgroundColor: 'pink',
        borderRadius: '50%',
        opacity: 0.6,
        transform: `translate(${position.x}px, ${position.y}px)`,
        pointerEvents: 'none',
        left: -20,
        top: -20,
        width: 40,
        height: 40,
      }} />
    </>
  );
}
```

The problem with this code is in suppressing the dependency linter. If you remove the suppression, you’ll see that this Effect should depend on the `handleMove` function. This makes sense: `handleMove` is declared inside the component body, which makes it a reactive value. Every reactive value must be specified as a dependency, or it can potentially get stale over time!

The author of the original code has “lied” to React by saying that the Effect does not depend (`[]`) on any reactive values. This is why React did not re-synchronize the Effect after `canMove` has changed (and `handleMove` with it). Because React did not re-synchronize the Effect, the `handleMove` attached as a listener is the `handleMove` function created during the initial render. During the initial render, `canMove` was `true`, which is why `handleMove` from the initial render will forever see that value.

**If you never suppress the linter, you will never see problems with stale values.**

With `useEffectEvent`, there is no need to “lie” to the linter, and the code works as you would expect:

```
import { useState, useEffect } from 'react';
import { experimental_useEffectEvent as useEffectEvent } from 'react';

export default function App() {
  const [position, setPosition] = useState({ x: 0, y: 0 });
  const [canMove, setCanMove] = useState(true);

  const onMove = useEffectEvent(e => {
    if (canMove) {
      setPosition({ x: e.clientX, y: e.clientY });
    }
  });

  useEffect(() => {
    window.addEventListener('pointermove', onMove);
    return () => window.removeEventListener('pointermove', onMove);
  }, []);

  return (
    <>
      <label>
        <input type="checkbox"
          checked={canMove}
          onChange={e => setCanMove(e.target.checked)}
        />
        The dot is allowed to move
      </label>
      <hr />
      <div style={{
        position: 'absolute',
        backgroundColor: 'pink',
        borderRadius: '50%',
        opacity: 0.6,
        transform: `translate(${position.x}px, ${position.y}px)`,
        pointerEvents: 'none',
        left: -20,
        top: -20,
        width: 40,
        height: 40,
      }} />
    </>
  );
}
```

This doesn’t mean that `useEffectEvent` is *always* the correct solution. You should only apply it to the lines of code that you don’t want to be reactive. In the above sandbox, you didn’t want the Effect’s code to be reactive with regards to `canMove`. That’s why it made sense to extract an Effect Event.

Read [Removing Effect Dependencies](/learn/removing-effect-dependencies) for other correct alternatives to suppressing the linter.

### Limitations of Effect Events[](#limitations-of-effect-events "Link for Limitations of Effect Events ")

### Under Construction

This section describes an **experimental API that has not yet been released** in a stable version of React.

Effect Events are very limited in how you can use them:

* **Only call them from inside Effects.**
* **Never pass them to other components or Hooks.**

For example, don’t declare and pass an Effect Event like this:

```
function Timer() {

  const [count, setCount] = useState(0);



  const onTick = useEffectEvent(() => {

    setCount(count + 1);

  });



  useTimer(onTick, 1000); // 🔴 Avoid: Passing Effect Events



  return <h1>{count}</h1>

}



function useTimer(callback, delay) {

  useEffect(() => {

    const id = setInterval(() => {

      callback();

    }, delay);

    return () => {

      clearInterval(id);

    };

  }, [delay, callback]); // Need to specify "callback" in dependencies

}
```

Instead, always declare Effect Events directly next to the Effects that use them:

```
function Timer() {

  const [count, setCount] = useState(0);

  useTimer(() => {

    setCount(count + 1);

  }, 1000);

  return <h1>{count}</h1>

}



function useTimer(callback, delay) {

  const onTick = useEffectEvent(() => {

    callback();

  });



  useEffect(() => {

    const id = setInterval(() => {

      onTick(); // ✅ Good: Only called locally inside an Effect

    }, delay);

    return () => {

      clearInterval(id);

    };

  }, [delay]); // No need to specify "onTick" (an Effect Event) as a dependency

}
```

```
import { useState, useEffect } from 'react';

export default function Timer() {
  const [count, setCount] = useState(0);
  const [increment, setIncrement] = useState(1);

  useEffect(() => {
    const id = setInterval(() => {
      setCount(c => c + increment);
    }, 1000);
    return () => {
      clearInterval(id);
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  return (
    <>
      <h1>
        Counter: {count}
        <button onClick={() => setCount(0)}>Reset</button>
      </h1>
      <hr />
      <p>
        Every second, increment by:
        <button disabled={increment === 0} onClick={() => {
          setIncrement(i => i - 1);
        }}>–</button>
        <b>{increment}</b>
        <button onClick={() => {
          setIncrement(i => i + 1);
        }}>+</button>
      </p>
    </>
  );
}
```

[PreviousLifecycle of Reactive Effects](/learn/lifecycle-of-reactive-effects)

[NextRemoving Effect Dependencies](/learn/removing-effect-dependencies)

***

----
url: https://legacy.reactjs.org/blog/2016/08/05/relay-state-of-the-state.html
----

August 05, 2016 by [Joseph Savona](https://twitter.com/en_JS)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

This month marks a year since we released Relay and we’d like to share an update on the project and what’s next.

## [](#a-year-in-review)A Year In Review

A year after launch, we’re incredibly excited to see an active community forming around Relay and that companies such as Twitter are [using Relay in production](https://fabric.io/blog/building-fabric-mission-control-with-graphql-and-relay):

> For a project like mission control, GraphQL and Relay were a near-perfect solution, and the cost of building it any other way justified the investment.
>
> — Fin Hopkins

This kind of positive feedback is really encouraging (I’ll admit to re-reading that post far too many times), and great motivation for us to keep going and make Relay even better.

With the community’s help we’ve already come a long way since the technical preview. Here are some highlights:

* In March we added support for server-side rendering and for creating multiple instances of Relay on a single page. This was a coordinated effort over the course of several months by community members [Denis Nedelyaev](https://github.com/denvned) and [Gerald Monaco](https://github.com/devknoll) (now at Facebook).
* Also in March we added support for React Native. While we use Relay and React Native together internally, they didn’t quite work together in open-source out of the box. We owe a big thanks to [Adam Miskiewicz](https://github.com/skevy), [Tom Burns](https://github.com/boourns), [Gaëtan Renaudeau](https://github.com/gre), [David Aurelio](https://github.com/davidaurelio), [Martín Bigio](https://github.com/martinbigio), [Paul O’Shannessy](https://github.com/zpao), [Sophie Alpert](https://github.com/sophiebits), and many others who helped track down and resolve issues. Finally, thanks to [Steven Luscher](https://github.com/steveluscher) for coordinating this effort and building the first Relay/ReactNative example app.

We’ve also seen some great open-source projects spring up around Relay:

* [Denis Nedelyaev](https://github.com/denvned) created [isomorphic-relay](https://github.com/denvned/isomorphic-relay/), a package that helps developers build server-rendered Relay apps where data is prepared on the server and then used to bootstrap the app on the client.
* [Jimmy Jia](https://github.com/taion) created [react-router-relay](https://github.com/relay-tools/react-router-relay) to integrate Relay data-fetching into React Router.
* [Pavel Chertorogov](https://github.com/nodkz) released [relay-network-layer](https://github.com/nodkz/react-relay-network-layer), which adds features such as batching query requests, middleware, authentication, logging, and more.

This is just a small sampling of the community’s contributions. So far we’ve merged over 300 PRs - about 25% of our commits - from over 80 of you. These PRs have improved everything from the website and docs down the very core of the framework. We’re humbled by these outstanding contributions and excited to keep working with each of you!

# [](#retrospective--roadmap)Retrospective & Roadmap

Earlier this year we paused to reflect on the state of the project. What was working well? What could be improved? What features should we add, and what could we remove? A few themes emerged: performance on mobile, developer experience, and empowering the community.

## [](#mobile-perf)Mobile Perf

First, Relay was built to serve the needs of product developers at Facebook. In 2016, that means helping developers to build apps that work well on [mobile devices connecting on slower networks](https://newsroom.fb.com/news/2015/10/news-feed-fyi-building-for-all-connectivity/). For example, people in developing markets commonly use [2011 year-class phones](https://code.facebook.com/posts/307478339448736/year-class-a-classification-system-for-android/) and connect via [2G class networks](https://code.facebook.com/posts/952628711437136/classes-performance-and-network-segmentation-on-android/). These scenarios present their own challenges.

Therefore, one of our primary goals this year is to optimize Relay for performance on low-end mobile devices *first*, knowing that this can translate to improved performance on high-end devices as well. In addition to standard approaches such as benchmarking, profiling, and optimizations, we’re also working on big-picture changes.

For example, in today’s Relay, here’s what happens when an app is opened. First, React Native starts initializing the JavaScript context (loading and parsing your code and then running it). When this finishes, the app executes and Relay sees that you need data. It constructs and prints the query, uploads the query text to the server, processes the response, and renders your app. (Note that this process applies on the web, except that the code has to be *downloaded* instead of loaded from the device.)

Ideally, though, we could begin fetching data as soon as the native code had loaded - in parallel with the JS context initialization. By the time your JS code was ready to run, the data-fetching would already be under way. To do this we would need a way to determine *statically* - at build time - what query an application would send.

The key is that GraphQL is already static - we just need to fully embrace this fact. More on this later.

## [](#developer-experience)Developer Experience

Next, we’ve paid attention to the community’s feedback and know that, to put it simply, Relay could be “easier” to use (and “simpler” too). This isn’t entirely surprising to us - Relay was originally designed as a routing library and gradually morphed into a data-fetching library. Concepts like Relay “routes”, for example, no longer serve as critical a role and are just one more concept that developers have to learn about. Another example is mutations: while writes *are* inherently more complex than reads, our API doesn’t make the simple things simple enough.

Alongside our focus on mobile performance, we’ve also kept the developer experience in mind as we evolve Relay core.

## [](#empowering-the-community)Empowering the Community

Finally, we want to make it easier for people in the community to develop useful libraries that work with Relay. By comparison, React’s small surface area - components - allows developers to build cool things like routing, higher-order components, or reusable text editors. For Relay, this would mean having the framework provide core primitives that users can build upon. We want it to be possible for the community to integrate Relay with view libraries other than React, or to build real-time subscriptions as a complementary library.

# [](#whats-next)What’s Next

These were big goals, and also a bit scary; we knew that incremental improvements would only allow us to move so fast. So in April we started a project to build a new implementation of Relay core targeting low-end mobile devices from the start.

As you can guess since we’re writing this, the experiment was a success. The result is a new core that retains the best parts of Relay today - colocated components & data-dependencies, automatic data/view consistency, declarative data-fetching - while improving performance on mobile devices and addressing several common areas of confusion.

We’re currently focused on shipping the first applications using the new core: ironing out bugs, refining the API changes and developer experience, and adding any missing features. We’re excited to bring these changes to open source, and will do so once we’ve proven them in production. We’ll go into more detail in some upcoming talks - links below - but for now here’s an overview:

* **Static Queries**: By adding a couple of Relay-specific directives, we’ve been able to retain the expressivity of current Relay queries using static syntax (concretely: you know what query an app will execute just by looking at the source text, without having to run that code). For starters this will allow Relay apps to start fetching data in parallel with JavaScript initialization. But it also unlocks other possibilities: knowing the query ahead of time means that we can generate optimized code for handling query responses, for example, or for reading query data from an offline cache.
* **Expressive Mutations**: We’ll continue to support a higher-level mutation API for common cases, but will also provide a lower-level API that allows “raw” data access where necessary. If you need to order a list of cached elements, for example, there will be a way to `sort()` it.
* **Route-less Relay**: Routes will be gone in open source. Instead of a route with multiple query definitions, you’ll just provide a single query with as many root fields as you want.
* **Cache Eviction/Garbage Collection**: The API and architecture is designed from the start to allow removing cached data that is no longer referenced by a mounted view.

Stepping back, we recognize that any API changes will require an investment on your part. To make the transition easier, though, *we will continue to support the current API for the foreseeable future* (we’re still using it too). And as much as possible we will open-source the tools that we use to migrate our own code. Ideas that we’re exploring include codemods, an interoperability layer for the old/new APIs, and tutorials & guides to ease migration.

Ultimately, we’re making these changes because we believe they make Relay better all around: simpler for developers building apps and faster for the people using them.

# [](#conclusion)Conclusion

If you made it this far, congrats and thanks for reading! We’ll be sharing more information about these changes in some upcoming talks:

* [Greg Hurrell](https://github.com/wincent) will presenting a Relay “Deep Dive” at the [Silicon Valley ReactJS Meetup](http://www.meetup.com/Silicon-Valley-ReactJS-Meetup/events/232236845/) on August 17th.
* I ([@josephsavona](https://github.com/josephsavona)) will be speaking about Relay at [React Rally](http://www.reactrally.com) on August 25th.

We can’t wait to share the new code with you and are working as fast as we can to do so!

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2016-08-05-relay-state-of-the-state.md)

----
url: https://react.dev/reference/react/useId
----

[API Reference](/reference/react)

[Hooks](/reference/react/hooks)

# useId[](#undefined "Link for this heading")

`useId` is a React Hook for generating unique IDs that can be passed to accessibility attributes.

```
const id = useId()
```

***

## Reference[](#reference "Link for Reference ")

### `useId()`[](#useid "Link for this heading")

Call `useId` at the top level of your component to generate a unique ID:

```
import { useId } from 'react';



function PasswordField() {

  const passwordHintId = useId();

  // ...
```

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

* `useId` **should not be used to generate keys** in a list. [Keys should be generated from your data.](/learn/rendering-lists#where-to-get-your-key)

* `useId` currently cannot be used in [async Server Components](/reference/rsc/server-components#async-components-with-server-components).

***

## Usage[](#usage "Link for Usage ")

### Pitfall

**Do not call `useId` to generate keys in a list.** [Keys should be generated from your data.](/learn/rendering-lists#where-to-get-your-key)

### Generating unique IDs for accessibility attributes[](#generating-unique-ids-for-accessibility-attributes "Link for Generating unique IDs for accessibility attributes ")

Call `useId` at the top level of your component to generate a unique ID:

```
import { useId } from 'react';



function PasswordField() {

  const passwordHintId = useId();

  // ...
```

You can then pass the generated ID to different attributes:

```
<>

  <input type="password" aria-describedby={passwordHintId} />

  <p id={passwordHintId}>

</>
```

**Let’s walk through an example to see when this is useful.**

[HTML accessibility attributes](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA) like [`aria-describedby`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-describedby) let you specify that two tags are related to each other. For example, you can specify that an element (like an input) is described by another element (like a paragraph).

In regular HTML, you would write it like this:

```
<label>

  Password:

  <input

    type="password"

    aria-describedby="password-hint"

  />

</label>

<p id="password-hint">

  The password should contain at least 18 characters

</p>
```

However, hardcoding IDs like this is not a good practice in React. A component may be rendered more than once on the page—but IDs have to be unique! Instead of hardcoding an ID, generate a unique ID with `useId`:

```
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>

    </>

  );

}
```

Now, even if `PasswordField` appears multiple times on the screen, the generated IDs won’t clash.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
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>
    </>
  );
}

export default function App() {
  return (
    <>
      <h2>Choose password</h2>
      <PasswordField />
      <h2>Confirm password</h2>
      <PasswordField />
    </>
  );
}
```

***

### Generating IDs for several related elements[](#generating-ids-for-several-related-elements "Link for Generating IDs for several related elements ")

If you need to give IDs to multiple related elements, you can call `useId` to generate a shared prefix for them:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useId } from 'react';

export default function Form() {
  const id = useId();
  return (
    <form>
      <label htmlFor={id + '-firstName'}>First Name:</label>
      <input id={id + '-firstName'} type="text" />
      <hr />
      <label htmlFor={id + '-lastName'}>Last Name:</label>
      <input id={id + '-lastName'} type="text" />
    </form>
  );
}
```

This lets you avoid calling `useId` for every single element that needs a unique ID.

***

### Specifying a shared prefix for all generated IDs[](#specifying-a-shared-prefix-for-all-generated-ids "Link for Specifying a shared prefix for all generated IDs ")

If you render multiple independent React applications on a single page, pass `identifierPrefix` as an option to your [`createRoot`](/reference/react-dom/client/createRoot#parameters) or [`hydrateRoot`](/reference/react-dom/client/hydrateRoot) calls. This ensures that the IDs generated by the two different apps never clash because every identifier generated with `useId` will start with the distinct prefix you’ve specified.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { createRoot } from 'react-dom/client';
import App from './App.js';
import './styles.css';

const root1 = createRoot(document.getElementById('root1'), {
  identifierPrefix: 'my-first-app-'
});
root1.render(<App />);

const root2 = createRoot(document.getElementById('root2'), {
  identifierPrefix: 'my-second-app-'
});
root2.render(<App />);
```

***

### Using the same ID prefix on the client and the server[](#using-the-same-id-prefix-on-the-client-and-the-server "Link for Using the same ID prefix on the client and the server ")

If you [render multiple independent React apps on the same page](#specifying-a-shared-prefix-for-all-generated-ids), and some of these apps are server-rendered, make sure that the `identifierPrefix` you pass to the [`hydrateRoot`](/reference/react-dom/client/hydrateRoot) call on the client side is the same as the `identifierPrefix` you pass to the [server APIs](/reference/react-dom/server) such as [`renderToPipeableStream`.](/reference/react-dom/server/renderToPipeableStream)

```
// Server

import { renderToPipeableStream } from 'react-dom/server';



const { pipe } = renderToPipeableStream(

  <App />,

  { identifierPrefix: 'react-app1' }

);
```

```
// Client

import { hydrateRoot } from 'react-dom/client';



const domNode = document.getElementById('root');

const root = hydrateRoot(

  domNode,

  reactNode,

  { identifierPrefix: 'react-app1' }

);
```

You do not need to pass `identifierPrefix` if you only have one React app on the page.

[PrevioususeEffectEvent](/reference/react/useEffectEvent)

[NextuseImperativeHandle](/reference/react/useImperativeHandle)

***

----
url: https://react.dev/reference/react-dom/preload
----

[API Reference](/reference/react)

[APIs](/reference/react-dom)

# preload[](#undefined "Link for this heading")

### Note

[React-based frameworks](/learn/creating-a-react-app) frequently handle resource loading for you, so you might not have to call this API yourself. Consult your framework’s documentation for details.

`preload` lets you eagerly fetch a resource such as a stylesheet, font, or external script that you expect to use.

```
preload("https://example.com/font.woff2", {as: "font"});
```

* [Reference](#reference)
  * [`preload(href, options)`](#preload)

* [Usage](#usage)

  * [Preloading when rendering](#preloading-when-rendering)
  * [Preloading in an event handler](#preloading-in-an-event-handler)

***

## Reference[](#reference "Link for Reference ")

### `preload(href, options)`[](#preload "Link for this heading")

To preload a resource, call the `preload` function from `react-dom`.

```
import { preload } from 'react-dom';



function AppRoot() {

  preload("https://example.com/font.woff2", {as: "font"});

  // ...

}
```

***

## Usage[](#usage "Link for Usage ")

### Preloading when rendering[](#preloading-when-rendering "Link for Preloading when rendering ")

Call `preload` when rendering a component if you know that it or its children will use a specific resource.

#### Examples of preloading[](#examples "Link for Examples of preloading")

#### Example 1 of 4:Preloading an external script[](#preloading-an-external-script "Link for this heading")

```
import { preload } from 'react-dom';



function AppRoot() {

  preload("https://example.com/script.js", {as: "script"});

  return ...;

}
```

If you want the browser to start executing the script immediately (rather than just downloading it), use [`preinit`](/reference/react-dom/preinit) instead. If you want to load an ESM module, use [`preloadModule`](/reference/react-dom/preloadModule).

### Preloading in an event handler[](#preloading-in-an-event-handler "Link for Preloading in an event handler ")

Call `preload` in an event handler before transitioning to a page or state where external resources will be needed. This gets the process started earlier than if you call it during the rendering of the new page or state.

```
import { preload } from 'react-dom';



function CallToAction() {

  const onClick = () => {

    preload("https://example.com/wizardStyles.css", {as: "style"});

    startWizard();

  }

  return (

    <button onClick={onClick}>Start Wizard</button>

  );

}
```

[PreviouspreinitModule](/reference/react-dom/preinitModule)

[NextpreloadModule](/reference/react-dom/preloadModule)

***

----
url: https://react.dev/reference/react/StrictMode
----

[API Reference](/reference/react)

[Components](/reference/react/components)

# \<StrictMode>[](#undefined "Link for this heading")

`<StrictMode>` lets you find common bugs in your components early during development.

```
<StrictMode>

  <App />

</StrictMode>
```

  * [Fixing bugs found by re-running ref callbacks in development](#fixing-bugs-found-by-re-running-ref-callbacks-in-development)
  * [Fixing deprecation warnings enabled by Strict Mode](#fixing-deprecation-warnings-enabled-by-strict-mode)

***

## Reference[](#reference "Link for Reference ")

### `<StrictMode>`[](#strictmode "Link for this heading")

Use `StrictMode` to enable additional development behaviors and warnings for the component tree inside:

```
import { StrictMode } from 'react';

import { createRoot } from 'react-dom/client';



const root = createRoot(document.getElementById('root'));

root.render(

  <StrictMode>

    <App />

  </StrictMode>

);
```

[See more examples below.](#usage)

Strict Mode enables the following development-only behaviors:

* Your components will [re-render an extra time](#fixing-bugs-found-by-double-rendering-in-development) to find bugs caused by impure rendering.
* Your components will [re-run Effects an extra time](#fixing-bugs-found-by-re-running-effects-in-development) to find bugs caused by missing Effect cleanup.
* Your components will [re-run refs callbacks an extra time](#fixing-bugs-found-by-re-running-ref-callbacks-in-development) to find bugs caused by missing ref cleanup.
* Your components will [be checked for usage of deprecated APIs.](#fixing-deprecation-warnings-enabled-by-strict-mode)

#### Props[](#props "Link for Props ")

`StrictMode` accepts no props.

#### Caveats[](#caveats "Link for Caveats ")

* There is no way to opt out of Strict Mode inside a tree wrapped in `<StrictMode>`. This gives you confidence that all components inside `<StrictMode>` are checked. If two teams working on a product disagree whether they find the checks valuable, they need to either reach consensus or move `<StrictMode>` down in the tree.

***

## Usage[](#usage "Link for Usage ")

### Enabling Strict Mode for entire app[](#enabling-strict-mode-for-entire-app "Link for Enabling Strict Mode for entire app ")

Strict Mode enables extra development-only checks for the entire component tree inside the `<StrictMode>` component. These checks help you find common bugs in your components early in the development process.

To enable Strict Mode for your entire app, wrap your root component with `<StrictMode>` when you render it:

```
import { StrictMode } from 'react';

import { createRoot } from 'react-dom/client';



const root = createRoot(document.getElementById('root'));

root.render(

  <StrictMode>

    <App />

  </StrictMode>

);
```

We recommend wrapping your entire app in Strict Mode, especially for newly created apps. If you use a framework that calls [`createRoot`](/reference/react-dom/client/createRoot) for you, check its documentation for how to enable Strict Mode.

Although the Strict Mode checks **only run in development,** they help you find bugs that already exist in your code but can be tricky to reliably reproduce in production. Strict Mode lets you fix bugs before your users report them.

### Note

Strict Mode enables the following checks in development:

* Your components will [re-render an extra time](#fixing-bugs-found-by-double-rendering-in-development) to find bugs caused by impure rendering.
* Your components will [re-run Effects an extra time](#fixing-bugs-found-by-re-running-effects-in-development) to find bugs caused by missing Effect cleanup.
* Your components will [re-run ref callbacks an extra time](#fixing-bugs-found-by-re-running-ref-callbacks-in-development) to find bugs caused by missing ref cleanup.
* Your components will [be checked for usage of deprecated APIs.](#fixing-deprecation-warnings-enabled-by-strict-mode)

**All of these checks are development-only and do not impact the production build.**

***

### Enabling Strict Mode for a part of the app[](#enabling-strict-mode-for-a-part-of-the-app "Link for Enabling Strict Mode for a part of the app ")

You can also enable Strict Mode for any part of your application:

```
import { StrictMode } from 'react';



function App() {

  return (

    <>

      <Header />

      <StrictMode>

        <main>

          <Sidebar />

          <Content />

        </main>

      </StrictMode>

      <Footer />

    </>

  );

}
```

In this example, Strict Mode checks will not run against the `Header` and `Footer` components. However, they will run on `Sidebar` and `Content`, as well as all of the components inside them, no matter how deep.

### Note

When `StrictMode` is enabled for a part of the app, React will only enable behaviors that are possible in production. For example, if `<StrictMode>` is not enabled at the root of the app, it will not [re-run Effects an extra time](#fixing-bugs-found-by-re-running-effects-in-development) on initial mount, since this would cause child effects to double fire without the parent effects, which cannot happen in production.

***

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
export default function StoryTray({ stories }) {
  const items = stories;
  items.push({ id: 'create', label: 'Create Story' });
  return (
    <ul>
      {items.map(story => (
        <li key={story.id}>
          {story.label}
        </li>
      ))}
    </ul>
  );
}
```

There is a mistake in the code above. However, it is easy to miss because the initial output appears correct.

This mistake will become more noticeable if the `StoryTray` component re-renders multiple times. For example, let’s make the `StoryTray` re-render with a different background color whenever you hover over it:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function StoryTray({ stories }) {
  const [isHover, setIsHover] = useState(false);
  const items = stories;
  items.push({ id: 'create', label: 'Create Story' });
  return (
    <ul
      onPointerEnter={() => setIsHover(true)}
      onPointerLeave={() => setIsHover(false)}
      style={{
        backgroundColor: isHover ? '#ddd' : '#fff'
      }}
    >
      {items.map(story => (
        <li key={story.id}>
          {story.label}
        </li>
      ))}
    </ul>
  );
}
```

Notice how every time you hover over the `StoryTray` component, “Create Story” gets added to the list again. The intention of the code was to add it once at the end. But `StoryTray` directly modifies the `stories` array from the props. Every time `StoryTray` renders, it adds “Create Story” again at the end of the same array. In other words, `StoryTray` is not a pure function—running it multiple times produces different results.

To fix this problem, you can make a copy of the array, and modify that copy instead of the original one:

```
export default function StoryTray({ stories }) {

  const items = stories.slice(); // Clone the array

  // ✅ Good: Pushing into a new array

  items.push({ id: 'create', label: 'Create Story' });
```

This would [make the `StoryTray` function pure.](/learn/keeping-components-pure) Each time it is called, it would only modify a new copy of the array, and would not affect any external objects or variables. This solves the bug, but you had to make the component re-render more often before it became obvious that something is wrong with its behavior.

**In the original example, the bug wasn’t obvious. Now let’s wrap the original (buggy) code in `<StrictMode>`:**

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
export default function StoryTray({ stories }) {
  const items = stories;
  items.push({ id: 'create', label: 'Create Story' });
  return (
    <ul>
      {items.map(story => (
        <li key={story.id}>
          {story.label}
        </li>
      ))}
    </ul>
  );
}
```

**Strict Mode *always* calls your rendering function twice, so you can see the mistake right away** (“Create Story” appears twice). This lets you notice such mistakes early in the process. When you fix your component to render in Strict Mode, you *also* fix many possible future production bugs like the hover functionality from before:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function StoryTray({ stories }) {
  const [isHover, setIsHover] = useState(false);
  const items = stories.slice(); // Clone the array
  items.push({ id: 'create', label: 'Create Story' });
  return (
    <ul
      onPointerEnter={() => setIsHover(true)}
      onPointerLeave={() => setIsHover(false)}
      style={{
        backgroundColor: isHover ? '#ddd' : '#fff'
      }}
    >
      {items.map(story => (
        <li key={story.id}>
          {story.label}
        </li>
      ))}
    </ul>
  );
}
```

Without Strict Mode, it was easy to miss the bug until you added more re-renders. Strict Mode made the same bug appear right away. Strict Mode helps you find bugs before you push them to your team and to your users.

[Read more about keeping components pure.](/learn/keeping-components-pure)

### Note

If you have [React DevTools](/learn/react-developer-tools) installed, any `console.log` calls during the second render call will appear slightly dimmed. React DevTools also offers a setting (off by default) to suppress them completely.

***

### Fixing bugs found by re-running Effects in development[](#fixing-bugs-found-by-re-running-effects-in-development "Link for Fixing bugs found by re-running Effects in development ")

Strict Mode can also help find bugs in [Effects.](/learn/synchronizing-with-effects)

Every Effect has some setup code and may have some cleanup code. Normally, React calls setup when the component *mounts* (is added to the screen) and calls cleanup when the component *unmounts* (is removed from the screen). React then calls cleanup and setup again if its dependencies changed since the last render.

When Strict Mode is on, React will also run **one extra setup+cleanup cycle in development for every Effect.** This may feel surprising, but it helps reveal subtle bugs that are hard to catch manually.

**Here is an example to illustrate how re-running Effects in Strict Mode helps you find bugs early.**

Consider this example that connects a component to a chat:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { createRoot } from 'react-dom/client';
import './styles.css';

import App from './App';

const root = createRoot(document.getElementById("root"));
root.render(<App />);
```

There is an issue with this code, but it might not be immediately clear.

To make the issue more obvious, let’s implement a feature. In the example below, `roomId` is not hardcoded. Instead, the user can select the `roomId` that they want to connect to from a dropdown. Click “Open chat” and then select different chat rooms one by one. Keep track of the number of active connections in the console:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { createRoot } from 'react-dom/client';
import './styles.css';

import App from './App';

const root = createRoot(document.getElementById("root"));
root.render(<App />);
```

You’ll notice that the number of open connections always keeps growing. In a real app, this would cause performance and network problems. The issue is that [your Effect is missing a cleanup function:](/learn/synchronizing-with-effects#step-3-add-cleanup-if-needed)

```
  useEffect(() => {

    const connection = createConnection(serverUrl, roomId);

    connection.connect();

    return () => connection.disconnect();

  }, [roomId]);
```

Now that your Effect “cleans up” after itself and destroys the outdated connections, the leak is solved. However, notice that the problem did not become visible until you’ve added more features (the select box).

**In the original example, the bug wasn’t obvious. Now let’s wrap the original (buggy) code in `<StrictMode>`:**

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import './styles.css';

import App from './App';

const root = createRoot(document.getElementById("root"));
root.render(
  <StrictMode>
    <App />
  </StrictMode>
);
```

**With Strict Mode, you immediately see that there is a problem** (the number of active connections jumps to 2). Strict Mode runs an extra setup+cleanup cycle for every Effect. This Effect has no cleanup logic, so it creates an extra connection but doesn’t destroy it. This is a hint that you’re missing a cleanup function.

Strict Mode lets you notice such mistakes early in the process. When you fix your Effect by adding a cleanup function in Strict Mode, you *also* fix many possible future production bugs like the select box from before:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import './styles.css';

import App from './App';

const root = createRoot(document.getElementById("root"));
root.render(
  <StrictMode>
    <App />
  </StrictMode>
);
```

Notice how the active connection count in the console doesn’t keep growing anymore.

Without Strict Mode, it was easy to miss that your Effect needed cleanup. By running *setup → cleanup → setup* instead of *setup* for your Effect in development, Strict Mode made the missing cleanup logic more noticeable.

[Read more about implementing Effect cleanup.](/learn/synchronizing-with-effects#how-to-handle-the-effect-firing-twice-in-development)

***

### Fixing bugs found by re-running ref callbacks in development[](#fixing-bugs-found-by-re-running-ref-callbacks-in-development "Link for Fixing bugs found by re-running ref callbacks in development ")

Strict Mode can also help find bugs in [callbacks refs.](/learn/manipulating-the-dom-with-refs)

Every callback `ref` has some setup code and may have some cleanup code. Normally, React calls setup when the element is *created* (is added to the DOM) and calls cleanup when the element is *removed* (is removed from the DOM).

When Strict Mode is on, React will also run **one extra setup+cleanup cycle in development for every callback `ref`.** This may feel surprising, but it helps reveal subtle bugs that are hard to catch manually.

Consider this example, which allows you to select an animal and then scroll to one of them. Notice when you switch from “Cats” to “Dogs”, the console logs show that the number of animals in the list keeps growing, and the “Scroll to” buttons stop working:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useRef, useState } from "react";

export default function CatFriends() {
  const itemsRef = useRef([]);
  const [catList, setCatList] = useState(setupCatList);
  const [cat, setCat] = useState('neo');

  function scrollToCat(index) {
    const list = itemsRef.current;
    const {node} = list[index];
    node.scrollIntoView({
      behavior: "smooth",
      block: "nearest",
      inline: "center",
    });
  }

  const cats = catList.filter(c => c.type === cat)

  return (
    <>
      <nav>
        <button onClick={() => setCat('neo')}>Neo</button>
        <button onClick={() => setCat('millie')}>Millie</button>
      </nav>
      <hr />
      <nav>
        <span>Scroll to:</span>{cats.map((cat, index) => (
          <button key={cat.src} onClick={() => scrollToCat(index)}>
            {index}
          </button>
        ))}
      </nav>
      <div>
        <ul>
          {cats.map((cat) => (
            <li
              key={cat.src}
              ref={(node) => {
                const list = itemsRef.current;
                const item = {cat: cat, node};
                list.push(item);
                console.log(`✅ Adding cat to the map. Total cats: ${list.length}`);
                if (list.length > 10) {
                  console.log('❌ Too many cats in the list!');
                }
                return () => {
                  // 🚩 No cleanup, this is a bug!
                }
              }}
            >
              <img src={cat.src} />
            </li>
          ))}
        </ul>
      </div>
    </>
  );
}

function setupCatList() {
  const catList = [];
  for (let i = 0; i < 10; i++) {
    catList.push({type: 'neo', src: "https://placecats.com/neo/320/240?" + i});
  }
  for (let i = 0; i < 10; i++) {
    catList.push({type: 'millie', src: "https://placecats.com/millie/320/240?" + i});
  }

  return catList;
}
```

**This is a production bug!** Since the ref callback doesn’t remove animals from the list in the cleanup, the list of animals keeps growing. This is a memory leak that can cause performance problems in a real app, and breaks the behavior of the app.

The issue is the ref callback doesn’t cleanup after itself:

```
<li

  ref={node => {

    const list = itemsRef.current;

    const item = {animal, node};

    list.push(item);

    return () => {

      // 🚩 No cleanup, this is a bug!

    }

  }}

</li>
```

Now let’s wrap the original (buggy) code in `<StrictMode>`:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useRef, useState } from "react";

export default function CatFriends() {
  const itemsRef = useRef([]);
  const [catList, setCatList] = useState(setupCatList);
  const [cat, setCat] = useState('neo');

  function scrollToCat(index) {
    const list = itemsRef.current;
    const {node} = list[index];
    node.scrollIntoView({
      behavior: "smooth",
      block: "nearest",
      inline: "center",
    });
  }

  const cats = catList.filter(c => c.type === cat)

  return (
    <>
      <nav>
        <button onClick={() => setCat('neo')}>Neo</button>
        <button onClick={() => setCat('millie')}>Millie</button>
      </nav>
      <hr />
      <nav>
        <span>Scroll to:</span>{cats.map((cat, index) => (
          <button key={cat.src} onClick={() => scrollToCat(index)}>
            {index}
          </button>
        ))}
      </nav>
      <div>
        <ul>
          {cats.map((cat) => (
            <li
              key={cat.src}
              ref={(node) => {
                const list = itemsRef.current;
                const item = {cat: cat, node};
                list.push(item);
                console.log(`✅ Adding cat to the map. Total cats: ${list.length}`);
                if (list.length > 10) {
                  console.log('❌ Too many cats in the list!');
                }
                return () => {
                  // 🚩 No cleanup, this is a bug!
                }
              }}
            >
              <img src={cat.src} />
            </li>
          ))}
        </ul>
      </div>
    </>
  );
}

function setupCatList() {
  const catList = [];
  for (let i = 0; i < 10; i++) {
    catList.push({type: 'neo', src: "https://placecats.com/neo/320/240?" + i});
  }
  for (let i = 0; i < 10; i++) {
    catList.push({type: 'millie', src: "https://placecats.com/millie/320/240?" + i});
  }

  return catList;
}
```

**With Strict Mode, you immediately see that there is a problem**. Strict Mode runs an extra setup+cleanup cycle for every callback ref. This callback ref has no cleanup logic, so it adds refs but doesn’t remove them. This is a hint that you’re missing a cleanup function.

Strict Mode lets you eagerly find mistakes in callback refs. When you fix your callback by adding a cleanup function in Strict Mode, you *also* fix many possible future production bugs like the “Scroll to” bug from before:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useRef, useState } from "react";

export default function CatFriends() {
  const itemsRef = useRef([]);
  const [catList, setCatList] = useState(setupCatList);
  const [cat, setCat] = useState('neo');

  function scrollToCat(index) {
    const list = itemsRef.current;
    const {node} = list[index];
    node.scrollIntoView({
      behavior: "smooth",
      block: "nearest",
      inline: "center",
    });
  }

  const cats = catList.filter(c => c.type === cat)

  return (
    <>
      <nav>
        <button onClick={() => setCat('neo')}>Neo</button>
        <button onClick={() => setCat('millie')}>Millie</button>
      </nav>
      <hr />
      <nav>
        <span>Scroll to:</span>{cats.map((cat, index) => (
          <button key={cat.src} onClick={() => scrollToCat(index)}>
            {index}
          </button>
        ))}
      </nav>
      <div>
        <ul>
          {cats.map((cat) => (
            <li
              key={cat.src}
              ref={(node) => {
                const list = itemsRef.current;
                const item = {cat: cat, node};
                list.push(item);
                console.log(`✅ Adding cat to the map. Total cats: ${list.length}`);
                if (list.length > 10) {
                  console.log('❌ Too many cats in the list!');
                }
                return () => {
                  list.splice(list.indexOf(item), 1);
                  console.log(`❌ Removing cat from the map. Total cats: ${itemsRef.current.length}`);
                }
              }}
            >
              <img src={cat.src} />
            </li>
          ))}
        </ul>
      </div>
    </>
  );
}

function setupCatList() {
  const catList = [];
  for (let i = 0; i < 10; i++) {
    catList.push({type: 'neo', src: "https://placecats.com/neo/320/240?" + i});
  }
  for (let i = 0; i < 10; i++) {
    catList.push({type: 'millie', src: "https://placecats.com/millie/320/240?" + i});
  }

  return catList;
}
```

Now on inital mount in StrictMode, the ref callbacks are all setup, cleaned up, and setup again:

```
...

✅ Adding animal to the map. Total animals: 10

...

❌ Removing animal from the map. Total animals: 0

...

✅ Adding animal to the map. Total animals: 10
```

**This is expected.** Strict Mode confirms that the ref callbacks are cleaned up correctly, so the size never grows above the expected amount. After the fix, there are no memory leaks, and all the features work as expected.

Without Strict Mode, it was easy to miss the bug until you clicked around to app to notice broken features. Strict Mode made the bugs appear right away, before you push them to production.

***

### Fixing deprecation warnings enabled by Strict Mode[](#fixing-deprecation-warnings-enabled-by-strict-mode "Link for Fixing deprecation warnings enabled by Strict Mode ")

React warns if some component anywhere inside a `<StrictMode>` tree uses one of these deprecated APIs:

* `UNSAFE_` class lifecycle methods like [`UNSAFE_componentWillMount`](/reference/react/Component#unsafe_componentwillmount). [See alternatives.](https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html#migrating-from-legacy-lifecycles)

These APIs are primarily used in older [class components](/reference/react/Component) so they rarely appear in modern apps.

[Previous\<Profiler>](/reference/react/Profiler)

[Next\<Suspense>](/reference/react/Suspense)

***

----
url: https://18.react.dev/reference/react-dom/hooks
----

[API Reference](/reference/react)

# Built-in React DOM Hooks[](#undefined "Link for this heading")

The `react-dom` package contains Hooks that are only supported for web applications (which run in the browser DOM environment). These Hooks are not supported in non-browser environments like iOS, Android, or Windows applications. If you are looking for Hooks that are supported in web browsers *and other environments* see [the React Hooks page](/reference/react). This page lists all the Hooks in the `react-dom` package.

***

## Form Hooks[](#form-hooks "Link for Form Hooks ")

### Canary

Form Hooks are currently only available in React’s canary and experimental channels. Learn more about [React’s release channels here](/community/versioning-policy#all-release-channels).

*Forms* let you create interactive controls for submitting information. To manage forms in your components, use one of these Hooks:

* [`useFormStatus`](/reference/react-dom/hooks/useFormStatus) allows you to make updates to the UI based on the status of the a form.

```
function Form({ action }) {

  async function increment(n) {

    return n + 1;

  }

  const [count, incrementFormAction] = useActionState(increment, 0);

  return (

    <form action={action}>

      <button formAction={incrementFormAction}>Count: {count}</button>

      <Button />

    </form>

  );

}



function Button() {

  const { pending } = useFormStatus();

  return (

    <button disabled={pending} type="submit">

      Submit

    </button>

  );

}
```

[NextuseFormStatus](/reference/react-dom/hooks/useFormStatus)

***

----
url: https://legacy.reactjs.org/blog/2021/06/08/the-plan-for-react-18.html
----

June 08, 2021 by [Andrew Clark](https://twitter.com/acdlite), [Brian Vaughn](https://github.com/bvaughn), [Christine Abernathy](https://twitter.com/abernathyca), [Dan Abramov](https://twitter.com/dan_abramov), [Rachel Nabors](https://twitter.com/rachelnabors), [Rick Hanlon](https://twitter.com/rickhanlonii), [Sebastian Markbåge](https://twitter.com/sebmarkbage), and [Seth Webster](https://twitter.com/sethwebster)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

> Update Nov. 15th, 2021
>
> React 18 is now in beta. More information about the status of the release is [available in the React 18 Working Group post](https://github.com/reactwg/react-18/discussions/112).

The React team is excited to share a few updates:

1. We’ve started work on the React 18 release, which will be our next major version.
2. We’ve created a Working Group to prepare the community for gradual adoption of new features in React 18.
3. We’ve published a React 18 Alpha so that library authors can try it and provide feedback.

These updates are primarily aimed at maintainers of third-party libraries. If you’re learning, teaching, or using React to build user-facing applications, you can safely ignore this post. But you are welcome to follow the discussions in the React 18 Working Group if you’re curious!

## [](#whats-coming-in-react-18)What’s coming in React 18

When it’s released, React 18 will include out-of-the-box improvements (like [automatic batching](https://github.com/reactwg/react-18/discussions/21)), new APIs (like [`startTransition`](https://github.com/reactwg/react-18/discussions/41)), and a [new streaming server renderer](https://github.com/reactwg/react-18/discussions/37) with built-in support for `React.lazy`.

These features are possible thanks to a new opt-in mechanism we’re adding in React 18. It’s called “concurrent rendering” and it lets React prepare multiple versions of the UI at the same time. This change is mostly behind-the-scenes, but it unlocks new possibilities to improve both real and perceived performance of your app.

If you’ve been following our research into the future of React (we don’t expect you to!), you might have heard of something called “concurrent mode” or that it might break your app. In response to this feedback from the community, we’ve redesigned the upgrade strategy for gradual adoption. Instead of an all-or-nothing “mode”, concurrent rendering will only be enabled for updates triggered by one of the new features. In practice, this means **you will be able to adopt React 18 without rewrites and try the new features at your own pace.**

## [](#a-gradual-adoption-strategy)A gradual adoption strategy

Since concurrency in React 18 is opt-in, there are no significant out-of-the-box breaking changes to component behavior. **You can upgrade to React 18 with minimal or no changes to your application code, with a level of effort comparable to a typical major React release**. Based on our experience converting several apps to React 18, we expect that many users will be able to upgrade within a single afternoon.

We successfully shipped concurrent features to tens of thousands of components at Facebook, and in our experience, we’ve found that most React components “just work” without additional changes. We’re committed to making sure this is a smooth upgrade for the entire community, so today we’re announcing the React 18 Working Group.

## [](#working-with-the-community)Working with the community

We’re trying something new for this release: We’ve invited a panel of experts, developers, library authors, and educators from across the React community to participate in our [React 18 Working Group](https://github.com/reactwg/react-18) to provide feedback, ask questions, and collaborate on the release. We couldn’t invite everyone we wanted to this initial, small group, but if this experiment works out, we hope there will be more in the future!

**The goal of the React 18 Working Group is to prepare the ecosystem for a smooth, gradual adoption of React 18 by existing applications and libraries.** The Working Group is hosted on [GitHub Discussions](https://github.com/reactwg/react-18/discussions) and is available for the public to read. Members of the working group can leave feedback, ask questions, and share ideas. The core team will also use the discussions repo to share our research findings. As the stable release gets closer, any important information will also be posted on this blog.

For more information on upgrading to React 18, or additional resources about the release, see the [React 18 announcement post](https://github.com/reactwg/react-18/discussions/4).

## [](#accessing-the-react-18-working-group)Accessing the React 18 Working Group

Everyone can read the discussions in the [React 18 Working Group repo](https://github.com/reactwg/react-18).

Because we expect an initial surge of interest in the Working Group, only invited members will be allowed to create or comment on threads. However, the threads are fully visible to the public, so everyone has access to the same information. We believe this is a good compromise between creating a productive environment for working group members, while maintaining transparency with the wider community.

As always, you can submit bug reports, questions, and general feedback to our [issue tracker](https://github.com/facebook/react/issues).

## [](#how-to-try-react-18-alpha-today)How to try React 18 Alpha today

New alphas are [regularly published to npm using the `@alpha` tag](https://github.com/reactwg/react-18/discussions/9). These releases are built using the most recent commit to our main repo. When a feature or bugfix is merged, it will appear in an alpha the following weekday.

There may be significant behavioral or API changes between alpha releases. Please remember that **alpha releases are not recommended for user-facing, production applications**.

## [](#projected-react-18-release-timeline)Projected React 18 release timeline

We don’t have a specific release date scheduled, but we expect it will take several months of feedback and iteration before React 18 is ready for most production applications.

* Library Alpha: Available today
* Public Beta: At least several months
* Release Candidate (RC): At least several weeks after Beta
* General Availability: At least several weeks after RC

More details about our projected release timeline are [available in the Working Group](https://github.com/reactwg/react-18/discussions/9). We’ll post updates on this blog when we’re closer to a public release.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2021-06-08-the-plan-for-react-18.md)

----
url: https://legacy.reactjs.org/docs/forms.html
----

> These docs are old and won’t be updated. Go to [react.dev](https://react.dev/) for the new React docs.
>
> These new documentation pages teach modern React and include live examples:
>
> * [`<input>`](https://react.dev/reference/react-dom/components/input)
> * [`<select>`](https://react.dev/reference/react-dom/components/select)
> * [`<textarea>`](https://react.dev/reference/react-dom/components/textarea)

HTML form elements work a bit differently from other DOM elements in React, because form elements naturally keep some internal state. For example, this form in plain HTML accepts a single name:

```
<form>
  <label>
    Name:
    <input type="text" name="name" />
  </label>
  <input type="submit" value="Submit" />
</form>
```

This form has the default HTML form behavior of browsing to a new page when the user submits the form. If you want this behavior in React, it just works. But in most cases, it’s convenient to have a JavaScript function that handles the submission of the form and has access to the data that the user entered into the form. The standard way to achieve this is with a technique called “controlled components”.

## [](#controlled-components)Controlled Components

In HTML, form elements such as `<input>`, `<textarea>`, and `<select>` typically maintain their own state and update it based on user input. In React, mutable state is typically kept in the state property of components, and only updated with [`setState()`](/docs/react-component.html#setstate).

We can combine the two by making the React state be the “single source of truth”. Then the React component that renders a form also controls what happens in that form on subsequent user input. An input form element whose value is controlled by React in this way is called a “controlled component”.

For example, if we want to make the previous example log the name when it is submitted, we can write the form as a controlled component:

```
class NameForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {value: ''};
    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange(event) {    this.setState({value: event.target.value});  }
  handleSubmit(event) {
    alert('A name was submitted: ' + this.state.value);
    event.preventDefault();
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>        <label>
          Name:
          <input type="text" value={this.state.value} onChange={this.handleChange} />        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}
```

[**Try it on CodePen**](https://codepen.io/gaearon/pen/VmmPgp?editors=0010)

Since the `value` attribute is set on our form element, the displayed value will always be `this.state.value`, making the React state the source of truth. Since `handleChange` runs on every keystroke to update the React state, the displayed value will update as the user types.

With a controlled component, the input’s value is always driven by the React state. While this means you have to type a bit more code, you can now pass the value to other UI elements too, or reset it from other event handlers.

## [](#the-textarea-tag)The textarea Tag

In HTML, a `<textarea>` element defines its text by its children:

```
<textarea>
  Hello there, this is some text in a text area
</textarea>
```

In React, a `<textarea>` uses a `value` attribute instead. This way, a form using a `<textarea>` can be written very similarly to a form that uses a single-line input:

```
class EssayForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {      value: 'Please write an essay about your favorite DOM element.'    };
    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange(event) {    this.setState({value: event.target.value});  }
  handleSubmit(event) {
    alert('An essay was submitted: ' + this.state.value);
    event.preventDefault();
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Essay:
          <textarea value={this.state.value} onChange={this.handleChange} />        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}
```

Notice that `this.state.value` is initialized in the constructor, so that the text area starts off with some text in it.

## [](#the-select-tag)The select Tag

In HTML, `<select>` creates a drop-down list. For example, this HTML creates a drop-down list of flavors:

```
<select>
  <option value="grapefruit">Grapefruit</option>
  <option value="lime">Lime</option>
  <option selected value="coconut">Coconut</option>
  <option value="mango">Mango</option>
</select>
```

Note that the Coconut option is initially selected, because of the `selected` attribute. React, instead of using this `selected` attribute, uses a `value` attribute on the root `select` tag. This is more convenient in a controlled component because you only need to update it in one place. For example:

```
class FlavorForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {value: 'coconut'};
    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange(event) {    this.setState({value: event.target.value});  }
  handleSubmit(event) {
    alert('Your favorite flavor is: ' + this.state.value);
    event.preventDefault();
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Pick your favorite flavor:
          <select value={this.state.value} onChange={this.handleChange}>            <option value="grapefruit">Grapefruit</option>
            <option value="lime">Lime</option>
            <option value="coconut">Coconut</option>
            <option value="mango">Mango</option>
          </select>
        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}
```

[**Try it on CodePen**](https://codepen.io/gaearon/pen/JbbEzX?editors=0010)

Overall, this makes it so that `<input type="text">`, `<textarea>`, and `<select>` all work very similarly - they all accept a `value` attribute that you can use to implement a controlled component.

> Note
>
> You can pass an array into the `value` attribute, allowing you to select multiple options in a `select` tag:
>
> ```
> <select multiple={true} value={['B', 'C']}>
> ```

## [](#the-file-input-tag)The file input Tag

In HTML, an `<input type="file">` lets the user choose one or more files from their device storage to be uploaded to a server or manipulated by JavaScript via the [File API](https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications).

```
<input type="file" />
```

Because its value is read-only, it is an **uncontrolled** component in React. It is discussed together with other uncontrolled components [later in the documentation](/docs/uncontrolled-components.html#the-file-input-tag).

## [](#handling-multiple-inputs)Handling Multiple Inputs

When you need to handle multiple controlled `input` elements, you can add a `name` attribute to each element and let the handler function choose what to do based on the value of `event.target.name`.

For example:

```
class Reservation extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      isGoing: true,
      numberOfGuests: 2
    };

    this.handleInputChange = this.handleInputChange.bind(this);
  }

  handleInputChange(event) {
    const target = event.target;
    const value = target.type === 'checkbox' ? target.checked : target.value;
    const name = target.name;
    this.setState({
      [name]: value    });
  }

  render() {
    return (
      <form>
        <label>
          Is going:
          <input
            name="isGoing"            type="checkbox"
            checked={this.state.isGoing}
            onChange={this.handleInputChange} />
        </label>
        <br />
        <label>
          Number of guests:
          <input
            name="numberOfGuests"            type="number"
            value={this.state.numberOfGuests}
            onChange={this.handleInputChange} />
        </label>
      </form>
    );
  }
}
```

[**Try it on CodePen**](https://codepen.io/gaearon/pen/wgedvV?editors=0010)

Note how we used the ES6 [computed property name](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Object_initializer#Computed_property_names) syntax to update the state key corresponding to the given input name:

```
this.setState({
  [name]: value});
```

It is equivalent to this ES5 code:

```
var partialState = {};
partialState[name] = value;this.setState(partialState);
```

Also, since `setState()` automatically [merges a partial state into the current state](/docs/state-and-lifecycle.html#state-updates-are-merged), we only needed to call it with the changed parts.

## [](#controlled-input-null-value)Controlled Input Null Value

Specifying the `value` prop on a [controlled component](/docs/forms.html#controlled-components) prevents the user from changing the input unless you desire so. If you’ve specified a `value` but the input is still editable, you may have accidentally set `value` to `undefined` or `null`.

The following code demonstrates this. (The input is locked at first but becomes editable after a short delay.)

```
ReactDOM.createRoot(mountNode).render(<input value="hi" />);

setTimeout(function() {
  ReactDOM.createRoot(mountNode).render(<input value={null} />);
}, 1000);
```

## [](#alternatives-to-controlled-components)Alternatives to Controlled Components

It can sometimes be tedious to use controlled components, because you need to write an event handler for every way your data can change and pipe all of the input state through a React component. This can become particularly annoying when you are converting a preexisting codebase to React, or integrating a React application with a non-React library. In these situations, you might want to check out [uncontrolled components](/docs/uncontrolled-components.html), an alternative technique for implementing input forms.

## [](#fully-fledged-solutions)Fully-Fledged Solutions

If you’re looking for a complete solution including validation, keeping track of the visited fields, and handling form submission, [Formik](https://jaredpalmer.com/formik) is one of the popular choices. However, it is built on the same principles of controlled components and managing state — so don’t neglect to learn them.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/forms.md)

* Previous article

  [Lists and Keys](/docs/lists-and-keys.html)

* Next article

  [Lifting State Up](/docs/lifting-state-up.html)

----
url: https://react.dev/reference/react/useInsertionEffect
----

[API Reference](/reference/react)

[Hooks](/reference/react/hooks)

# useInsertionEffect[](#undefined "Link for this heading")

### Pitfall

`useInsertionEffect` is for CSS-in-JS library authors. Unless you are working on a CSS-in-JS library and need a place to inject the styles, you probably want [`useEffect`](/reference/react/useEffect) or [`useLayoutEffect`](/reference/react/useLayoutEffect) instead.

`useInsertionEffect` allows inserting elements into the DOM before any layout Effects fire.

```
useInsertionEffect(setup, dependencies?)
```

* [Reference](#reference)
  * [`useInsertionEffect(setup, dependencies?)`](#useinsertioneffect)
* [Usage](#usage)
  * [Injecting dynamic styles from CSS-in-JS libraries](#injecting-dynamic-styles-from-css-in-js-libraries)

***

## Reference[](#reference "Link for Reference ")

### `useInsertionEffect(setup, dependencies?)`[](#useinsertioneffect "Link for this heading")

Call `useInsertionEffect` to insert styles before any Effects fire that may need to read layout:

```
import { useInsertionEffect } from 'react';



// Inside your CSS-in-JS library

function useCSS(rule) {

  useInsertionEffect(() => {

    // ... inject <style> tags here ...

  });

  return rule;

}
```

***

## Usage[](#usage "Link for Usage ")

### Injecting dynamic styles from CSS-in-JS libraries[](#injecting-dynamic-styles-from-css-in-js-libraries "Link for Injecting dynamic styles from CSS-in-JS libraries ")

Traditionally, you would style React components using plain CSS.

```
// In your JS file:

<button className="success" />



// In your CSS file:

.success { color: green; }
```

```
// Inside your CSS-in-JS library

let isInserted = new Set();

function useCSS(rule) {

  useInsertionEffect(() => {

    // As explained earlier, we don't recommend runtime injection of <style> tags.

    // But if you have to do it, then it's important to do in useInsertionEffect.

    if (!isInserted.has(rule)) {

      isInserted.add(rule);

      document.head.appendChild(getStyleForRule(rule));

    }

  });

  return rule;

}



function Button() {

  const className = useCSS('...');

  return <div className={className} />;

}
```

Similarly to `useEffect`, `useInsertionEffect` does not run on the server. If you need to collect which CSS rules have been used on the server, you can do it during rendering:

```
let collectedRulesSet = new Set();



function useCSS(rule) {

  if (typeof window === 'undefined') {

    collectedRulesSet.add(rule);

  }

  useInsertionEffect(() => {

    // ...

  });

  return rule;

}
```

[Read more about upgrading CSS-in-JS libraries with runtime injection to `useInsertionEffect`.](https://github.com/reactwg/react-18/discussions/110)

##### Deep Dive#### How is this better than injecting styles during rendering or useLayoutEffect?[](#how-is-this-better-than-injecting-styles-during-rendering-or-uselayouteffect "Link for How is this better than injecting styles during rendering or useLayoutEffect? ")

If you insert styles during rendering and React is processing a [non-blocking update,](/reference/react/useTransition#perform-non-blocking-updates-with-actions) the browser will recalculate the styles every single frame while rendering a component tree, which can be **extremely slow.**

`useInsertionEffect` is better than inserting styles during [`useLayoutEffect`](/reference/react/useLayoutEffect) or [`useEffect`](/reference/react/useEffect) because it ensures that by the time other Effects run in your components, the `<style>` tags have already been inserted. Otherwise, layout calculations in regular Effects would be wrong due to outdated styles.

[PrevioususeImperativeHandle](/reference/react/useImperativeHandle)

[NextuseLayoutEffect](/reference/react/useLayoutEffect)

***

----
url: https://react.dev/reference/eslint-plugin-react-hooks/lints/config
----

[API Reference](/reference/react)

[Lints](/reference/eslint-plugin-react-hooks)

# config[](#undefined "Link for this heading")

Validates the compiler [configuration options](/reference/react-compiler/configuration).

## Rule Details[](#rule-details "Link for Rule Details ")

React Compiler accepts various [configuration options](/reference/react-compiler/configuration) to control its behavior. This rule validates that your configuration uses correct option names and value types, preventing silent failures from typos or incorrect settings.

### Invalid[](#invalid "Link for Invalid ")

Examples of incorrect code for this rule:

```
// ❌ Unknown option name

module.exports = {

  plugins: [

    ['babel-plugin-react-compiler', {

      compileMode: 'all' // Typo: should be compilationMode

    }]

  ]

};



// ❌ Invalid option value

module.exports = {

  plugins: [

    ['babel-plugin-react-compiler', {

      compilationMode: 'everything' // Invalid: use 'all' or 'infer'

    }]

  ]

};
```

### Valid[](#valid "Link for Valid ")

Examples of correct code for this rule:

```
// ✅ Valid compiler configuration

module.exports = {

  plugins: [

    ['babel-plugin-react-compiler', {

      compilationMode: 'infer',

      panicThreshold: 'critical_errors'

    }]

  ]

};
```

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### Configuration not working as expected[](#config-not-working "Link for Configuration not working as expected ")

Your compiler configuration might have typos or incorrect values:

```
// ❌ Wrong: Common configuration mistakes

module.exports = {

  plugins: [

    ['babel-plugin-react-compiler', {

      // Typo in option name

      compilationMod: 'all',

      // Wrong value type

      panicThreshold: true,

      // Unknown option

      optimizationLevel: 'max'

    }]

  ]

};
```

Check the [configuration documentation](/reference/react-compiler/configuration) for valid options:

```
// ✅ Better: Valid configuration

module.exports = {

  plugins: [

    ['babel-plugin-react-compiler', {

      compilationMode: 'all', // or 'infer'

      panicThreshold: 'none', // or 'critical_errors', 'all_errors'

      // Only use documented options

    }]

  ]

};
```

[Previouscomponent-hook-factories](/reference/eslint-plugin-react-hooks/lints/component-hook-factories)

[Nexterror-boundaries](/reference/eslint-plugin-react-hooks/lints/error-boundaries)

***

----
url: https://legacy.reactjs.org/docs/faq-styling.html
----

### [](#how-do-i-add-css-classes-to-components)How do I add CSS classes to components?

Pass a string as the `className` prop:

```
render() {
  return <span className="menu navigation-menu">Menu</span>
}
```

It is common for CSS classes to depend on the component props or state:

```
render() {
  let className = 'menu';
  if (this.props.isActive) {
    className += ' menu-active';
  }
  return <span className={className}>Menu</span>
}
```

> Tip
>
> If you often find yourself writing code like this, [classnames](https://www.npmjs.com/package/classnames#usage-with-reactjs) package can simplify it.

### [](#can-i-use-inline-styles)Can I use inline styles?

Yes, see the docs on styling [here](/docs/dom-elements.html#style).

### [](#are-inline-styles-bad)Are inline styles bad?

CSS classes are generally better for performance than inline styles.

### [](#what-is-css-in-js)What is CSS-in-JS?

“CSS-in-JS” refers to a pattern where CSS is composed using JavaScript instead of defined in external files.

*Note that this functionality is not a part of React, but provided by third-party libraries.* React does not have an opinion about how styles are defined; if in doubt, a good starting point is to define your styles in a separate `*.css` file as usual and refer to them using [`className`](/docs/dom-elements.html#classname).

### [](#can-i-do-animations-in-react)Can I do animations in React?

React can be used to power animations. See [React Transition Group](https://reactcommunity.org/react-transition-group/), [React Motion](https://github.com/chenglou/react-motion), [React Spring](https://github.com/react-spring/react-spring), or [Framer Motion](https://framer.com/motion), for example.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/faq-styling.md)

----
url: https://legacy.reactjs.org/blog/2015/11/02/react-v0.14.2.html
----

November 02, 2015 by [Paul O’Shannessy](https://twitter.com/zpao)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

We have a quick update following the release of 0.14.1 last week. It turns out we broke a couple things in the development build of React when using Internet Explorer. Luckily it was only the development build, so your production applications were unaffected. This release is mostly to address those issues. There is one notable change if consuming React from npm. For the `react-dom` package, we moved `react` from a regular dependency to a peer dependency. This will impact very few people as these two are typically installed together at the top level, but it will fix some issues with dependencies of installed components also using `react` as a peer dependency.

The release is now available for download:

* **React**\
  Dev build with warnings: <https://fb.me/react-0.14.2.js>\
  Minified build for production: <https://fb.me/react-0.14.2.min.js>
* **React with Add-Ons**\
  Dev build with warnings: <https://fb.me/react-with-addons-0.14.2.js>\
  Minified build for production: <https://fb.me/react-with-addons-0.14.2.min.js>
* **React DOM** (include React in the page before React DOM)\
  Dev build with warnings: <https://fb.me/react-dom-0.14.2.js>\
  Minified build for production: <https://fb.me/react-dom-0.14.2.min.js>

We’ve also published version `0.14.2` of the `react`, `react-dom`, and addons packages on npm and the `react` package on bower.

***

## [](#changelog)Changelog

### [](#react-dom)React DOM

* Fixed bug with development build preventing events from firing in some versions of Internet Explorer & Edge
* Fixed bug with development build when using es5-sham in older versions of Internet Explorer
* Added support for `integrity` attribute
* Fixed bug resulting in `children` prop being coerced to a string for custom elements, which was not the desired behavior.
* Moved `react` from `dependencies` to `peerDependencies` to match expectations and align with `react-addons-*` packages

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2015-11-02-react-v0.14.2.md)

----
url: https://legacy.reactjs.org/blog/2015/02/24/streamlining-react-elements.html
----

February 24, 2015 by [Sebastian Markbåge](https://twitter.com/sebmarkbage)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

React v0.13 is right around the corner and so we wanted to discuss some upcoming changes to ReactElement. In particular, we added several warnings to some esoteric use cases of ReactElement. There are no runtime behavior changes for ReactElement - we’re adding these warnings in the hope that we can change some behavior in v0.14 if the changes are valuable to the community.

If you use React in an idiomatic way, chances are, you’ll never see any of these warnings. In that case, you can skip this blog post. You can just enjoy the benefits! These changes will unlock simplified semantics, better error messages, stack traces and compiler optimizations!

## [](#immutable-props)Immutable Props

In React 0.12, the props object was mutable. It allows you to do patterns like this:

```
var element = <Foo bar={false} />;
if (shouldUseFoo) {
  element.props.foo = 10;
  element.props.bar = true;
}
```

The problem is that we don’t have a convenient way to tell when you’re done mutating.

### [](#problem-mutating-props-you-dont-own)Problem: Mutating Props You Don’t Own

If you mutate something, you destroy the original value. Therefore, there is nothing to diff against. Imagine something like this:

```
var element = this.props.child;
element.props.count = this.state.count;
return element;
```

You take a ReactElement through `props.child` and mutate its property before rendering it. If this component’s state updates, this render function won’t actually get a new ReactElement in `props.child`. It will be the same one. You’re mutating the same props.

You could imagine that this would work. However, this disables the ability for any component to use `shouldComponentUpdate`. It looks like the component never changed because the previous value is always the same as the next one. Since the DOM layer does diffing, this pattern doesn’t even work in this case. The change will never propagate down to the DOM except the first time.

Additionally, if this element is reused in other places or used to switch back and forth between two modes, then you have all kinds of weird race conditions.

It has always been broken to mutate the props of something passed into you. The problem is that we can’t warn you about this special case if you accidentally do this.

### [](#problem-too-late-validation)Problem: Too Late Validation

In React 0.12, we do PropType validation very deep inside React during mounting. This means that by the time you get an error, the debugger stack is long gone. This makes it difficult to find complex issues during debugging. We have to do this since it is fairly common for extra props to be added between the call to React.createElement and the mount time. So the type is incomplete until then.

The static analysis in Flow is also impaired by this. There is no convenient place in the code where Flow can determine that the props are finalized.

### [](#solution-immutable-props)Solution: Immutable Props

Therefore, we would like to be able to freeze the element.props object so that it is immediately immutable at the JSX callsite (or createElement). In React 0.13 we will start warning you if you mutate `element.props` after this point.

You can generally refactor these pattern to simply use two different JSX calls:

```
if (shouldUseFoo) {
  return <Foo foo={10} bar={true} />;
} else {
  return <Foo bar={false} />;
}
```

However, if you really need to dynamically build up your props you can just use a temporary object and spread it into JSX:

```
var props = { bar: false };
if (shouldUseFoo) {
  props.foo = 10;
  props.bar = true;
}
return <Foo {...props} />;
```

It is still OK to do deep mutations of objects. E.g:

```
return <Foo nestedObject={this.state.myModel} />;
```

In this case it’s still ok to mutate the myModel object in state. We recommend that you use fully immutable models. E.g. by using immutable-js. However, we realize that mutable models are still convenient in many cases. Therefore we’re only considering shallow freezing the props object that belongs to the ReactElement itself. Not nested objects.

### [](#solution-early-proptype-warnings)Solution: Early PropType Warnings

We will also start warning you for PropTypes at the JSX or createElement callsite. This will help debugging as you’ll have the stack trace right there. Similarly, Flow also validates PropTypes at this callsite.

Note: There are valid patterns that clones a ReactElement and adds additional props to it. In that case these additional props needs to be optional.

```
var element1 = <Foo />; // extra prop is optional
var element2 = React.addons.cloneWithProps(element1, { extra: 'prop' });
```

## [](#owner)Owner

In React each child has both a “parent” and an “owner”. The owner is the component that created a ReactElement. I.e. the render method which contains the JSX or createElement callsite.

```
class Foo {
  render() {
    return <div><span /></div>;
  }
}
```

In this example, the owner of the `span` is `Foo` but the parent is the `div`.

There is also an undocumented feature called “context” that also relies on the concept of an “owner” to pass hidden props down the tree.

### [](#problem-the-semantics-are-opaque-and-confusing)Problem: The Semantics are Opaque and Confusing

The problem is that these are hidden artifacts attached to the ReactElement. In fact, you probably didn’t even know about it. It silently changes semantics. Take this for example:

```
var foo = <input className="foo" />;
class Component {
  render() {
    return bar ? <input className="bar" /> : foo;
  }
}
```

These two inputs have different owners, therefore React will not keep its state when the conditional switches. There is nothing in the code to indicate that. Similarly, if you use `React.addons.cloneWithProps`, the owner changes.

### [](#problem-timing-matters)Problem: Timing Matters

The owner is tracked by the currently executing stack. This means that the semantics of a ReactElement varies depending on when it is executed. Take this example:

```
class A {
  render() {
    return <B renderer={text => <span>{text}</span>} />;
  }
}
class B {
  render() {
    return this.props.renderer('foo');
  }
}
```

The owner of the `span` is actually `B`, not `A` because of the timing of the callback. This all adds complexity and suffers from similar problems as mutation.

### [](#problem-it-couples-jsx-to-react)Problem: It Couples JSX to React

Have you wondered why JSX depends on React? Couldn’t the transpiler have that built-in to its runtime? The reason you need to have `React.createElement` in scope is because we depend on internal state of React to capture the current “owner”. Without this, you wouldn’t need to have React in scope.

### [](#solution-make-context-parent-based-instead-of-owner-based)Solution: Make Context Parent-Based Instead of Owner-Based

The first thing we’re doing is warning you if you’re using the “owner” feature in a way that relies on it propagating through owners. Instead, we’re planning on propagating it through parents to its children. In almost all cases, this shouldn’t matter. In fact, parent-based contexts is simply a superset.

### [](#solution-remove-the-semantic-implications-of-owner)Solution: Remove the Semantic Implications of Owner

It turns out that there are very few cases where owners are actually important part of state-semantics. As a precaution, we’ll warn you if it turns out that the owner is important to determine state. In almost every case this shouldn’t matter. Unless you’re doing some weird optimizations, you shouldn’t see this warning.

### [](#pending-change-the-refs-semantics)Pending: Change the refs Semantics

Refs are still based on “owner”. We haven’t fully solved this special case just yet.

In 0.13 we introduced a new callback-refs API that doesn’t suffer from these problems but we’ll keep on a nice declarative alternative to the current semantics for refs. As always, we won’t deprecate something until we’re sure that you’ll have a nice upgrade path.

## [](#keyed-objects-as-maps)Keyed Objects as Maps

In React 0.12, and earlier, you could use keyed objects to provide an external key to an element or a set. This pattern isn’t actually widely used. It shouldn’t be an issue for most of you.

```
<div>{ {a: <span />, b: <span />} }</div>
```

### [](#problem-relies-on-enumeration-order)Problem: Relies on Enumeration Order

The problem with this pattern is that it relies on enumeration order of objects. This is technically unspecified, even though implementations now agree to use insertion order. Except for the special case when numeric keys are used.

### [](#problem-using-objects-as-maps-is-bad)Problem: Using Objects as Maps is Bad

It is generally accepted that using objects as maps screw up type systems, VM optimizations, compilers etc. It is much better to use a dedicated data structure like ES6 Maps.

More importantly, this can have important security implications. For example this has a potential security problem:

```
var children = {};
items.forEach(item => children[item.title] = <span />);
return <div>{children}</div>;
```

Imagine if `item.title === '__proto__'` for example.

### [](#problem-cant-be-differentiated-from-arbitrary-objects)Problem: Can’t be Differentiated from Arbitrary Objects

Since these objects can have any keys with almost any value, we can’t differentiate them from a mistake. If you put some random object, we will try our best to traverse it and render it, instead of failing with a helpful warning. In fact, this is one of the few places where you can accidentally get an infinite loop in React.

To differentiate ReactElements from one of these objects, we have to tag them with `_isReactElement`. This is another issue preventing us from inlining ReactElements as simple object literals.

### [](#solution-just-use-an-array-and-key)Solution: Just use an Array and key={…}

Most of the time you can just use an array with keyed ReactElements.

```
var children = items.map(item => <span key={item.title} />);
<div>{children}</div>
```

### [](#solution-reactaddonscreatefragment)Solution: React.addons.createFragment

However, this is not always possible if you’re trying to add a prefix key to an unknown set (e.g. this.props.children). It is also not always the easiest upgrade path. Therefore, we are adding a helper to `React.addons` called `createFragment()`. This accepts a keyed object and returns an opaque type.

```
<div>{React.addons.createFragment({ a: <div />, b: this.props.children })}</div>
```

The exact signature of this kind of fragment will be determined later. It will likely be some kind of immutable sequence.

Note: This will still not be valid as the direct return value of `render()`. Unfortunately, they still need to be wrapped in a `<div />` or some other element.

## [](#compiler-optimizations-unlocked)Compiler Optimizations: Unlocked!

These changes also unlock several possible compiler optimizations for static content in React 0.14. These optimizations were previously only available to template-based frameworks. They will now also be possible for React code! Both for JSX and `React.createElement/Factory`\*!

See these GitHub Issues for a deep dive into compiler optimizations:

* [Reuse Constant Value Types](https://github.com/facebook/react/issues/3226)
* [Tagging ReactElements](https://github.com/facebook/react/issues/3227)
* [Inline ReactElements](https://github.com/facebook/react/issues/3228)

\* If you use the recommended pattern of explicit React.createFactory calls on the consumer side - since they are easily statically analyzed.

## [](#rationale)Rationale

I thought that these changes were particularly important because the mere existence of these patterns means that even components that DON’T use these patterns have to pay the price. There are other problematic patterns such as mutating state, but they’re at least localized to a component subtree so they don’t harm the ecosystem.

As always, we’d love to hear your feedback and if you have any trouble upgrading, please let us know.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2015-02-24-streamlining-react-elements.md)

----
url: https://legacy.reactjs.org/blog/2013/12/23/community-roundup-12.html
----

December 23, 2013 by [Vjeux](https://twitter.com/vjeux)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

React got featured on the front-page of Hacker News thanks to the Om library. If you try it out for the first time, take a look at the [docs](/docs/getting-started.html) and do not hesitate to ask questions on the [Google Group](https://groups.google.com/group/reactjs), [IRC](irc://chat.freenode.net/reactjs) or [Stack Overflow](http://stackoverflow.com/questions/tagged/reactjs). We are trying our best to help you out!

## [](#the-future-of-javascript-mvc)The Future of JavaScript MVC

[David Nolen](https://swannodette.github.io/) announced Om, a thin wrapper on-top of React in ClojureScript. It stands out by only using immutable data structures. This unlocks the ability to write a very efficient [shouldComponentUpdate](/docs/component-specs.html#updating-shouldcomponentupdate) and get huge performance improvements on some tasks.

> We’ve known this for some time over here in the ClojureScript corner of the world - all of our collections are immutable and modeled directly on the original Clojure versions written in Java. Modern JavaScript engines have now been tuned to the point that it’s no longer uncommon to see collection performance within 2.5X of the Java Virtual Machine.
>
> Wait, wait, wait. What does the performance of persistent data structures have to do with the future of JavaScript MVCs?
>
> A whole lot.
>
> [](https://swannodette.github.io/2013/12/17/the-future-of-javascript-mvcs/)
>
> [Read the full article…](https://swannodette.github.io/2013/12/17/the-future-of-javascript-mvcs/)

## [](#scroll-position-with-react)Scroll Position with React

Managing the scroll position when new content is inserted is usually very tricky to get right. [Vjeux](http://blog.vjeux.com/) discovered that [componentWillUpdate](/docs/component-specs.html#updating-componentwillupdate) and [componentDidUpdate](/docs/component-specs.html#updating-componentdidupdate) were triggered exactly at the right time to manage the scroll position.

> We can check the scroll position before the component has updated with componentWillUpdate and scroll if necessary at componentDidUpdate
>
> ```
> componentWillUpdate: function() {
>   var node = this.getDOMNode();
>   this.shouldScrollBottom =
>     (node.scrollTop + node.offsetHeight) === node.scrollHeight;
> },
> componentDidUpdate: function() {
>   if (this.shouldScrollBottom) {
>     var node = this.getDOMNode();
>     node.scrollTop = node.scrollHeight
>   }
> },
> ```
>
> [Check out the blog article…](http://blog.vjeux.com/2013/javascript/scroll-position-with-react.html)

## [](#lights-out)Lights Out

React declarative approach is well suited to write games. [Cheng Lou](https://github.com/chenglou) wrote the famous Lights Out game in React. It’s a good example of use of [TransitionGroup](/docs/animation.html) to implement animations.

[](https://chenglou.github.io/react-lights-out/)

[Try it out!](https://chenglou.github.io/react-lights-out/)

## [](#reactive-table-bookmarklet)Reactive Table Bookmarklet

[Stoyan Stefanov](http://www.phpied.com/) wrote a bookmarklet to process tables on the internet. It adds a little “pop” button that expands to a full-screen view with sorting, editing and export to csv and json.

[](http://www.phpied.com/reactivetable-bookmarklet/)

[Check out the blog post…](http://www.phpied.com/reactivetable-bookmarklet/)

## [](#montagejs-tutorial-in-react)MontageJS Tutorial in React

[Ross Allen](https://twitter.com/ssorallen) implemented [MontageJS](http://montagejs.org/)’s [Reddit tutorial](http://montagejs.org/docs/tutorial-reddit-client-with-montagejs.html) in React. This is a good opportunity to compare the philosophies of the two libraries.

[View the source on JSFiddle…](https://jsfiddle.net/ssorallen/fEsYt/)

## [](#writing-good-react-components)Writing Good React Components

[William Högman Rudenmalm](http://blog.whn.se/) wrote an article on how to write good React components. This is full of good advice.

> The idea of dividing software into smaller parts or components is hardly new - It is the essance of good software. The same principles that apply to software in general apply to building React components. That doesn’t mean that writing good React components is just about applying general rules.
>
> The web offers a unique set of challenges, which React offers interesting solutions to. First and foremost among these solutions is the what is called the Mock DOM. Rather than having user code interface with the DOM in a direct fashion, as is the case with most DOM manipulation libraries.
>
> You build a model of how you want the DOM end up like. React then inserts this model into the DOM. This is very useful for updates because React simply compares the model or mock DOM against the actual DOM, and then only updates based on the difference between the two states.
>
> [Read the full article …](http://blog.whn.se/post/69621609605/writing-good-react-components)

## [](#hoodie-react-todomvc)Hoodie React TodoMVC

[Sven Lito](http://svenlito.com/) integrated the React TodoMVC example within an [Hoodie](http://hood.ie/) web app environment. This should let you get started using Hoodie and React.

```
hoodie new todomvc -t "hoodiehq/hoodie-react-todomvc"
```

[Check out on GitHub…](https://github.com/hoodiehq/hoodie-react-todomvc)

## [](#jsx-compiler)JSX Compiler

Ever wanted to have a quick way to see what a JSX tag would be converted to? [Tim Yung](http://www.yungsters.com/) made a page for it.

[](/react/jsx-compiler.html)

[Try it out!](/jsx-compiler.html)

## [](#random-tweet)Random Tweet

> .[@jordwalke](https://twitter.com/jordwalke) lays down some truth <http://t.co/AXAn0UlUe3>, optimizing your JS application shouldn't force you to rewrite so much code [#reactjs](https://twitter.com/search?q=%23reactjs\&src=hash)
>
> — David Nolen (@swannodette) [December 19, 2013](https://twitter.com/swannodette/statuses/413780079249215488)

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2013-12-23-community-roundup-12.md)

----
url: https://legacy.reactjs.org/blog/2013/12/30/community-roundup-13.html
----

December 30, 2013 by [Vjeux](https://twitter.com/vjeux)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

Happy holidays! This blog post is a little-late Christmas present for all the React users. Hopefully it will inspire you to write awesome web apps in 2014!

## [](#react-touch)React Touch

[Pete Hunt](http://www.petehunt.net/) wrote three demos showing that React can be used to run 60fps native-like experiences on mobile web. A frosted glass effect, an image gallery with 3d animations and an infinite scroll view.

[Try out the demos!](https://petehunt.github.io/react-touch/)

## [](#introduction-to-react)Introduction to React

[Stoyan Stefanov](http://www.phpied.com/) talked at Joe Dev On Tech about React. He goes over all the features of the library and ends with a concrete example.

## [](#jsx-e4x-the-good-parts)JSX: E4X The Good Parts

JSX is often compared to the now defunct E4X, [Vjeux](http://blog.vjeux.com/) went over all the E4X features and explained how JSX is different and hopefully doesn’t repeat the same mistakes.

> E4X (ECMAScript for XML) is a JavaScript syntax extension and a runtime to manipulate XML. It was promoted by Mozilla but failed to become mainstream and is now deprecated. JSX was inspired by E4X. In this article, I’m going to go over all the features of E4X and explain the design decisions behind JSX.
>
> **Historical Context**
>
> E4X has been created in 2002 by John Schneider. This was the golden age of XML where it was being used for everything: data, configuration files, code, interfaces (DOM) … E4X was first implemented inside of Rhino, a JavaScript implementation from Mozilla written in Java.
>
> [Continue reading …](http://blog.vjeux.com/2013/javascript/jsx-e4x-the-good-parts.html)

## [](#react--socketio)React + Socket.io

[Geert Pasteels](http://enome.be/nl) made a small experiment with Socket.io. He wrote a very small mixin that synchronizes React state with the server. Just include this mixin to your React component and it is now live!

```
changeHandler: function (data) {
  if (!_.isEqual(data.state, this.state) && this.path === data.path) {
    this.setState(data.state);
  }
},
componentDidMount: function (root) {
  this.path = utils.nodePath(root);
  socket.on('component-change', this.changeHandler);
},
componentWillUpdate: function (props, state) {
  socket.emit('component-change', { path: this.path, state: state });
},
componentWillUnmount: function () {
  socket.removeListener('component-change', this.change);
}
```

[Check it out on GitHub…](https://github.com/Enome/react.io)

## [](#cssobjectify)cssobjectify

[Andrey Popp](http://andreypopp.com/) implemented a source transform that takes a CSS file and converts it to JSON. This integrates pretty nicely with React.

```
/* style.css */
MyComponent {
  font-size: 12px;
  background-color: red;
}

/* myapp.js */
var React = require('react-tools/build/modules/React');
var Styles = require('./styles.css');

var MyComponent = React.createClass({
  render: function() {
    return (
      <div style={Styles.MyComponent}>
        Hello, world!
      </div>
    )
  }
});
```

[Check it out on GitHub…](https://github.com/andreypopp/cssobjectify)

## [](#ngreact)ngReact

[David Chang](http://davidandsuzi.com/) working at [HasOffer](http://www.hasoffers.com/) wanted to speed up his Angular app and replaced Angular primitives by React at different layers. When using React naively it is 67% faster, but when combining it with angular’s transclusion it is 450% slower.

> Rendering this takes 803ms for 10 iterations, hovering around 35 and 55ms for each data reload (that’s 67% faster). You’ll notice that the first load takes a little longer than successive loads, and the second load REALLY struggles - here, it’s 433ms, which is more than half of the total time!
>
> [](http://davidandsuzi.com/ngreact-react-components-in-angular/)
>
> [Read the full article…](http://davidandsuzi.com/ngreact-react-components-in-angular/)

## [](#vim-jsx)vim-jsx

[Max Wang](https://github.com/mxw) made a vim syntax highlighting and indentation plugin for vim.

> Syntax highlighting and indenting for JSX. JSX is a JavaScript syntax transformer which translates inline XML document fragments into JavaScript objects. It was developed by Facebook alongside React.
>
> This bundle requires pangloss’s [vim-javascript](https://github.com/pangloss/vim-javascript) syntax highlighting.
>
> Vim support for inline XML in JS is remarkably similar to the same for PHP.
>
> [View on GitHub…](https://github.com/mxw/vim-jsx)

## [](#random-tweet)Random Tweet

> I may be starting to get annoying with this, but ReactJS is really exciting. I truly feel the virtual DOM is a game changer.
>
> — Eric Florenzano (@ericflo) [December 20, 2013](https://twitter.com/ericflo/statuses/413842834974732288)

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2013-12-30-community-roundup-13.md)

----
url: https://react.dev/reference/react-dom/components
----

[API Reference](/reference/react)

# React DOM Components[](#undefined "Link for this heading")

React supports all of the browser built-in [HTML](https://developer.mozilla.org/en-US/docs/Web/HTML/Element) and [SVG](https://developer.mozilla.org/en-US/docs/Web/SVG/Element) components.

***

## Common components[](#common-components "Link for Common components ")

All of the built-in browser components support some props and events.

* [Common components (e.g. `<div>`)](/reference/react-dom/components/common)

This includes React-specific props like `ref` and `dangerouslySetInnerHTML`.

***

## Form components[](#form-components "Link for Form components ")

These built-in browser components accept user input:

* [`<input>`](/reference/react-dom/components/input)
* [`<select>`](/reference/react-dom/components/select)
* [`<textarea>`](/reference/react-dom/components/textarea)

They are special in React because passing the `value` prop to them makes them *[controlled.](/reference/react-dom/components/input#controlling-an-input-with-a-state-variable)*

***

***

***

### Custom HTML elements[](#custom-html-elements "Link for Custom HTML elements ")

If you render a tag with a dash, like `<my-element>`, React will assume you want to render a [custom HTML element.](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements)

If you render a built-in browser HTML element with an [`is`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/is) attribute, it will also be treated as a custom element.

#### Setting values on custom elements[](#attributes-vs-properties "Link for Setting values on custom elements ")

Custom elements have two methods of passing data into them:

1. Attributes: Which are displayed in markup and can only be set to string values
2. Properties: Which are not displayed in markup and can be set to arbitrary JavaScript values

By default, React will pass values bound in JSX as attributes:

```
<my-element value="Hello, world!"></my-element>
```

Non-string JavaScript values passed to custom elements will be serialized by default:

```
// Will be passed as `"1,2,3"` as the output of `[1,2,3].toString()`

<my-element value={[1,2,3]}></my-element>
```

React will, however, recognize an custom element’s property as one that it may pass arbitrary values to if the property name shows up on the class during construction:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
export class MyElement extends HTMLElement {
  constructor() {
    super();
    // The value here will be overwritten by React
    // when initialized as an element
    this.value = undefined;
  }

  connectedCallback() {
    this.innerHTML = this.value.join(", ");
  }
}
```

#### Listening for events on custom elements[](#custom-element-events "Link for Listening for events on custom elements ")

A common pattern when using custom elements is that they may dispatch [`CustomEvent`s](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent) rather than accept a function to call when an event occur. You can listen for these events using an `on` prefix when binding to the event via JSX.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
export function App() {
  return (
    <my-element
      onspeak={e => console.log(e.detail.message)}
    ></my-element>
  )
}
```

### Note

Events are case-sensitive and support dashes (`-`). Preserve the casing of the event and include all dashes when listening for custom element’s events:

```
// Listens for `say-hi` events

<my-element onsay-hi={console.log}></my-element>

// Listens for `sayHi` events

<my-element onsayHi={console.log}></my-element>
```

***

***

----
url: https://react.dev/learn/react-developer-tools
----

[Learn React](/learn)

[Setup](/learn/setup)

```
# Yarn

yarn global add react-devtools



# Npm

npm install -g react-devtools
```

Next open the developer tools from the terminal:

```
react-devtools
```

Then connect your website by adding the following `<script>` tag to the beginning of your website’s `<head>`:

```
<html>

  <head>

    <script src="http://localhost:8097"></script>
```

Reload your website in the browser now to view it in developer tools.

## Mobile (React Native)[](#mobile-react-native "Link for Mobile (React Native) ")

To inspect apps built with [React Native](https://reactnative.dev/), you can use [React Native DevTools](https://reactnative.dev/docs/react-native-devtools), the built-in debugger that deeply integrates React Developer Tools. All features work identically to the browser extension, including native element highlighting and selection.

[Learn more about debugging in React Native.](https://reactnative.dev/docs/debugging)

> For versions of React Native earlier than 0.76, please use the standalone build of React DevTools by following the [Safari and other browsers](#safari-and-other-browsers) guide above.

[PreviousUsing TypeScript](/learn/typescript)

[NextReact Compiler](/learn/react-compiler)

***

----
url: https://react.dev/reference/eslint-plugin-react-hooks/lints/gating
----

[API Reference](/reference/react)

[Lints](/reference/eslint-plugin-react-hooks)

# gating[](#undefined "Link for this heading")

Validates configuration of [gating mode](/reference/react-compiler/gating).

## Rule Details[](#rule-details "Link for Rule Details ")

Gating mode lets you gradually adopt React Compiler by marking specific components for optimization. This rule ensures your gating configuration is valid so the compiler knows which components to process.

### Invalid[](#invalid "Link for Invalid ")

Examples of incorrect code for this rule:

```
// ❌ Missing required fields

module.exports = {

  plugins: [

    ['babel-plugin-react-compiler', {

      gating: {

        importSpecifierName: '__experimental_useCompiler'

        // Missing 'source' field

      }

    }]

  ]

};



// ❌ Invalid gating type

module.exports = {

  plugins: [

    ['babel-plugin-react-compiler', {

      gating: '__experimental_useCompiler' // Should be object

    }]

  ]

};
```

### Valid[](#valid "Link for Valid ")

Examples of correct code for this rule:

```
// ✅ Complete gating configuration

module.exports = {

  plugins: [

    ['babel-plugin-react-compiler', {

      gating: {

        importSpecifierName: 'isCompilerEnabled', // exported function name

        source: 'featureFlags' // module name

      }

    }]

  ]

};



// featureFlags.js

export function isCompilerEnabled() {

  // ...

}



// ✅ No gating (compile everything)

module.exports = {

  plugins: [

    ['babel-plugin-react-compiler', {

      // No gating field - compiles all components

    }]

  ]

};
```

[Previouserror-boundaries](/reference/eslint-plugin-react-hooks/lints/error-boundaries)

[Nextglobals](/reference/eslint-plugin-react-hooks/lints/globals)

***

----
url: https://legacy.reactjs.org/blog/2016/01/08/A-implies-B-does-not-imply-B-implies-A.html
----

January 08, 2016 by [Jim Sproch](http://www.jimsproch.com)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

The documentation for `componentWillReceiveProps` states that `componentWillReceiveProps` will be invoked when the props change as the result of a rerender. Some people assume this means “if `componentWillReceiveProps` is called, then the props must have changed”, but that conclusion is logically incorrect.

The guiding principle is one of my favorites from formal logic/mathematics:

> A implies B does not imply B implies A

Example: “If I eat moldy food, then I will get sick” does not imply “if I am sick, then I must have eaten moldy food”. There are many other reasons I could be feeling sick. For instance, maybe the flu is circulating around the office. Similarly, there are many reasons that `componentWillReceiveProps` might get called, even if the props didn’t change.

If you don’t believe me, call `ReactDOM.render()` three times with the exact same props, and try to predict the number of times `componentWillReceiveProps` will get called:

```
class Component extends React.Component {
  componentWillReceiveProps(nextProps) {
    console.log('componentWillReceiveProps', nextProps.data.bar);
  }
  render() {
    return <div>Bar {this.props.data.bar}!</div>;
  }
}

var container = document.getElementById('container');

var mydata = {bar: 'drinks'};
ReactDOM.render(<Component data={mydata} />, container);
ReactDOM.render(<Component data={mydata} />, container);
ReactDOM.render(<Component data={mydata} />, container);
```

In this case, the answer is “2”. React calls `componentWillReceiveProps` twice (once for each of the two updates). Both times, the value of “drinks” is printed (ie. the props didn’t change).

To understand why, we need to think about what *could* have happened. The data *could* have changed between the initial render and the two subsequent updates, if the code had performed a mutation like this:

```
var mydata = {bar: 'drinks'};
ReactDOM.render(<Component data={mydata} />, container);
mydata.bar = 'food'
ReactDOM.render(<Component data={mydata} />, container);
mydata.bar = 'noise'
ReactDOM.render(<Component data={mydata} />, container);
```

React has no way of knowing that the data didn’t change. Therefore, React needs to call `componentWillReceiveProps`, because the component needs to be notified of the new props (even if the new props happen to be the same as the old props).

You might think that React could just use smarter checks for equality, but there are some issues with this idea:

* The old `mydata` and the new `mydata` are actually the same physical object (only the object’s internal value changed). Since the references are triple-equals-equal, doing an equality check doesn’t tell us if the value has changed. The only possible solution would be to have created a deep copy of the data, and then later do a deep comparison - but this can be prohibitively expensive for large data structures (especially ones with cycles).
* The `mydata` object might contain references to functions which have captured variables within closures. There is no way for React to peek into these closures, and thus no way for React to copy them and/or verify equality.
* The `mydata` object might contain references to objects which are re-instantiated during the parent’s render (ie. not triple-equals-equal) but are conceptually equal (ie. same keys and same values). A deep-compare (expensive) could detect this, except that functions present a problem again because there is no reliable way to compare two functions to see if they are semantically equivalent.

Given the language constraints, it is sometimes impossible for us to achieve meaningful equality semantics. In such cases, React will call `componentWillReceiveProps` (even though the props might not have changed) so the component has an opportunity to examine the new props and act accordingly.

As a result, your implementation of `componentWillReceiveProps` MUST NOT assume that your props have changed. If you want an operation (such as a network request) to occur only when props have changed, your `componentWillReceiveProps` code needs to check to see if the props actually changed.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2016-01-08-A-implies-B-does-not-imply-B-implies-A.md)

----
url: https://legacy.reactjs.org/blog/2014/02/20/react-v0.9.html
----

February 20, 2014 by [Sophie Alpert](https://sophiebits.com/)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

I’m excited to announce that today we’re releasing React v0.9, which incorporates many bug fixes and several new features since the last release. This release contains almost four months of work, including over 800 commits from over 70 committers!

Thanks to everyone who tested the release candidate; we were able to find and fix an error in the event handling code, we upgraded envify to make running browserify on React faster, and we added support for five new attributes.

As always, the release is available for download from the CDN:

* **React**\
  Dev build with warnings: <https://fb.me/react-0.9.0.js>\
  Minified build for production: <https://fb.me/react-0.9.0.min.js>
* **React with Add-Ons**\
  Dev build with warnings: <https://fb.me/react-with-addons-0.9.0.js>\
  Minified build for production: <https://fb.me/react-with-addons-0.9.0.min.js>
* **In-Browser JSX Transformer**\
  <https://fb.me/JSXTransformer-0.9.0.js>

We’ve also published version `0.9.0` of the `react` and `react-tools` packages on npm and the `react` package on bower.

## [](#whats-new)What’s New?

This version includes better support for normalizing event properties across all supported browsers so that you need to worry even less about cross-browser differences. We’ve also made many improvements to error messages and have refactored the core to never rethrow errors, so stack traces are more accurate and Chrome’s purple break-on-error stop sign now works properly.

We’ve also added to the add-ons build [React.addons.TestUtils](/docs/test-utils.html), a set of new utilities to help you write unit tests for React components. You can now simulate events on your components, and several helpers are provided to help make assertions about the rendered DOM tree.

We’ve also made several other improvements and a few breaking changes; the full changelog is provided below.

## [](#jsx-whitespace)JSX Whitespace

In addition to the changes to React core listed below, we’ve made a small change to the way JSX interprets whitespace to make things more consistent. With this release, space between two components on the same line will be preserved, while a newline separating a text node from a tag will be eliminated in the output. Consider the code:

```
<div>
  Monkeys:
  {listOfMonkeys} {submitButton}
</div>
```

In v0.8 and below, it was transformed to the following:

```
React.DOM.div(null,
  " Monkeys: ",
  listOfMonkeys, submitButton
)
```

In v0.9, it will be transformed to this JS instead:

```
React.DOM.div(null,
  "Monkeys:",  listOfMonkeys, " ", submitButton)
```

We believe this new behavior is more helpful and eliminates cases where unwanted whitespace was previously added.

In cases where you want to preserve the space adjacent to a newline, you can write `{'Monkeys: '}` or `Monkeys:{' '}` in your JSX source. We’ve included a script to do an automated codemod of your JSX source tree that preserves the old whitespace behavior by adding and removing spaces appropriately. You can [install jsx\_whitespace\_transformer from npm](https://github.com/facebook/react/blob/main/npm-jsx_whitespace_transformer/README.md) and run it over your source tree to modify files in place. The transformed JSX files will preserve your code’s existing whitespace behavior.

* When prop types validation fails, a warning is logged instead of an error thrown (with the production build of React, type checks are now skipped for performance)
* On `input`, `select`, and `textarea` elements, `.getValue()` is no longer supported; use `.getDOMNode().value` instead
* `this.context` on components is now reserved for internal use by React

#### [](#new-features)New Features

* React now never rethrows errors, so stack traces are more accurate and Chrome’s purple break-on-error stop sign now works properly

* Added support for SVG tags `defs`, `linearGradient`, `polygon`, `radialGradient`, `stop`

* Added support for more attributes:

  * `crossOrigin` for CORS requests
  * `download` and `hrefLang` for `<a>` tags
  * `mediaGroup` and `muted` for `<audio>` and `<video>` tags

* Boolean attributes such as `disabled` are rendered without a value (previously `disabled="true"`, now simply `disabled`)

* `React.addons.TestUtils` was added to help write unit tests

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2014-02-20-react-v0.9.md)

----
url: https://react.dev/reference/react-dom/preinit
----

[API Reference](/reference/react)

[APIs](/reference/react-dom)

# preinit[](#undefined "Link for this heading")

### Note

[React-based frameworks](/learn/creating-a-react-app) frequently handle resource loading for you, so you might not have to call this API yourself. Consult your framework’s documentation for details.

`preinit` lets you eagerly fetch and evaluate a stylesheet or external script.

```
preinit("https://example.com/script.js", {as: "script"});
```

* [Reference](#reference)
  * [`preinit(href, options)`](#preinit)

* [Usage](#usage)

  * [Preiniting when rendering](#preiniting-when-rendering)
  * [Preiniting in an event handler](#preiniting-in-an-event-handler)

***

## Reference[](#reference "Link for Reference ")

### `preinit(href, options)`[](#preinit "Link for this heading")

To preinit a script or stylesheet, call the `preinit` function from `react-dom`.

```
import { preinit } from 'react-dom';



function AppRoot() {

  preinit("https://example.com/script.js", {as: "script"});

  // ...

}
```

  * `crossOrigin`: a string. The [CORS policy](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/crossorigin) to use. Its possible values are `anonymous` and `use-credentials`.

***

## Usage[](#usage "Link for Usage ")

### Preiniting when rendering[](#preiniting-when-rendering "Link for Preiniting when rendering ")

Call `preinit` when rendering a component if you know that it or its children will use a specific resource, and you’re OK with the resource being evaluated and thereby taking effect immediately upon being downloaded.

#### Examples of preiniting[](#examples "Link for Examples of preiniting")

#### Example 1 of 2:Preiniting an external script[](#preiniting-an-external-script "Link for this heading")

```
import { preinit } from 'react-dom';



function AppRoot() {

  preinit("https://example.com/script.js", {as: "script"});

  return ...;

}
```

If you want the browser to download the script but not to execute it right away, use [`preload`](/reference/react-dom/preload) instead. If you want to load an ESM module, use [`preinitModule`](/reference/react-dom/preinitModule).

### Preiniting in an event handler[](#preiniting-in-an-event-handler "Link for Preiniting in an event handler ")

Call `preinit` in an event handler before transitioning to a page or state where external resources will be needed. This gets the process started earlier than if you call it during the rendering of the new page or state.

```
import { preinit } from 'react-dom';



function CallToAction() {

  const onClick = () => {

    preinit("https://example.com/wizardStyles.css", {as: "style"});

    startWizard();

  }

  return (

    <button onClick={onClick}>Start Wizard</button>

  );

}
```

[PreviousprefetchDNS](/reference/react-dom/prefetchDNS)

[NextpreinitModule](/reference/react-dom/preinitModule)

***

----
url: https://legacy.reactjs.org/blog/2013/07/30/use-react-and-jsx-in-ruby-on-rails.html
----

July 30, 2013 by [Paul O’Shannessy](https://twitter.com/zpao)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

Today we’re releasing a gem to make it easier to use React and JSX in Ruby on Rails applications: [react-rails](https://github.com/facebook/react-rails).

This gem has 2 primary purposes:

1. To package `react.js` in a way that’s easy to use and easy to update.
2. To allow you to write JSX without an external build step to transform that into JS.

## [](#packaging-reactjs)Packaging react.js

To make `react.js` available for use client-side, simply add `react` to your manifest, and declare the variant you’d like to use in your environment. When you use `:production`, the minified and optimized `react.min.js` will be used instead of the development version. For example:

```
# config/environments/development.rb

MyApp::Application.configure do
  config.react.variant = :development
  # use :production in production.rb
end
```

```
// app/assets/javascript/application.js

//= require react
```

## [](#writing-jsx)Writing JSX

When you name your file with `myfile.js.jsx`, `react-rails` will automatically try to transform that file. For the time being, we still require that you include the docblock at the beginning of the file. For example, this file will get transformed on request.

```
/** @jsx React.DOM */
React.renderComponent(<MyComponent/>, document.getElementById('example'))
```

## [](#asset-pipeline)Asset Pipeline

`react-rails` takes advantage of the [asset pipeline](http://guides.rubyonrails.org/asset_pipeline.html) that was introduced in Rails 3.1. A very important part of that pipeline is the `assets:precompile` Rake task. `react-rails` will ensure that your JSX files will be transformed into regular JS before all of your assets are minified and packaged.

## [](#installation)Installation

Installation follows the same process you’re familiar with. You can install it globally with `gem install react-rails`, though we suggest you add the dependency to your `Gemfile` directly.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2013-07-30-use-react-and-jsx-in-ruby-on-rails.md)

----
url: https://react.dev/reference/react/useMemo
----

[API Reference](/reference/react)

[Hooks](/reference/react/hooks)

# useMemo[](#undefined "Link for this heading")

`useMemo` is a React Hook that lets you cache the result of a calculation between re-renders.

```
const cachedValue = useMemo(calculateValue, dependencies)
```

### Note

[React Compiler](/learn/react-compiler) automatically memoizes values and functions, reducing the need for manual `useMemo` calls. You can use the compiler to handle memoization automatically.

***

## Reference[](#reference "Link for Reference ")

### `useMemo(calculateValue, dependencies)`[](#usememo "Link for this heading")

Call `useMemo` at the top level of your component to cache a calculation between re-renders:

```
import { useMemo } from 'react';



function TodoList({ todos, tab }) {

  const visibleTodos = useMemo(

    () => filterTodos(todos, tab),

    [todos, tab]

  );

  // ...

}
```

***

## Usage[](#usage "Link for Usage ")

### Skipping expensive recalculations[](#skipping-expensive-recalculations "Link for Skipping expensive recalculations ")

To cache a calculation between re-renders, wrap it in a `useMemo` call at the top level of your component:

```
import { useMemo } from 'react';



function TodoList({ todos, tab, theme }) {

  const visibleTodos = useMemo(() => filterTodos(todos, tab), [todos, tab]);

  // ...

}
```

```
function TodoList({ todos, tab, theme }) {

  const visibleTodos = filterTodos(todos, tab);

  // ...

}
```

Usually, this isn’t a problem because most calculations are very fast. However, if you’re filtering or transforming a large array, or doing some expensive computation, you might want to skip doing it again if data hasn’t changed. If both `todos` and `tab` are the same as they were during the last render, wrapping the calculation in `useMemo` like earlier lets you reuse `visibleTodos` you’ve already calculated before.

This type of caching is called *[memoization.](https://en.wikipedia.org/wiki/Memoization)*

### Note

**You should only rely on `useMemo` as a performance optimization.** If your code doesn’t work without it, find the underlying problem and fix it first. Then you may add `useMemo` to improve performance.

##### Deep Dive#### How to tell if a calculation is expensive?[](#how-to-tell-if-a-calculation-is-expensive "Link for How to tell if a calculation is expensive? ")

In general, unless you’re creating or looping over thousands of objects, it’s probably not expensive. If you want to get more confidence, you can add a console log to measure the time spent in a piece of code:

```
console.time('filter array');

const visibleTodos = filterTodos(todos, tab);

console.timeEnd('filter array');
```

Perform the interaction you’re measuring (for example, typing into the input). You will then see logs like `filter array: 0.15ms` in your console. If the overall logged time adds up to a significant amount (say, `1ms` or more), it might make sense to memoize that calculation. As an experiment, you can then wrap the calculation in `useMemo` to verify whether the total logged time has decreased for that interaction or not:

```
console.time('filter array');

const visibleTodos = useMemo(() => {

  return filterTodos(todos, tab); // Skipped if todos and tab haven't changed

}, [todos, tab]);

console.timeEnd('filter array');
```

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useMemo } from 'react';
import { filterTodos } from './utils.js'

export default function TodoList({ todos, theme, tab }) {
  const visibleTodos = useMemo(
    () => filterTodos(todos, tab),
    [todos, tab]
  );
  return (
    <div className={theme}>
      <p><b>Note: <code>filterTodos</code> is artificially slowed down!</b></p>
      <ul>
        {visibleTodos.map(todo => (
          <li key={todo.id}>
            {todo.completed ?
              <s>{todo.text}</s> :
              todo.text
            }
          </li>
        ))}
      </ul>
    </div>
  );
}
```

***

### Skipping re-rendering of components[](#skipping-re-rendering-of-components "Link for Skipping re-rendering of components ")

In some cases, `useMemo` can also help you optimize performance of re-rendering child components. To illustrate this, let’s say this `TodoList` component passes the `visibleTodos` as a prop to the child `List` component:

```
export default function TodoList({ todos, tab, theme }) {

  // ...

  return (

    <div className={theme}>

      <List items={visibleTodos} />

    </div>

  );

}
```

You’ve noticed that toggling the `theme` prop freezes the app for a moment, but if you remove `<List />` from your JSX, it feels fast. This tells you that it’s worth trying to optimize the `List` component.

**By default, when a component re-renders, React re-renders all of its children recursively.** This is why, when `TodoList` re-renders with a different `theme`, the `List` component *also* re-renders. This is fine for components that don’t require much calculation to re-render. But if you’ve verified that a re-render is slow, you can tell `List` to skip re-rendering when its props are the same as on last render by wrapping it in [`memo`:](/reference/react/memo)

```
import { memo } from 'react';



const List = memo(function List({ items }) {

  // ...

});
```

**With this change, `List` will skip re-rendering if all of its props are the *same* as on the last render.** This is where caching the calculation becomes important! Imagine that you calculated `visibleTodos` without `useMemo`:

```
export default function TodoList({ todos, tab, theme }) {

  // Every time the theme changes, this will be a different array...

  const visibleTodos = filterTodos(todos, tab);

  return (

    <div className={theme}>

      {/* ... so List's props will never be the same, and it will re-render every time */}

      <List items={visibleTodos} />

    </div>

  );

}
```

**In the above example, the `filterTodos` function always creates a *different* array,** similar to how the `{}` object literal always creates a new object. Normally, this wouldn’t be a problem, but it means that `List` props will never be the same, and your [`memo`](/reference/react/memo) optimization won’t work. This is where `useMemo` comes in handy:

```
export default function TodoList({ todos, tab, theme }) {

  // Tell React to cache your calculation between re-renders...

  const visibleTodos = useMemo(

    () => filterTodos(todos, tab),

    [todos, tab] // ...so as long as these dependencies don't change...

  );

  return (

    <div className={theme}>

      {/* ...List will receive the same props and can skip re-rendering */}

      <List items={visibleTodos} />

    </div>

  );

}
```

**By wrapping the `visibleTodos` calculation in `useMemo`, you ensure that it has the *same* value between the re-renders** (until dependencies change). You don’t *have to* wrap a calculation in `useMemo` unless you do it for some specific reason. In this example, the reason is that you pass it to a component wrapped in [`memo`,](/reference/react/memo) and this lets it skip re-rendering. There are a few other reasons to add `useMemo` which are described further on this page.

##### Deep Dive#### Memoizing individual JSX nodes[](#memoizing-individual-jsx-nodes "Link for Memoizing individual JSX nodes ")

Instead of wrapping `List` in [`memo`](/reference/react/memo), you could wrap the `<List />` JSX node itself in `useMemo`:

```
export default function TodoList({ todos, tab, theme }) {

  const visibleTodos = useMemo(() => filterTodos(todos, tab), [todos, tab]);

  const children = useMemo(() => <List items={visibleTodos} />, [visibleTodos]);

  return (

    <div className={theme}>

      {children}

    </div>

  );

}
```

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useMemo } from 'react';
import List from './List.js';
import { filterTodos } from './utils.js'

export default function TodoList({ todos, theme, tab }) {
  const visibleTodos = useMemo(
    () => filterTodos(todos, tab),
    [todos, tab]
  );
  return (
    <div className={theme}>
      <p><b>Note: <code>List</code> is artificially slowed down!</b></p>
      <List items={visibleTodos} />
    </div>
  );
}
```

***

### Preventing an Effect from firing too often[](#preventing-an-effect-from-firing-too-often "Link for Preventing an Effect from firing too often ")

Sometimes, you might want to use a value inside an [Effect:](/learn/synchronizing-with-effects)

```
function ChatRoom({ roomId }) {

  const [message, setMessage] = useState('');



  const options = {

    serverUrl: 'https://localhost:1234',

    roomId: roomId

  }



  useEffect(() => {

    const connection = createConnection(options);

    connection.connect();

    // ...
```

This creates a problem. [Every reactive value must be declared as a dependency of your Effect.](/learn/lifecycle-of-reactive-effects#react-verifies-that-you-specified-every-reactive-value-as-a-dependency) However, if you declare `options` as a dependency, it will cause your Effect to constantly reconnect to the chat room:

```
  useEffect(() => {

    const connection = createConnection(options);

    connection.connect();

    return () => connection.disconnect();

  }, [options]); // 🔴 Problem: This dependency changes on every render

  // ...
```

To solve this, you can wrap the object you need to call from an Effect in `useMemo`:

```
function ChatRoom({ roomId }) {

  const [message, setMessage] = useState('');



  const options = useMemo(() => {

    return {

      serverUrl: 'https://localhost:1234',

      roomId: roomId

    };

  }, [roomId]); // ✅ Only changes when roomId changes



  useEffect(() => {

    const connection = createConnection(options);

    connection.connect();

    return () => connection.disconnect();

  }, [options]); // ✅ Only changes when options changes

  // ...
```

This ensures that the `options` object is the same between re-renders if `useMemo` returns the cached object.

However, since `useMemo` is performance optimization, not a semantic guarantee, React may throw away the cached value if [there is a specific reason to do that](#caveats). This will also cause the effect to re-fire, **so it’s even better to remove the need for a function dependency** by moving your object *inside* the Effect:

```
function ChatRoom({ roomId }) {

  const [message, setMessage] = useState('');



  useEffect(() => {

    const options = { // ✅ No need for useMemo or object dependencies!

      serverUrl: 'https://localhost:1234',

      roomId: roomId

    }



    const connection = createConnection(options);

    connection.connect();

    return () => connection.disconnect();

  }, [roomId]); // ✅ Only changes when roomId changes

  // ...
```

Now your code is simpler and doesn’t need `useMemo`. [Learn more about removing Effect dependencies.](/learn/removing-effect-dependencies#move-dynamic-objects-and-functions-inside-your-effect)

### Memoizing a dependency of another Hook[](#memoizing-a-dependency-of-another-hook "Link for Memoizing a dependency of another Hook ")

Suppose you have a calculation that depends on an object created directly in the component body:

```
function Dropdown({ allItems, text }) {

  const searchOptions = { matchMode: 'whole-word', text };



  const visibleItems = useMemo(() => {

    return searchItems(allItems, searchOptions);

  }, [allItems, searchOptions]); // 🚩 Caution: Dependency on an object created in the component body

  // ...
```

Depending on an object like this defeats the point of memoization. When a component re-renders, all of the code directly inside the component body runs again. **The lines of code creating the `searchOptions` object will also run on every re-render.** Since `searchOptions` is a dependency of your `useMemo` call, and it’s different every time, React knows the dependencies are different, and recalculate `searchItems` every time.

To fix this, you could memoize the `searchOptions` object *itself* before passing it as a dependency:

```
function Dropdown({ allItems, text }) {

  const searchOptions = useMemo(() => {

    return { matchMode: 'whole-word', text };

  }, [text]); // ✅ Only changes when text changes



  const visibleItems = useMemo(() => {

    return searchItems(allItems, searchOptions);

  }, [allItems, searchOptions]); // ✅ Only changes when allItems or searchOptions changes

  // ...
```

In the example above, if the `text` did not change, the `searchOptions` object also won’t change. However, an even better fix is to move the `searchOptions` object declaration *inside* of the `useMemo` calculation function:

```
function Dropdown({ allItems, text }) {

  const visibleItems = useMemo(() => {

    const searchOptions = { matchMode: 'whole-word', text };

    return searchItems(allItems, searchOptions);

  }, [allItems, text]); // ✅ Only changes when allItems or text changes

  // ...
```

Now your calculation depends on `text` directly (which is a string and can’t “accidentally” become different).

***

### Memoizing a function[](#memoizing-a-function "Link for Memoizing a function ")

Suppose the `Form` component is wrapped in [`memo`.](/reference/react/memo) You want to pass a function to it as a prop:

```
export default function ProductPage({ productId, referrer }) {

  function handleSubmit(orderDetails) {

    post('/product/' + productId + '/buy', {

      referrer,

      orderDetails

    });

  }



  return <Form onSubmit={handleSubmit} />;

}
```

Just as `{}` creates a different object, function declarations like `function() {}` and expressions like `() => {}` produce a *different* function on every re-render. By itself, creating a new function is not a problem. This is not something to avoid! However, if the `Form` component is memoized, presumably you want to skip re-rendering it when no props have changed. A prop that is *always* different would defeat the point of memoization.

To memoize a function with `useMemo`, your calculation function would have to return another function:

```
export default function Page({ productId, referrer }) {

  const handleSubmit = useMemo(() => {

    return (orderDetails) => {

      post('/product/' + productId + '/buy', {

        referrer,

        orderDetails

      });

    };

  }, [productId, referrer]);



  return <Form onSubmit={handleSubmit} />;

}
```

This looks clunky! **Memoizing functions is common enough that React has a built-in Hook specifically for that. Wrap your functions into [`useCallback`](/reference/react/useCallback) instead of `useMemo`** to avoid having to write an extra nested function:

```
export default function Page({ productId, referrer }) {

  const handleSubmit = useCallback((orderDetails) => {

    post('/product/' + productId + '/buy', {

      referrer,

      orderDetails

    });

  }, [productId, referrer]);



  return <Form onSubmit={handleSubmit} />;

}
```

The two examples above are completely equivalent. The only benefit to `useCallback` is that it lets you avoid writing an extra nested function inside. It doesn’t do anything else. [Read more about `useCallback`.](/reference/react/useCallback)

***

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### My calculation runs twice on every re-render[](#my-calculation-runs-twice-on-every-re-render "Link for My calculation runs twice on every re-render ")

In [Strict Mode](/reference/react/StrictMode), React will call some of your functions twice instead of once:

```
function TodoList({ todos, tab }) {

  // This component function will run twice for every render.



  const visibleTodos = useMemo(() => {

    // This calculation will run twice if any of the dependencies change.

    return filterTodos(todos, tab);

  }, [todos, tab]);



  // ...
```

This is expected and shouldn’t break your code.

This **development-only** behavior helps you [keep components pure.](/learn/keeping-components-pure) React uses the result of one of the calls, and ignores the result of the other call. As long as your component and calculation functions are pure, this shouldn’t affect your logic. However, if they are accidentally impure, this helps you notice and fix the mistake.

For example, this impure calculation function mutates an array you received as a prop:

```
  const visibleTodos = useMemo(() => {

    // 🚩 Mistake: mutating a prop

    todos.push({ id: 'last', text: 'Go for a walk!' });

    const filtered = filterTodos(todos, tab);

    return filtered;

  }, [todos, tab]);
```

React calls your function twice, so you’d notice the todo is added twice. Your calculation shouldn’t change any existing objects, but it’s okay to change any *new* objects you created during the calculation. For example, if the `filterTodos` function always returns a *different* array, you can mutate *that* array instead:

```
  const visibleTodos = useMemo(() => {

    const filtered = filterTodos(todos, tab);

    // ✅ Correct: mutating an object you created during the calculation

    filtered.push({ id: 'last', text: 'Go for a walk!' });

    return filtered;

  }, [todos, tab]);
```

Read [keeping components pure](/learn/keeping-components-pure) to learn more about purity.

Also, check out the guides on [updating objects](/learn/updating-objects-in-state) and [updating arrays](/learn/updating-arrays-in-state) without mutation.

***

### My `useMemo` call is supposed to return an object, but returns undefined[](#my-usememo-call-is-supposed-to-return-an-object-but-returns-undefined "Link for this heading")

This code doesn’t work:

```
  // 🔴 You can't return an object from an arrow function with () => {

  const searchOptions = useMemo(() => {

    matchMode: 'whole-word',

    text: text

  }, [text]);
```

In JavaScript, `() => {` starts the arrow function body, so the `{` brace is not a part of your object. This is why it doesn’t return an object, and leads to mistakes. You could fix it by adding parentheses like `({` and `})`:

```
  // This works, but is easy for someone to break again

  const searchOptions = useMemo(() => ({

    matchMode: 'whole-word',

    text: text

  }), [text]);
```

However, this is still confusing and too easy for someone to break by removing the parentheses.

To avoid this mistake, write a `return` statement explicitly:

```
  // ✅ This works and is explicit

  const searchOptions = useMemo(() => {

    return {

      matchMode: 'whole-word',

      text: text

    };

  }, [text]);
```

***

### Every time my component renders, the calculation in `useMemo` re-runs[](#every-time-my-component-renders-the-calculation-in-usememo-re-runs "Link for this heading")

Make sure you’ve specified the dependency array as a second argument!

If you forget the dependency array, `useMemo` will re-run the calculation every time:

```
function TodoList({ todos, tab }) {

  // 🔴 Recalculates every time: no dependency array

  const visibleTodos = useMemo(() => filterTodos(todos, tab));

  // ...
```

This is the corrected version passing the dependency array as a second argument:

```
function TodoList({ todos, tab }) {

  // ✅ Does not recalculate unnecessarily

  const visibleTodos = useMemo(() => filterTodos(todos, tab), [todos, tab]);

  // ...
```

If this doesn’t help, then the problem is that at least one of your dependencies is different from the previous render. You can debug this problem by manually logging your dependencies to the console:

```
  const visibleTodos = useMemo(() => filterTodos(todos, tab), [todos, tab]);

  console.log([todos, tab]);
```

You can then right-click on the arrays from different re-renders in the console and select “Store as a global variable” for both of them. Assuming the first one got saved as `temp1` and the second one got saved as `temp2`, you can then use the browser console to check whether each dependency in both arrays is the same:

```
Object.is(temp1[0], temp2[0]); // Is the first dependency the same between the arrays?

Object.is(temp1[1], temp2[1]); // Is the second dependency the same between the arrays?

Object.is(temp1[2], temp2[2]); // ... and so on for every dependency ...
```

When you find which dependency breaks memoization, either find a way to remove it, or [memoize it as well.](#memoizing-a-dependency-of-another-hook)

***

### I need to call `useMemo` for each list item in a loop, but it’s not allowed[](#i-need-to-call-usememo-for-each-list-item-in-a-loop-but-its-not-allowed "Link for this heading")

Suppose the `Chart` component is wrapped in [`memo`](/reference/react/memo). You want to skip re-rendering every `Chart` in the list when the `ReportList` component re-renders. However, you can’t call `useMemo` in a loop:

```
function ReportList({ items }) {

  return (

    <article>

      {items.map(item => {

        // 🔴 You can't call useMemo in a loop like this:

        const data = useMemo(() => calculateReport(item), [item]);

        return (

          <figure key={item.id}>

            <Chart data={data} />

          </figure>

        );

      })}

    </article>

  );

}
```

Instead, extract a component for each item and memoize data for individual items:

```
function ReportList({ items }) {

  return (

    <article>

      {items.map(item =>

        <Report key={item.id} item={item} />

      )}

    </article>

  );

}



function Report({ item }) {

  // ✅ Call useMemo at the top level:

  const data = useMemo(() => calculateReport(item), [item]);

  return (

    <figure>

      <Chart data={data} />

    </figure>

  );

}
```

Alternatively, you could remove `useMemo` and instead wrap `Report` itself in [`memo`.](/reference/react/memo) If the `item` prop does not change, `Report` will skip re-rendering, so `Chart` will skip re-rendering too:

```
function ReportList({ items }) {

  // ...

}



const Report = memo(function Report({ item }) {

  const data = calculateReport(item);

  return (

    <figure>

      <Chart data={data} />

    </figure>

  );

});
```

[PrevioususeLayoutEffect](/reference/react/useLayoutEffect)

[NextuseOptimistic](/reference/react/useOptimistic)

***

----
url: https://18.react.dev/reference/react-dom/components/title
----

[API Reference](/reference/react)

[Components](/reference/react-dom/components)

# \<title>[](#undefined "Link for this heading")

### Canary

React’s extensions to `<title>` are currently only available in React’s canary and experimental channels. In stable releases of React `<title>` works only as a [built-in browser HTML component](https://react.dev/reference/react-dom/components#all-html-components). Learn more about [React’s release channels here](/community/versioning-policy#all-release-channels).

The [built-in browser `<title>` component](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/title) lets you specify the title of the document.

```
<title>My Blog</title>
```

* [Reference](#reference)
  * [`<title>`](#title)

* [Usage](#usage)

  * [Set the document title](#set-the-document-title)
  * [Use variables in the title](#use-variables-in-the-title)

***

## Reference[](#reference "Link for Reference ")

### `<title>`[](#title "Link for this heading")

To specify the title of the document, render the [built-in browser `<title>` component](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/title). You can render `<title>` from any component and React will always place the corresponding DOM element in the document head.

```
<title>My Blog</title>
```

[See more examples below.](#usage)

#### Props[](#props "Link for Props ")

`<title>` supports all [common element props.](/reference/react-dom/components/common#props)

***

## Usage[](#usage "Link for Usage ")

### Set the document title[](#set-the-document-title "Link for Set the document title ")

Render the `<title>` component from any component with text as its children. React will put a `<title>` DOM node in the document `<head>`.

```
import ShowRenderedHTML from './ShowRenderedHTML.js';

export default function ContactUsPage() {
  return (
    <ShowRenderedHTML>
      <title>My Site: Contact Us</title>
      <h1>Contact Us</h1>
      <p>Email us at support@example.com</p>
    </ShowRenderedHTML>
  );
}
```

### Use variables in the title[](#use-variables-in-the-title "Link for Use variables in the title ")

The children of the `<title>` component must be a single string of text. (Or a single number or a single object with a `toString` method.) It might not be obvious, but using JSX curly braces like this:

```
<title>Results page {pageNumber}</title> // 🔴 Problem: This is not a single string
```

… actually causes the `<title>` component to get a two-element array as its children (the string `"Results page"` and the value of `pageNumber`). This will cause an error. Instead, use string interpolation to pass `<title>` a single string:

```
<title>{`Results page ${pageNumber}`}</title>
```

[Previous\<style>](/reference/react-dom/components/style)

[NextAPIs](/reference/react-dom)

***

----
url: https://18.react.dev/reference/react-dom/preconnect
----

[API Reference](/reference/react)

[APIs](/reference/react-dom)

# preconnect[](#undefined "Link for this heading")

### Canary

The `preconnect` function is currently only available in React’s Canary and experimental channels. Learn more about [React’s release channels here](/community/versioning-policy#all-release-channels).

`preconnect` lets you eagerly connect to a server that you expect to load resources from.

```
preconnect("https://example.com");
```

* [Reference](#reference)
  * [`preconnect(href)`](#preconnect)

* [Usage](#usage)

  * [Preconnecting when rendering](#preconnecting-when-rendering)
  * [Preconnecting in an event handler](#preconnecting-in-an-event-handler)

***

## Reference[](#reference "Link for Reference ")

### `preconnect(href)`[](#preconnect "Link for this heading")

To preconnect to a host, call the `preconnect` function from `react-dom`.

```
import { preconnect } from 'react-dom';



function AppRoot() {

  preconnect("https://example.com");

  // ...

}
```

***

## Usage[](#usage "Link for Usage ")

### Preconnecting when rendering[](#preconnecting-when-rendering "Link for Preconnecting when rendering ")

Call `preconnect` when rendering a component if you know that its children will load external resources from that host.

```
import { preconnect } from 'react-dom';



function AppRoot() {

  preconnect("https://example.com");

  return ...;

}
```

### Preconnecting in an event handler[](#preconnecting-in-an-event-handler "Link for Preconnecting in an event handler ")

Call `preconnect` in an event handler before transitioning to a page or state where external resources will be needed. This gets the process started earlier than if you call it during the rendering of the new page or state.

```
import { preconnect } from 'react-dom';



function CallToAction() {

  const onClick = () => {

    preconnect('http://example.com');

    startWizard();

  }

  return (

    <button onClick={onClick}>Start Wizard</button>

  );

}
```

[Previoushydrate](/reference/react-dom/hydrate)

[NextprefetchDNS](/reference/react-dom/prefetchDNS)

***

----
url: https://legacy.reactjs.org/docs/hooks-faq.html
----

> These docs are old and won’t be updated. Go to [react.dev](https://react.dev/) for the new React docs.
>
> The new documentation pages teaches React with Hooks.

*Hooks* are a new addition in React 16.8. They let you use state and other React features without writing a class.

This page answers some of the frequently asked questions about [Hooks](/docs/hooks-overview.html).

* **[Adoption Strategy](#adoption-strategy)**

  * [Which versions of React include Hooks?](#which-versions-of-react-include-hooks)
  * [Do I need to rewrite all my class components?](#do-i-need-to-rewrite-all-my-class-components)
  * [What can I do with Hooks that I couldn’t with classes?](#what-can-i-do-with-hooks-that-i-couldnt-with-classes)
  * [How much of my React knowledge stays relevant?](#how-much-of-my-react-knowledge-stays-relevant)
  * [Should I use Hooks, classes, or a mix of both?](#should-i-use-hooks-classes-or-a-mix-of-both)
  * [Do Hooks cover all use cases for classes?](#do-hooks-cover-all-use-cases-for-classes)
  * [Do Hooks replace render props and higher-order components?](#do-hooks-replace-render-props-and-higher-order-components)
  * [What do Hooks mean for popular APIs like Redux connect() and React Router?](#what-do-hooks-mean-for-popular-apis-like-redux-connect-and-react-router)
  * [Do Hooks work with static typing?](#do-hooks-work-with-static-typing)
  * [How to test components that use Hooks?](#how-to-test-components-that-use-hooks)
  * [What exactly do the lint rules enforce?](#what-exactly-do-the-lint-rules-enforce)

* **[From Classes to Hooks](#from-classes-to-hooks)**

  * [How do lifecycle methods correspond to Hooks?](#how-do-lifecycle-methods-correspond-to-hooks)
  * [How can I do data fetching with Hooks?](#how-can-i-do-data-fetching-with-hooks)
  * [Is there something like instance variables?](#is-there-something-like-instance-variables)
  * [Should I use one or many state variables?](#should-i-use-one-or-many-state-variables)
  * [Can I run an effect only on updates?](#can-i-run-an-effect-only-on-updates)
  * [How to get the previous props or state?](#how-to-get-the-previous-props-or-state)
  * [Why am I seeing stale props or state inside my function?](#why-am-i-seeing-stale-props-or-state-inside-my-function)
  * [How do I implement getDerivedStateFromProps?](#how-do-i-implement-getderivedstatefromprops)
  * [Is there something like forceUpdate?](#is-there-something-like-forceupdate)
  * [Can I make a ref to a function component?](#can-i-make-a-ref-to-a-function-component)
  * [How can I measure a DOM node?](#how-can-i-measure-a-dom-node)
  * [What does const \[thing, setThing\] = useState() mean?](#what-does-const-thing-setthing--usestate-mean)

* **[Performance Optimizations](#performance-optimizations)**

  * [Can I skip an effect on updates?](#can-i-skip-an-effect-on-updates)
  * [Is it safe to omit functions from the list of dependencies?](#is-it-safe-to-omit-functions-from-the-list-of-dependencies)
  * [What can I do if my effect dependencies change too often?](#what-can-i-do-if-my-effect-dependencies-change-too-often)
  * [How do I implement shouldComponentUpdate?](#how-do-i-implement-shouldcomponentupdate)
  * [How to memoize calculations?](#how-to-memoize-calculations)
  * [How to create expensive objects lazily?](#how-to-create-expensive-objects-lazily)
  * [Are Hooks slow because of creating functions in render?](#are-hooks-slow-because-of-creating-functions-in-render)
  * [How to avoid passing callbacks down?](#how-to-avoid-passing-callbacks-down)
  * [How to read an often-changing value from useCallback?](#how-to-read-an-often-changing-value-from-usecallback)

* **[Under the Hood](#under-the-hood)**

  * [How does React associate Hook calls with components?](#how-does-react-associate-hook-calls-with-components)
  * [What is the prior art for Hooks?](#what-is-the-prior-art-for-hooks)

## [](#adoption-strategy)Adoption Strategy

### [](#which-versions-of-react-include-hooks)Which versions of React include Hooks?

Starting with 16.8.0, React includes a stable implementation of React Hooks for:

* React DOM
* React Native
* React DOM Server
* React Test Renderer
* React Shallow Renderer

Note that **to enable Hooks, all React packages need to be 16.8.0 or higher**. Hooks won’t work if you forget to update, for example, React DOM.

[React Native 0.59](https://reactnative.dev/blog/2019/03/12/releasing-react-native-059) and above support Hooks.

### [](#do-i-need-to-rewrite-all-my-class-components)Do I need to rewrite all my class components?

No. There are [no plans](/docs/hooks-intro.html#gradual-adoption-strategy) to remove classes from React — we all need to keep shipping products and can’t afford rewrites. We recommend trying Hooks in new code.

### [](#what-can-i-do-with-hooks-that-i-couldnt-with-classes)What can I do with Hooks that I couldn’t with classes?

Hooks offer a powerful and expressive new way to reuse functionality between components. [“Building Your Own Hooks”](/docs/hooks-custom.html) provides a glimpse of what’s possible. [This article](https://medium.com/@dan_abramov/making-sense-of-react-hooks-fdbde8803889) by a React core team member dives deeper into the new capabilities unlocked by Hooks.

### [](#how-much-of-my-react-knowledge-stays-relevant)How much of my React knowledge stays relevant?

Hooks are a more direct way to use the React features you already know — such as state, lifecycle, context, and refs. They don’t fundamentally change how React works, and your knowledge of components, props, and top-down data flow is just as relevant.

Hooks do have a learning curve of their own. If there’s something missing in this documentation, [raise an issue](https://github.com/reactjs/reactjs.org/issues/new) and we’ll try to help.

### [](#should-i-use-hooks-classes-or-a-mix-of-both)Should I use Hooks, classes, or a mix of both?

When you’re ready, we’d encourage you to start trying Hooks in new components you write. Make sure everyone on your team is on board with using them and familiar with this documentation. We don’t recommend rewriting your existing classes to Hooks unless you planned to rewrite them anyway (e.g. to fix bugs).

You can’t use Hooks *inside* a class component, but you can definitely mix classes and function components with Hooks in a single tree. Whether a component is a class or a function that uses Hooks is an implementation detail of that component. In the longer term, we expect Hooks to be the primary way people write React components.

### [](#do-hooks-cover-all-use-cases-for-classes)Do Hooks cover all use cases for classes?

Our goal is for Hooks to cover all use cases for classes as soon as possible. There are no Hook equivalents to the uncommon `getSnapshotBeforeUpdate`, `getDerivedStateFromError` and `componentDidCatch` lifecycles yet, but we plan to add them soon.

### [](#do-hooks-replace-render-props-and-higher-order-components)Do Hooks replace render props and higher-order components?

Often, render props and higher-order components render only a single child. We think Hooks are a simpler way to serve this use case. There is still a place for both patterns (for example, a virtual scroller component might have a `renderItem` prop, or a visual container component might have its own DOM structure). But in most cases, Hooks will be sufficient and can help reduce nesting in your tree.

### [](#what-do-hooks-mean-for-popular-apis-like-redux-connect-and-react-router)What do Hooks mean for popular APIs like Redux `connect()` and React Router?

You can continue to use the exact same APIs as you always have; they’ll continue to work.

React Redux since v7.1.0 [supports Hooks API](https://react-redux.js.org/api/hooks) and exposes hooks like `useDispatch` or `useSelector`.

React Router [supports hooks](https://reacttraining.com/react-router/web/api/Hooks) since v5.1.

Other libraries might support hooks in the future too.

### [](#do-hooks-work-with-static-typing)Do Hooks work with static typing?

Hooks were designed with static typing in mind. Because they’re functions, they are easier to type correctly than patterns like higher-order components. The latest Flow and TypeScript React definitions include support for React Hooks.

Importantly, custom Hooks give you the power to constrain React API if you’d like to type them more strictly in some way. React gives you the primitives, but you can combine them in different ways than what we provide out of the box.

### [](#how-to-test-components-that-use-hooks)How to test components that use Hooks?

From React’s point of view, a component using Hooks is just a regular component. If your testing solution doesn’t rely on React internals, testing components with Hooks shouldn’t be different from how you normally test components.

> Note
>
> [Testing Recipes](/docs/testing-recipes.html) include many examples that you can copy and paste.

For example, let’s say we have this counter component:

```
function Example() {
  const [count, setCount] = useState(0);
  useEffect(() => {
    document.title = `You clicked ${count} times`;
  });
  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}
```

We’ll test it using React DOM. To make sure that the behavior matches what happens in the browser, we’ll wrap the code rendering and updating it into [`ReactTestUtils.act()`](/docs/test-utils.html#act) calls:

```
import React from 'react';
import ReactDOM from 'react-dom/client';
import { act } from 'react-dom/test-utils';import Counter from './Counter';

let container;

beforeEach(() => {
  container = document.createElement('div');
  document.body.appendChild(container);
});

afterEach(() => {
  document.body.removeChild(container);
  container = null;
});

it('can render and update a counter', () => {
  // Test first render and effect
  act(() => {    ReactDOM.createRoot(container).render(<Counter />);  });  const button = container.querySelector('button');
  const label = container.querySelector('p');
  expect(label.textContent).toBe('You clicked 0 times');
  expect(document.title).toBe('You clicked 0 times');

  // Test second render and effect
  act(() => {    button.dispatchEvent(new MouseEvent('click', {bubbles: true}));  });  expect(label.textContent).toBe('You clicked 1 times');
  expect(document.title).toBe('You clicked 1 times');
});
```

The calls to `act()` will also flush the effects inside of them.

If you need to test a custom Hook, you can do so by creating a component in your test, and using your Hook from it. Then you can test the component you wrote.

To reduce the boilerplate, we recommend using [React Testing Library](https://testing-library.com/react) which is designed to encourage writing tests that use your components as the end users do.

For more information, check out [Testing Recipes](/docs/testing-recipes.html).

### [](#what-exactly-do-the-lint-rules-enforce)What exactly do the [lint rules](https://www.npmjs.com/package/eslint-plugin-react-hooks) enforce?

We provide an [ESLint plugin](https://www.npmjs.com/package/eslint-plugin-react-hooks) that enforces [rules of Hooks](/docs/hooks-rules.html) to avoid bugs. It assumes that any function starting with ”`use`” and a capital letter right after it is a Hook. We recognize this heuristic isn’t perfect and there may be some false positives, but without an ecosystem-wide convention there is just no way to make Hooks work well — and longer names will discourage people from either adopting Hooks or following the convention.

In particular, the rule enforces that:

* Calls to Hooks are either inside a `PascalCase` function (assumed to be a component) or another `useSomething` function (assumed to be a custom Hook).
* Hooks are called in the same order on every render.

There are a few more heuristics, and they might change over time as we fine-tune the rule to balance finding bugs with avoiding false positives.

## [](#from-classes-to-hooks)From Classes to Hooks

### [](#how-do-lifecycle-methods-correspond-to-hooks)How do lifecycle methods correspond to Hooks?

* `constructor`: Function components don’t need a constructor. You can initialize the state in the [`useState`](/docs/hooks-reference.html#usestate) call. If computing the initial state is expensive, you can pass a function to `useState`.
* `getDerivedStateFromProps`: Schedule an update [while rendering](#how-do-i-implement-getderivedstatefromprops) instead.
* `shouldComponentUpdate`: See `React.memo` [below](#how-do-i-implement-shouldcomponentupdate).
* `render`: This is the function component body itself.
* `componentDidMount`, `componentDidUpdate`, `componentWillUnmount`: The [`useEffect` Hook](/docs/hooks-reference.html#useeffect) can express all combinations of these (including [less](#can-i-skip-an-effect-on-updates) [common](#can-i-run-an-effect-only-on-updates) cases).
* `getSnapshotBeforeUpdate`, `componentDidCatch` and `getDerivedStateFromError`: There are no Hook equivalents for these methods yet, but they will be added soon.

### [](#how-can-i-do-data-fetching-with-hooks)How can I do data fetching with Hooks?

Here is a [small demo](https://codesandbox.io/s/jvvkoo8pq3) to get you started. To learn more, check out [this article](https://www.robinwieruch.de/react-hooks-fetch-data/) about data fetching with Hooks.

### [](#is-there-something-like-instance-variables)Is there something like instance variables?

Yes! The [`useRef()`](/docs/hooks-reference.html#useref) Hook isn’t just for DOM refs. The “ref” object is a generic container whose `current` property is mutable and can hold any value, similar to an instance property on a class.

You can write to it from inside `useEffect`:

```
function Timer() {
  const intervalRef = useRef();
  useEffect(() => {
    const id = setInterval(() => {
      // ...
    });
    intervalRef.current = id;    return () => {
      clearInterval(intervalRef.current);
    };
  });

  // ...
}
```

If we just wanted to set an interval, we wouldn’t need the ref (`id` could be local to the effect), but it’s useful if we want to clear the interval from an event handler:

```
  // ...
  function handleCancelClick() {
    clearInterval(intervalRef.current);  }
  // ...
```

Conceptually, you can think of refs as similar to instance variables in a class. Unless you’re doing [lazy initialization](#how-to-create-expensive-objects-lazily), avoid setting refs during rendering — this can lead to surprising behavior. Instead, typically you want to modify refs in event handlers and effects.

### [](#should-i-use-one-or-many-state-variables)Should I use one or many state variables?

If you’re coming from classes, you might be tempted to always call `useState()` once and put all state into a single object. You can do it if you’d like. Here is an example of a component that follows the mouse movement. We keep its position and size in the local state:

```
function Box() {
  const [state, setState] = useState({ left: 0, top: 0, width: 100, height: 100 });
  // ...
}
```

Now let’s say we want to write some logic that changes `left` and `top` when the user moves their mouse. Note how we have to merge these fields into the previous state object manually:

```
  // ...
  useEffect(() => {
    function handleWindowMouseMove(e) {
      // Spreading "...state" ensures we don't "lose" width and height      setState(state => ({ ...state, left: e.pageX, top: e.pageY }));    }
    // Note: this implementation is a bit simplified
    window.addEventListener('mousemove', handleWindowMouseMove);
    return () => window.removeEventListener('mousemove', handleWindowMouseMove);
  }, []);
  // ...
```

This is because when we update a state variable, we *replace* its value. This is different from `this.setState` in a class, which *merges* the updated fields into the object.

If you miss automatic merging, you could write a custom `useLegacyState` Hook that merges object state updates. However, **we recommend to split state into multiple state variables based on which values tend to change together.**

For example, we could split our component state into `position` and `size` objects, and always replace the `position` with no need for merging:

```
function Box() {
  const [position, setPosition] = useState({ left: 0, top: 0 });  const [size, setSize] = useState({ width: 100, height: 100 });

  useEffect(() => {
    function handleWindowMouseMove(e) {
      setPosition({ left: e.pageX, top: e.pageY });    }
    // ...
```

Separating independent state variables also has another benefit. It makes it easy to later extract some related logic into a custom Hook, for example:

```
function Box() {
  const position = useWindowPosition();  const [size, setSize] = useState({ width: 100, height: 100 });
  // ...
}

function useWindowPosition() {  const [position, setPosition] = useState({ left: 0, top: 0 });
  useEffect(() => {
    // ...
  }, []);
  return position;
}
```

Note how we were able to move the `useState` call for the `position` state variable and the related effect into a custom Hook without changing their code. If all state was in a single object, extracting it would be more difficult.

Both putting all state in a single `useState` call, and having a `useState` call per each field can work. Components tend to be most readable when you find a balance between these two extremes, and group related state into a few independent state variables. If the state logic becomes complex, we recommend [managing it with a reducer](/docs/hooks-reference.html#usereducer) or a custom Hook.

### [](#can-i-run-an-effect-only-on-updates)Can I run an effect only on updates?

This is a rare use case. If you need it, you can [use a mutable ref](#is-there-something-like-instance-variables) to manually store a boolean value corresponding to whether you are on the first or a subsequent render, then check that flag in your effect. (If you find yourself doing this often, you could create a custom Hook for it.)

### [](#how-to-get-the-previous-props-or-state)How to get the previous props or state?

There are two cases in which you might want to get previous props or state.

Sometimes, you need previous props to **clean up an effect.** For example, you might have an effect that subscribes to a socket based on the `userId` prop. If the `userId` prop changes, you want to unsubscribe from the *previous* `userId` and subscribe to the *next* one. You don’t need to do anything special for this to work:

```
useEffect(() => {
  ChatAPI.subscribeToSocket(props.userId);
  return () => ChatAPI.unsubscribeFromSocket(props.userId);
}, [props.userId]);
```

In the above example, if `userId` changes from `3` to `4`, `ChatAPI.unsubscribeFromSocket(3)` will run first, and then `ChatAPI.subscribeToSocket(4)` will run. There is no need to get “previous” `userId` because the cleanup function will capture it in a closure.

Other times, you might need to **adjust state based on a change in props or other state**. This is rarely needed and is usually a sign you have some duplicate or redundant state. However, in the rare case that you need this pattern, you can [store previous state or props in state and update them during rendering](#how-do-i-implement-getderivedstatefromprops).

We have previously suggested a custom Hook called `usePrevious` to hold the previous value. However, we’ve found that most use cases fall into the two patterns described above. If your use case is different, you can [hold a value in a ref](#is-there-something-like-instance-variables) and manually update it when needed. Avoid reading and updating refs during rendering because this makes your component’s behavior difficult to predict and understand.

### [](#why-am-i-seeing-stale-props-or-state-inside-my-function)Why am I seeing stale props or state inside my function?

Any function inside a component, including event handlers and effects, “sees” the props and state from the render it was created in. For example, consider code like this:

```
function Example() {
  const [count, setCount] = useState(0);

  function handleAlertClick() {
    setTimeout(() => {
      alert('You clicked on: ' + count);
    }, 3000);
  }

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
      <button onClick={handleAlertClick}>
        Show alert
      </button>
    </div>
  );
}
```

If you first click “Show alert” and then increment the counter, the alert will show the `count` variable **at the time you clicked the “Show alert” button**. This prevents bugs caused by the code assuming props and state don’t change.

If you intentionally want to read the *latest* state from some asynchronous callback, you could keep it in [a ref](/docs/hooks-faq.html#is-there-something-like-instance-variables), mutate it, and read from it.

Finally, another possible reason you’re seeing stale props or state is if you use the “dependency array” optimization but didn’t correctly specify all the dependencies. For example, if an effect specifies `[]` as the second argument but reads `someProp` inside, it will keep “seeing” the initial value of `someProp`. The solution is to either remove the dependency array, or to fix it. Here’s [how you can deal with functions](#is-it-safe-to-omit-functions-from-the-list-of-dependencies), and here’s [other common strategies](#what-can-i-do-if-my-effect-dependencies-change-too-often) to run effects less often without incorrectly skipping dependencies.

> Note
>
> We provide an [`exhaustive-deps`](https://github.com/facebook/react/issues/14920) ESLint rule as a part of the [`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.

### [](#how-do-i-implement-getderivedstatefromprops)How do I implement `getDerivedStateFromProps`?

While you probably [don’t need it](/blog/2018/06/07/you-probably-dont-need-derived-state.html), in rare cases that you do (such as implementing a `<Transition>` component), you can update the state right during rendering. React will re-run the component with updated state immediately after exiting the first render so it wouldn’t be expensive.

Here, we store the previous value of the `row` prop in a state variable so that we can compare:

```
function ScrollView({row}) {
  const [isScrollingDown, setIsScrollingDown] = useState(false);
  const [prevRow, setPrevRow] = useState(null);

  if (row !== prevRow) {
    // Row changed since last render. Update isScrollingDown.
    setIsScrollingDown(prevRow !== null && row > prevRow);
    setPrevRow(row);
  }

  return `Scrolling down: ${isScrollingDown}`;
}
```

This might look strange at first, but an update during rendering is exactly what `getDerivedStateFromProps` has always been like conceptually.

### [](#is-there-something-like-forceupdate)Is there something like forceUpdate?

Both `useState` and `useReducer` Hooks [bail out of updates](/docs/hooks-reference.html#bailing-out-of-a-state-update) if the next value is the same as the previous one. Mutating state in place and calling `setState` will not cause a re-render.

Normally, you shouldn’t mutate local state in React. However, as an escape hatch, you can use an incrementing counter to force a re-render even if the state has not changed:

```
  const [ignored, forceUpdate] = useReducer(x => x + 1, 0);

  function handleClick() {
    forceUpdate();
  }
```

Try to avoid this pattern if possible.

### [](#can-i-make-a-ref-to-a-function-component)Can I make a ref to a function component?

While you shouldn’t need this often, you may expose some imperative methods to a parent component with the [`useImperativeHandle`](/docs/hooks-reference.html#useimperativehandle) Hook.

### [](#how-can-i-measure-a-dom-node)How can I measure a DOM node?

One rudimentary way to measure the position or size of a DOM node is to use a [callback ref](/docs/refs-and-the-dom.html#callback-refs). React will call that callback whenever the ref gets attached to a different node. Here is a [small demo](https://codesandbox.io/s/l7m0v5x4v9):

```
function MeasureExample() {
  const [height, setHeight] = useState(0);

  const measuredRef = useCallback(node => {    if (node !== null) {      setHeight(node.getBoundingClientRect().height);    }  }, []);
  return (
    <>
      <h1 ref={measuredRef}>Hello, world</h1>      <h2>The above header is {Math.round(height)}px tall</h2>
    </>
  );
}
```

We didn’t choose `useRef` in this example because an object ref doesn’t notify us about *changes* to the current ref value. Using a callback ref ensures that [even if a child component displays the measured node later](https://codesandbox.io/s/818zzk8m78) (e.g. in response to a click), we still get notified about it in the parent component and can update the measurements.

Note that we pass `[]` as a dependency array to `useCallback`. This ensures that our ref callback doesn’t change between the re-renders, and so React won’t call it unnecessarily.

In this example, the callback ref will be called only when the component mounts and unmounts, since the rendered `<h1>` component stays present throughout any rerenders. If you want to be notified any time a component resizes, you may want to use [`ResizeObserver`](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver) or a third-party Hook built on it.

If you want, you can [extract this logic](https://codesandbox.io/s/m5o42082xy) into a reusable Hook:

```
function MeasureExample() {
  const [rect, ref] = useClientRect();  return (
    <>
      <h1 ref={ref}>Hello, world</h1>
      {rect !== null &&
        <h2>The above header is {Math.round(rect.height)}px tall</h2>
      }
    </>
  );
}

function useClientRect() {
  const [rect, setRect] = useState(null);
  const ref = useCallback(node => {
    if (node !== null) {
      setRect(node.getBoundingClientRect());
    }
  }, []);
  return [rect, ref];
}
```

### [](#what-does-const-thing-setthing--usestate-mean)What does `const [thing, setThing] = useState()` mean?

If you’re not familiar with this syntax, check out the [explanation](/docs/hooks-state.html#tip-what-do-square-brackets-mean) in the State Hook documentation.

## [](#performance-optimizations)Performance Optimizations

### [](#can-i-skip-an-effect-on-updates)Can I skip an effect on updates?

Yes. See [conditionally firing an effect](/docs/hooks-reference.html#conditionally-firing-an-effect). Note that forgetting to handle updates often [introduces bugs](/docs/hooks-effect.html#explanation-why-effects-run-on-each-update), which is why this isn’t the default behavior.

### [](#is-it-safe-to-omit-functions-from-the-list-of-dependencies)Is it safe to omit functions from the list of dependencies?

Generally speaking, no.

```
function Example({ someProp }) {
  function doSomething() {
    console.log(someProp);  }

  useEffect(() => {
    doSomething();
  }, []); // 🔴 This is not safe (it calls `doSomething` which uses `someProp`)}
```

It’s difficult to remember which props or state are used by functions outside of the effect. This is why **usually you’ll want to declare functions needed by an effect *inside* of it.** Then it’s easy to see what values from the component scope that effect depends on:

```
function Example({ someProp }) {
  useEffect(() => {
    function doSomething() {
      console.log(someProp);    }

    doSomething();
  }, [someProp]); // ✅ OK (our effect only uses `someProp`)}
```

If after that we still don’t use any values from the component scope, it’s safe to specify `[]`:

```
useEffect(() => {
  function doSomething() {
    console.log('hello');
  }

  doSomething();
}, []); // ✅ OK in this example because we don't use *any* values from component scope
```

Depending on your use case, there are a few more options described below.

> Note
>
> We provide the [`exhaustive-deps`](https://github.com/facebook/react/issues/14920) ESLint rule as a part of the [`eslint-plugin-react-hooks`](https://www.npmjs.com/package/eslint-plugin-react-hooks#installation) package. It helps you find components that don’t handle updates consistently.

Let’s see why this matters.

If you specify a [list of dependencies](/docs/hooks-reference.html#conditionally-firing-an-effect) as the last argument to `useEffect`, `useLayoutEffect`, `useMemo`, `useCallback`, or `useImperativeHandle`, it must include all values that are used inside the callback and participate in the React data flow. That includes props, state, and anything derived from them.

It is **only** safe to omit a function from the dependency list if nothing in it (or the functions called by it) references props, state, or values derived from them. This example has a bug:

```
function ProductPage({ productId }) {
  const [product, setProduct] = useState(null);

  async function fetchProduct() {
    const response = await fetch('http://myapi/product/' + productId); // Uses productId prop    const json = await response.json();
    setProduct(json);
  }

  useEffect(() => {
    fetchProduct();
  }, []); // 🔴 Invalid because `fetchProduct` uses `productId`  // ...
}
```

**The recommended fix is to move that function *inside* of your effect**. That makes it easy to see which props or state your effect uses, and to ensure they’re all declared:

```
function ProductPage({ productId }) {
  const [product, setProduct] = useState(null);

  useEffect(() => {
    // By moving this function inside the effect, we can clearly see the values it uses.    async function fetchProduct() {      const response = await fetch('http://myapi/product/' + productId);      const json = await response.json();      setProduct(json);    }
    fetchProduct();
  }, [productId]); // ✅ Valid because our effect only uses productId  // ...
}
```

This also allows you to handle out-of-order responses with a local variable inside the effect:

```
  useEffect(() => {
    let ignore = false;    async function fetchProduct() {
      const response = await fetch('http://myapi/product/' + productId);
      const json = await response.json();
      if (!ignore) setProduct(json);    }

    fetchProduct();
    return () => { ignore = true };  }, [productId]);
```

We moved the function inside the effect so it doesn’t need to be in its dependency list.

> Tip
>
> Check out [this small demo](https://codesandbox.io/s/jvvkoo8pq3) and [this article](https://www.robinwieruch.de/react-hooks-fetch-data/) to learn more about data fetching with Hooks.

**If for some reason you *can’t* move a function inside an effect, there are a few more options:**

* **You can try moving that function outside of your component**. In that case, the function is guaranteed to not reference any props or state, and also doesn’t need to be in the list of dependencies.
* If the function you’re calling is a pure computation and is safe to call while rendering, you may **call it outside of the effect instead,** and make the effect depend on the returned value.
* As a last resort, you can **add a function to effect dependencies but *wrap its definition*** into the [`useCallback`](/docs/hooks-reference.html#usecallback) Hook. This ensures it doesn’t change on every render unless *its own* dependencies also change:

```
function ProductPage({ productId }) {
  // ✅ Wrap with useCallback to avoid change on every render  const fetchProduct = useCallback(() => {    // ... Does something with productId ...  }, [productId]); // ✅ All useCallback dependencies are specified
  return <ProductDetails fetchProduct={fetchProduct} />;
}

function ProductDetails({ fetchProduct }) {
  useEffect(() => {
    fetchProduct();
  }, [fetchProduct]); // ✅ All useEffect dependencies are specified
  // ...
}
```

Note that in the above example we **need** to keep the function in the dependencies list. This ensures that a change in the `productId` prop of `ProductPage` automatically triggers a refetch in the `ProductDetails` component.

### [](#what-can-i-do-if-my-effect-dependencies-change-too-often)What can I do if my effect dependencies change too often?

Sometimes, your effect may be using state that changes too often. You might be tempted to omit that state from a list of dependencies, but that usually leads to bugs:

```
function Counter() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    const id = setInterval(() => {
      setCount(count + 1); // This effect depends on the `count` state    }, 1000);
    return () => clearInterval(id);
  }, []); // 🔴 Bug: `count` is not specified as a dependency
  return <h1>{count}</h1>;
}
```

The empty set of dependencies, `[]`, means that the effect will only run once when the component mounts, and not on every re-render. The problem is that inside the `setInterval` callback, the value of `count` does not change, because we’ve created a closure with the value of `count` set to `0` as it was when the effect callback ran. Every second, this callback then calls `setCount(0 + 1)`, so the count never goes above 1.

Specifying `[count]` as a list of dependencies would fix the bug, but would cause the interval to be reset on every change. Effectively, each `setInterval` would get one chance to execute before being cleared (similar to a `setTimeout`.) That may not be desirable. To fix this, we can use the [functional update form of `setState`](/docs/hooks-reference.html#functional-updates). It lets us specify *how* the state needs to change without referencing the *current* state:

```
function Counter() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    const id = setInterval(() => {
      setCount(c => c + 1); // ✅ This doesn't depend on `count` variable outside    }, 1000);
    return () => clearInterval(id);
  }, []); // ✅ Our effect doesn't use any variables in the component scope
  return <h1>{count}</h1>;
}
```

(The identity of the `setCount` function is guaranteed to be stable so it’s safe to omit.)

Now, the `setInterval` callback executes once a second, but each time the inner call to `setCount` can use an up-to-date value for `count` (called `c` in the callback here.)

In more complex cases (such as if one state depends on another state), try moving the state update logic outside the effect with the [`useReducer` Hook](/docs/hooks-reference.html#usereducer). [This article](https://adamrackis.dev/state-and-use-reducer/) offers an example of how you can do this. **The identity of the `dispatch` function from `useReducer` is always stable** — even if the reducer function is declared inside the component and reads its props.

As a last resort, if you want something like `this` in a class, you can [use a ref](/docs/hooks-faq.html#is-there-something-like-instance-variables) to hold a mutable variable. Then you can write and read to it. For example:

```
function Example(props) {
  // Keep latest props in a ref.  const latestProps = useRef(props);  useEffect(() => {    latestProps.current = props;  });
  useEffect(() => {
    function tick() {
      // Read latest props at any time      console.log(latestProps.current);    }

    const id = setInterval(tick, 1000);
    return () => clearInterval(id);
  }, []); // This effect never re-runs}
```

Only do this if you couldn’t find a better alternative, as relying on mutation makes components less predictable. If there’s a specific pattern that doesn’t translate well, [file an issue](https://github.com/facebook/react/issues/new) with a runnable example code and we can try to help.

### [](#how-do-i-implement-shouldcomponentupdate)How do I implement `shouldComponentUpdate`?

You can wrap a function component with `React.memo` to shallowly compare its props:

```
const Button = React.memo((props) => {
  // your component
});
```

It’s not a Hook because it doesn’t compose like Hooks do. `React.memo` is equivalent to `PureComponent`, but it only compares props. (You can also add a second argument to specify a custom comparison function that takes the old and new props. If it returns true, the update is skipped.)

`React.memo` doesn’t compare state because there is no single state object to compare. But you can make children pure too, or even [optimize individual children with `useMemo`](/docs/hooks-faq.html#how-to-memoize-calculations).

### [](#how-to-memoize-calculations)How to memoize calculations?

The [`useMemo`](/docs/hooks-reference.html#usememo) Hook lets you cache calculations between multiple renders by “remembering” the previous computation:

```
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
```

This code calls `computeExpensiveValue(a, b)`. But if the dependencies `[a, b]` haven’t changed since the last value, `useMemo` skips calling it a second time and simply reuses the last value it returned.

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`.

**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. (For rare cases when a value must *never* be recomputed, you can [lazily initialize](#how-to-create-expensive-objects-lazily) a ref.)

Conveniently, `useMemo` also lets you skip an expensive re-render of a child:

```
function Parent({ a, b }) {
  // Only re-rendered if `a` changes:
  const child1 = useMemo(() => <Child1 a={a} />, [a]);
  // Only re-rendered if `b` changes:
  const child2 = useMemo(() => <Child2 b={b} />, [b]);
  return (
    <>
      {child1}
      {child2}
    </>
  )
}
```

Note that this approach won’t work in a loop because Hook calls [can’t](/docs/hooks-rules.html) be placed inside loops. But you can extract a separate component for the list item, and call `useMemo` there.

### [](#how-to-create-expensive-objects-lazily)How to create expensive objects lazily?

`useMemo` lets you [memoize an expensive calculation](#how-to-memoize-calculations) if the dependencies are the same. However, it only serves as a hint, and doesn’t *guarantee* the computation won’t re-run. But sometimes you need to be sure an object is only created once.

**The first common use case is when creating the initial state is expensive:**

```
function Table(props) {
  // ⚠️ createRows() is called on every render
  const [rows, setRows] = useState(createRows(props.count));
  // ...
}
```

To avoid re-creating the ignored initial state, we can pass a **function** to `useState`:

```
function Table(props) {
  // ✅ createRows() is only called once
  const [rows, setRows] = useState(() => createRows(props.count));
  // ...
}
```

React will only call this function during the first render. See the [`useState` API reference](/docs/hooks-reference.html#usestate).

**You might also occasionally want to avoid re-creating the `useRef()` initial value.** For example, maybe you want to ensure some imperative class instance only gets created once:

```
function Image(props) {
  // ⚠️ IntersectionObserver is created on every render
  const ref = useRef(new IntersectionObserver(onIntersect));
  // ...
}
```

`useRef` **does not** accept a special function overload like `useState`. Instead, you can write your own function that creates and sets it lazily:

```
function Image(props) {
  const ref = useRef(null);

  // ✅ IntersectionObserver is created lazily once
  function getObserver() {
    if (ref.current === null) {
      ref.current = new IntersectionObserver(onIntersect);
    }
    return ref.current;
  }

  // When you need it, call getObserver()
  // ...
}
```

This avoids creating an expensive object until it’s truly needed for the first time. If you use Flow or TypeScript, you can also give `getObserver()` a non-nullable type for convenience.

### [](#are-hooks-slow-because-of-creating-functions-in-render)Are Hooks slow because of creating functions in render?

No. In modern browsers, the raw performance of closures compared to classes doesn’t differ significantly except in extreme scenarios.

In addition, consider that the design of Hooks is more efficient in a couple ways:

* Hooks avoid a lot of the overhead that classes require, like the cost of creating class instances and binding event handlers in the constructor.
* **Idiomatic code using Hooks doesn’t need the deep component tree nesting** that is prevalent in codebases that use higher-order components, render props, and context. With smaller component trees, React has less work to do.

Traditionally, performance concerns around inline functions in React have been related to how passing new callbacks on each render breaks `shouldComponentUpdate` optimizations in child components. Hooks approach this problem from three sides.

* The [`useCallback`](/docs/hooks-reference.html#usecallback) Hook lets you keep the same callback reference between re-renders so that `shouldComponentUpdate` continues to work:

  ```
  // Will not change unless `a` or `b` changes
  const memoizedCallback = useCallback(() => {  doSomething(a, b);
  }, [a, b]);
  ```

* The [`useMemo`](/docs/hooks-faq.html#how-to-memoize-calculations) Hook makes it easier to control when individual children update, reducing the need for pure components.

* Finally, the [`useReducer`](/docs/hooks-reference.html#usereducer) Hook reduces the need to pass callbacks deeply, as explained below.

### [](#how-to-avoid-passing-callbacks-down)How to avoid passing callbacks down?

We’ve found that most people don’t enjoy manually passing callbacks through every level of a component tree. Even though it is more explicit, it can feel like a lot of “plumbing”.

In large component trees, an alternative we recommend is to pass down a `dispatch` function from [`useReducer`](/docs/hooks-reference.html#usereducer) via context:

```
const TodosDispatch = React.createContext(null);

function TodosApp() {
  // Note: `dispatch` won't change between re-renders  const [todos, dispatch] = useReducer(todosReducer);
  return (
    <TodosDispatch.Provider value={dispatch}>
      <DeepTree todos={todos} />
    </TodosDispatch.Provider>
  );
}
```

Any child in the tree inside `TodosApp` can use the `dispatch` function to pass actions up to `TodosApp`:

```
function DeepChild(props) {
  // If we want to perform an action, we can get dispatch from context.  const dispatch = useContext(TodosDispatch);
  function handleClick() {
    dispatch({ type: 'add', text: 'hello' });
  }

  return (
    <button onClick={handleClick}>Add todo</button>
  );
}
```

This is both more convenient from the maintenance perspective (no need to keep forwarding callbacks), and avoids the callback problem altogether. Passing `dispatch` down like this is the recommended pattern for deep updates.

Note that you can still choose whether to pass the application *state* down as props (more explicit) or as context (more convenient for very deep updates). If you use context to pass down the state too, use two different context types — the `dispatch` context never changes, so components that read it don’t need to rerender unless they also need the application state.

### [](#how-to-read-an-often-changing-value-from-usecallback)How to read an often-changing value from `useCallback`?

> Note
>
> We recommend to [pass `dispatch` down in context](#how-to-avoid-passing-callbacks-down) rather than individual callbacks in props. The approach below is only mentioned here for completeness and as an escape hatch.

In some rare cases you might need to memoize a callback with [`useCallback`](/docs/hooks-reference.html#usecallback) but the memoization doesn’t work very well because the inner function has to be re-created too often. If the function you’re memoizing is an event handler and isn’t used during rendering, you can use [ref as an instance variable](#is-there-something-like-instance-variables), and save the last committed value into it manually:

```
function Form() {
  const [text, updateText] = useState('');
  const textRef = useRef();

  useEffect(() => {
    textRef.current = text; // Write it to the ref  });

  const handleSubmit = useCallback(() => {
    const currentText = textRef.current; // Read it from the ref    alert(currentText);
  }, [textRef]); // Don't recreate handleSubmit like [text] would do

  return (
    <>
      <input value={text} onChange={e => updateText(e.target.value)} />
      <ExpensiveTree onSubmit={handleSubmit} />
    </>
  );
}
```

This is a rather convoluted pattern but it shows that you can do this escape hatch optimization if you need it. It’s more bearable if you extract it to a custom Hook:

```
function Form() {
  const [text, updateText] = useState('');
  // Will be memoized even if `text` changes:
  const handleSubmit = useEventCallback(() => {    alert(text);
  }, [text]);

  return (
    <>
      <input value={text} onChange={e => updateText(e.target.value)} />
      <ExpensiveTree onSubmit={handleSubmit} />
    </>
  );
}

function useEventCallback(fn, dependencies) {  const ref = useRef(() => {
    throw new Error('Cannot call an event handler while rendering.');
  });

  useEffect(() => {
    ref.current = fn;
  }, [fn, ...dependencies]);

  return useCallback(() => {
    const fn = ref.current;
    return fn();
  }, [ref]);
}
```

In either case, we **don’t recommend this pattern** and only show it here for completeness. Instead, it is preferable to [avoid passing callbacks deep down](#how-to-avoid-passing-callbacks-down).

## [](#under-the-hood)Under the Hood

### [](#how-does-react-associate-hook-calls-with-components)How does React associate Hook calls with components?

React keeps track of the currently rendering component. Thanks to the [Rules of Hooks](/docs/hooks-rules.html), we know that Hooks are only called from React components (or custom Hooks — which are also only called from React components).

There is an internal list of “memory cells” associated with each component. They’re just JavaScript objects where we can put some data. When you call a Hook like `useState()`, it reads the current cell (or initializes it during the first render), and then moves the pointer to the next one. This is how multiple `useState()` calls each get independent local state.

### [](#what-is-the-prior-art-for-hooks)What is the prior art for Hooks?

Hooks synthesize ideas from several different sources:

* Our old experiments with functional APIs in the [react-future](https://github.com/reactjs/react-future/tree/master/07%20-%20Returning%20State) repository.
* React community’s experiments with render prop APIs, including [Ryan Florence](https://github.com/ryanflorence)’s [Reactions Component](https://github.com/reactions/component).
* [Dominic Gannaway](https://github.com/trueadm)’s [`adopt` keyword](https://gist.github.com/trueadm/17beb64288e30192f3aa29cad0218067) proposal as a sugar syntax for render props.
* State variables and state cells in [DisplayScript](http://displayscript.org/introduction.html).
* [Reducer components](https://reasonml.github.io/reason-react/docs/en/state-actions-reducer.html) in ReasonReact.
* [Subscriptions](http://reactivex.io/rxjs/class/es6/Subscription.js~Subscription.html) in Rx.
* [Algebraic effects](https://github.com/ocamllabs/ocaml-effects-tutorial#2-effectful-computations-in-a-pure-setting) in Multicore OCaml.

[Sebastian Markbåge](https://github.com/sebmarkbage) came up with the original design for Hooks, later refined by [Andrew Clark](https://github.com/acdlite), [Sophie Alpert](https://github.com/sophiebits), [Dominic Gannaway](https://github.com/trueadm), and other members of the React team.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/hooks-faq.md)

* Previous article

  [Hooks API Reference](/docs/hooks-reference.html)

----
url: https://legacy.reactjs.org/blog/2015/02/18/react-conf-roundup-2015.html
----

February 18, 2015 by [Steven Luscher](https://twitter.com/steveluscher)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

It was a privilege to welcome the React community to Facebook HQ on January 28–29 for the first-ever React.js Conf, and a pleasure to be able to unveil three new technologies that we’ve been using internally at Facebook for some time: GraphQL, Relay, and React Native.

## [](#the-talks)The talks

### []()Keynote [#](#talk-keynote)

**Tom Occhino** opened with a history of how React came to be, before announcing Facebook’s answer to a long-looming what-if question: what if we could use React to target something other than the DOM?

### []()Tweaking in real time [#](#talk-tweak)

**Brenton Simpson** showed us how eBay brings Bret Victor’s feedback loop to your favorite editor using webpack, react-hot-loader, and [Ambidex](https://github.com/appsforartists/ambidex).

### []()Abstract Syntax Trees [#](#talk-ast)

**Gurdas Nijor** showed us how we can leverage some conventions of React to perform source code transformations that unlock an inspirational set of use cases.

### []()Relay and GraphQL [#](#talk-relay-graphql)

**Daniel Schafer** and **Jing Chen** showed us how Facebook approaches data fetching with React, giving us an early peek at the forthcoming duo of Relay and GraphQL.

### []()Channels [#](#talk-channels)

**James Long** explores what might happen if we introduce channels, a new style of coordinating actions, to React.

### []()React Router [#](#talk-router)

**Michael Jackson** reminded us that URLs should be part of our design process, and showed us how [react-router](https://github.com/rackt/react-router) can help to manage the transitions between them.

### []()Full-stack Flux [#](#talk-full-stack-flux)

**Pete Hunt** showed us how a Flux approach can help us scale actions and questions on the backend in addition to the frontend.

### []()High-performance [#](#talk-performance)

**Jason Bonta** showed us how complex user interfaces can get, and how his team keeps them performant as they scale. He also had the pleasure of open-sourcing his team’s work on [FixedDataTable](https://facebook.github.io/fixed-data-table/).

### []()FormatJS and react-intl [#](#talk-intl)

**Eric Ferraiuolo** showed how you can bring your app to a worldwide audience using a series of polyfills and emerging ECMAScript APIs.

### []()Hype! [#](#talk-hype)

**Ryan Florence** showed us how easy it is to transition from a career selling life insurance, to a burgeoning one as a software developer. All you have to do is to learn how to say “yes.”

### []()React Native [#](#talk-native)

**Christopher Chedeau** showed us how to bring the developer experience of working with React on the web to native app development, using React Native.

### []()Components [#](#talk-components)

**Andrew Rota** explained how React and Web Components can work together, and how to avoid some common pitfalls.

### []()Immutability [#](#talk-immutable)

**Lee Byron** led a master-class on persistent immutable data structures, showing us the world of possibility that they can unlock for your software, and perhaps JavaScript in general.

### []()Beyond the DOM [#](#talk-gibbon)

**Jafar Husain** told us a story about how Netflix was able to push React into places where the DOM could not go.

### []()Data Visualization [#](#talk-visualization)

**Zach Nation** showed us how we can produce visualizations from over 45 million data points without breaking a sweat.

### []()React Refracted [#](#talk-refracted)

**David Nolen** gave us a view of React from a non-JavaScript perspective, challenging some common intuition along the way.

### []()Flux Panel [#](#talk-flux-panel)

**Bill Fisher** coordinated a Flux panel together with **Michael Ridgway**, **Spike Brehm**, **Andres Suarez**, **Jing Chen**, **Ian Obermiller**, and **Kyle Davis**.

### []()Component communication [#](#talk-communication)

**Bonnie Eisenman** led us through the ‘adapter’ approach to inter-component communication taken by her team at Codecademy.

### []()Flow and TypeScript [#](#talk-typescript)

**James Brantly** demonstrated how we can reap the benefits of static typing using both Flow and TypeScript.

### []()Core Team Q\&A [#](#talk-qa)

**Tom Occhino**, **Sophie Alpert**, **Lee Byron**, **Christopher Chedeau**, **Sebastian Markbåge**, **Jing Chen**, and **Dan Schafer** closed the conference with a Q\&A session.

## [](#reactions)Reactions

The conference is over, but the conversation has just begun.

**Mihai Parparita** detailed his efforts to [hack his way to a React.js Conf ticket](http://blog.persistent.info/2014/12/html-munging-my-way-to-reactjs-conf.html); **James Long** blogged about [his first encounter with React Native](http://jlongster.com/First-Impressions-using-React-Native); **Eric Florenzano** talked about how he perceives the [impact of Relay, GraphQL, and React Native](https://medium.com/@ericflo/facebook-just-taught-us-all-how-to-build-websites-51f1e7e996f2) on software development; **Margaret Staples** blogged about her experience of [being on-campus at Facebook HQ](http://deadlugosi.blogspot.com/2015/02/facebook-gave-me-ice-cream.html); **Jeff Barczewski** tied his experience of attending the conference up with a bow in this [blog post filled with photos, videos, and links](http://codewinds.com/blog/2015-02-04-reactjs-conf.html); **Kevin Old** left us with [his takeaways](http://kevinold.com/2015/01/31/takeaways-from-reactjs-conf-2015.html); **Paul Wittmann** found React Native [freshly on his radar](http://www.railslove.com/stories/fresh-on-our-radar-react-native); and finally, undeterred by not being able to attend the conference in person, **Justin Ball** [summarized it from afar](http://www.justinball.com/2015/02/02/i-didn't-attend-react.js-conf.html).

And, in case you missed a session, you can borrow **Michael Chan’s** [drawings](http://chantastic.io/2015-reactjs-conf/), **Mihai Parparita’s** [summary](https://quip.com/uJQeABv7nkFN), or **Shaohua Zhou’s** [day 1](http://getshao.com/2015/01/29/react-js-conf-notes-day1/) / [day 2](http://getshao.com/2015/01/29/react-js-conf-notes-day-2/) notes.

> Notes from [@dlschafer](https://twitter.com/dlschafer) and [@jingc](https://twitter.com/jingc)'s [#reactjsconf](https://twitter.com/hashtag/reactjsconf?src=hash) talk "Data fetching for React applications at Facebook" [pic.twitter.com/IUZUbDCDMQ](http://t.co/IUZUbDCDMQ)
>
> — Michael Chan (@chantastic) [January 28, 2015](https://twitter.com/chantastic/status/560538533161472000)

> This is just magical (in the good way)… GraphQL + Relay is amazing. [#reactjsconf](https://twitter.com/hashtag/reactjsconf?src=hash)
>
> — Chris Williams (@voodootikigod) [January 28, 2015](https://twitter.com/voodootikigod/status/560533225395589120)

> These… these are my people. :) [#reactjsconf](https://twitter.com/hashtag/reactjsconf?src=hash)
>
> — Thomas Beirne (@Beirnet) [January 28, 2015](https://twitter.com/Beirnet/status/560317879501848576)

> Humbled by the React team and community. Found [#reactjsconf](https://twitter.com/hashtag/reactjsconf?src=hash) very mindful, practical and just real.
>
> — xnoɹǝʃ uɐıɹq (@brianleroux) [January 30, 2015](https://twitter.com/brianleroux/status/560972130112655360)

> I say with confidence as a former UIKit author: \[React's model for the UI layer is vastly better than UIKit's. React Native is a \*huge\* deal.
>
> — Andy Matuschak (@andy\_matuschak) [January 28, 2015](https://twitter.com/andy_matuschak/status/560511204867575808)

]

> [#reactjsconf](https://twitter.com/hashtag/reactjsconf?src=hash) was incredible. Amazing project stewardship and community. Boring prediction, React Native sends adoption vertical in 2015.
>
> — David Nolen (@swannodette) [January 30, 2015](https://twitter.com/swannodette/status/561232290273980416)

> I really love the community shout outs by [@vjeux](https://twitter.com/Vjeux) between talks at [#reactjsconf](https://twitter.com/hashtag/reactjsconf?src=hash)!
>
> — Andrew Rota (@AndrewRota) [January 29, 2015](https://twitter.com/AndrewRota/status/560927339522297856)

**All proceeds from React.js Conf 2015 were donated to the wonderful programs at [code.org](http://code.org)**. These programs aim to increase access to the field of computer science by underrepresented members of our community. Watch this video to learn more.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2015-02-18-react-conf-roundup-2015.md)

----
url: https://react.dev/reference/react-compiler/directives/use-memo
----

[API Reference](/reference/react)

[Directives](/reference/react-compiler/directives)

# use memo[](#undefined "Link for this heading")

`"use memo"` marks a function for React Compiler optimization.

### Note

In most cases, you don’t need `"use memo"`. It’s primarily needed in `annotation` mode where you must explicitly mark functions for optimization. In `infer` mode, the compiler automatically detects components and hooks by their naming patterns (PascalCase for components, `use` prefix for hooks). If a component or hook isn’t being compiled in `infer` mode, you should fix its naming convention rather than forcing compilation with `"use memo"`.

* [Reference](#reference)

  * [`"use memo"`](#use-memo)
  * [How `"use memo"` marks functions for optimization](#how-use-memo-marks)
  * [When to use `"use memo"`](#when-to-use)

* [Usage](#usage)
  * [Working with different compilation modes](#compilation-modes)

* [Troubleshooting](#troubleshooting)

  * [Verifying optimization](#verifying-optimization)
  * [See also](#see-also)

***

## Reference[](#reference "Link for Reference ")

### `"use memo"`[](#use-memo "Link for this heading")

Add `"use memo"` at the beginning of a function to mark it for React Compiler optimization.

```
function MyComponent() {

  "use memo";

  // ...

}
```

When a function contains `"use memo"`, the React Compiler will analyze and optimize it during build time. The compiler will automatically memoize values and components to prevent unnecessary re-computations and re-renders.

#### Caveats[](#caveats "Link for Caveats ")

* `"use memo"` must be at the very beginning of a function body, before any imports or other code (comments are OK).
* The directive must be written with double or single quotes, not backticks.
* The directive must exactly match `"use memo"`.
* Only the first directive in a function is processed; additional directives are ignored.
* The effect of the directive depends on your [`compilationMode`](/reference/react-compiler/compilationMode) setting.

### How `"use memo"` marks functions for optimization[](#how-use-memo-marks "Link for this heading")

In a React app that uses the React Compiler, functions are analyzed at build time to determine if they can be optimized. By default, the compiler automatically infers which components to memoize, but this can depend on your [`compilationMode`](/reference/react-compiler/compilationMode) setting if you’ve set it.

`"use memo"` explicitly marks a function for optimization, overriding the default behavior:

* In `annotation` mode: Only functions with `"use memo"` are optimized
* In `infer` mode: The compiler uses heuristics, but `"use memo"` forces optimization
* In `all` mode: Everything is optimized by default, making `"use memo"` redundant

The directive creates a clear boundary in your codebase between optimized and non-optimized code, giving you fine-grained control over the compilation process.

### When to use `"use memo"`[](#when-to-use "Link for this heading")

You should consider using `"use memo"` when:

#### You’re using annotation mode[](#annotation-mode-use "Link for You’re using annotation mode ")

In `compilationMode: 'annotation'`, the directive is required for any function you want optimized:

```
// ✅ This component will be optimized

function OptimizedList() {

  "use memo";

  // ...

}



// ❌ This component won't be optimized

function SimpleWrapper() {

  // ...

}
```

#### You’re gradually adopting React Compiler[](#gradual-adoption "Link for You’re gradually adopting React Compiler ")

Start with `annotation` mode and selectively optimize stable components:

```
// Start by optimizing leaf components

function Button({ onClick, children }) {

  "use memo";

  // ...

}



// Gradually move up the tree as you verify behavior

function ButtonGroup({ buttons }) {

  "use memo";

  // ...

}
```

***

## Usage[](#usage "Link for Usage ")

### Working with different compilation modes[](#compilation-modes "Link for Working with different compilation modes ")

The behavior of `"use memo"` changes based on your compiler configuration:

```
// babel.config.js

module.exports = {

  plugins: [

    ['babel-plugin-react-compiler', {

      compilationMode: 'annotation' // or 'infer' or 'all'

    }]

  ]

};
```

#### Annotation mode[](#annotation-mode-example "Link for Annotation mode ")

```
// ✅ Optimized with "use memo"

function ProductCard({ product }) {

  "use memo";

  // ...

}



// ❌ Not optimized (no directive)

function ProductList({ products }) {

  // ...

}
```

#### Infer mode (default)[](#infer-mode-example "Link for Infer mode (default) ")

```
// Automatically memoized because this is named like a Component

function ComplexDashboard({ data }) {

  // ...

}



// Skipped: Is not named like a Component

function simpleDisplay({ text }) {

  // ...

}
```

In `infer` mode, the compiler automatically detects components and hooks by their naming patterns (PascalCase for components, `use` prefix for hooks). If a component or hook isn’t being compiled in `infer` mode, you should fix its naming convention rather than forcing compilation with `"use memo"`.

***

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### Verifying optimization[](#verifying-optimization "Link for Verifying optimization ")

To confirm your component is being optimized:

1. Check the compiled output in your build
2. Use React DevTools to check for Memo ✨ badge

### See also[](#see-also "Link for See also ")

* [`"use no memo"`](/reference/react-compiler/directives/use-no-memo) - Opt out of compilation
* [`compilationMode`](/reference/react-compiler/compilationMode) - Configure compilation behavior
* [React Compiler](/learn/react-compiler) - Getting started guide

[PreviousDirectives](/reference/react-compiler/directives)

[Next"use no memo"](/reference/react-compiler/directives/use-no-memo)

***

----
url: https://react.dev/link/new-jsx-transform
----

September 22, 2020 by [Luna Ruan](https://twitter.com/lunaruan)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

Although React 17 [doesn’t contain new features](/blog/2020/08/10/react-v17-rc.html), it will provide support for a new version of the JSX transform. In this post, we will describe what it is and how to try it.

## [](#whats-a-jsx-transform)What’s a JSX Transform?

Browsers don’t understand JSX out of the box, so most React users rely on a compiler like Babel or TypeScript to **transform JSX code into regular JavaScript**. Many preconfigured toolkits like Create React App or Next.js also include a JSX transform under the hood.

Together with the React 17 release, we’ve wanted to make a few improvements to the JSX transform, but we didn’t want to break existing setups. This is why we [worked with Babel](https://babeljs.io/blog/2020/03/16/7.9.0#a-new-jsx-transform-11154httpsgithubcombabelbabelpull11154) to **offer a new, rewritten version of the JSX transform** for people who would like to upgrade.

Upgrading to the new transform is completely optional, but it has a few benefits:

* With the new transform, you can **use JSX without importing React**.
* Depending on your setup, its compiled output may **slightly improve the bundle size**.
* It will enable future improvements that **reduce the number of concepts** you need to learn React.

**This upgrade will not change the JSX syntax and is not required.** The old JSX transform will keep working as usual, and there are no plans to remove the support for it.

[React 17 RC](/blog/2020/08/10/react-v17-rc.html) already includes support for the new transform, so go give it a try! To make it easier to adopt, **we’ve also backported its support** to React 16.14.0, React 15.7.0, and React 0.14.10. You can find the upgrade instructions for different tools [below](#how-to-upgrade-to-the-new-jsx-transform).

Now let’s take a closer look at the differences between the old and the new transform.

## [](#whats-different-in-the-new-transform)What’s Different in the New Transform?

When you use JSX, the compiler transforms it into React function calls that the browser can understand. **The old JSX transform** turned JSX into `React.createElement(...)` calls.

For example, let’s say your source code looks like this:

```
import React from 'react';

function App() {
  return <h1>Hello World</h1>;
}
```

Under the hood, the old JSX transform turns it into regular JavaScript:

```
import React from 'react';

function App() {
  return React.createElement('h1', null, 'Hello world');
}
```

> Note
>
> **Your source code doesn’t need to change in any way.** We’re describing how the JSX transform turns your JSX source code into the JavaScript code a browser can understand.

However, this is not perfect:

* Because JSX was compiled into `React.createElement`, `React` needed to be in scope if you used JSX.
* There are some [performance improvements and simplifications](https://github.com/reactjs/rfcs/blob/createlement-rfc/text/0000-create-element-changes.md#motivation) that `React.createElement` does not allow.

To solve these issues, React 17 introduces two new entry points to the React package that are intended to only be used by compilers like Babel and TypeScript. Instead of transforming JSX to `React.createElement`, **the new JSX transform** automatically imports special functions from those new entry points in the React package and calls them.

Let’s say that your source code looks like this:

```
function App() {
  return <h1>Hello World</h1>;
}
```

This is what the new JSX transform compiles it to:

```
// Inserted by a compiler (don't import it yourself!)
import {jsx as _jsx} from 'react/jsx-runtime';

function App() {
  return _jsx('h1', { children: 'Hello world' });
}
```

Note how our original code **did not need to import React** to use JSX anymore! (But we would still need to import React in order to use Hooks or other exports that React provides.)

**This change is fully compatible with all of the existing JSX code**, so you won’t have to change your components. If you’re curious, you can check out the [technical RFC](https://github.com/reactjs/rfcs/blob/createlement-rfc/text/0000-create-element-changes.md#detailed-design) for more details about how the new transform works.

> Note
>
> The functions inside `react/jsx-runtime` and `react/jsx-dev-runtime` must only be used by the compiler transform. If you need to manually create elements in your code, you should keep using `React.createElement`. It will continue to work and is not going away.

## [](#how-to-upgrade-to-the-new-jsx-transform)How to Upgrade to the New JSX Transform

If you aren’t ready to upgrade to the new JSX transform or if you are using JSX for another library, don’t worry. The old transform will not be removed and will continue to be supported.

If you want to upgrade, you will need two things:

* **A version of React that supports the new transform** ([React 17 RC](/blog/2020/08/10/react-v17-rc.html) and higher supports it, but we’ve also released React 16.14.0, React 15.7.0, and React 0.14.10 for people who are still on the older major versions).
* **A compatible compiler** (see instructions for different tools below).

Since the new JSX transform doesn’t require React to be in scope, [we’ve also prepared an automated script](#removing-unused-react-imports) that will remove the unnecessary imports from your codebase.

### [](#create-react-app)Create React App

Create React App [4.0.0](https://github.com/facebook/create-react-app/releases/tag/v4.0.0)+ uses the new transform for compatible React versions.

### [](#nextjs)Next.js

Next.js [v9.5.3](https://github.com/vercel/next.js/releases/tag/v9.5.3)+ uses the new transform for compatible React versions.

### [](#gatsby)Gatsby

Gatsby [v2.24.5](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby/CHANGELOG.md#22452-2020-08-28)+ uses the new transform for compatible React versions.

> Note
>
> If you get [this Gatsby error](https://github.com/gatsbyjs/gatsby/issues/26979) after upgrading to React 17 RC, run `npm update` to fix it.

### [](#manual-babel-setup)Manual Babel Setup

Support for the new JSX transform is available in Babel [v7.9.0](https://babeljs.io/blog/2020/03/16/7.9.0) and above.

First, you’ll need to update to the latest Babel and plugin transform.

If you are using `@babel/plugin-transform-react-jsx`:

```
# for npm users
npm update @babel/core @babel/plugin-transform-react-jsx
```

```
# for yarn users
yarn upgrade @babel/core @babel/plugin-transform-react-jsx
```

If you are using `@babel/preset-react`:

```
# for npm users
npm update @babel/core @babel/preset-react
```

```
# for yarn users
yarn upgrade @babel/core @babel/preset-react
```

Currently, the old transform `{"runtime": "classic"}` is the default option. To enable the new transform, you can pass `{"runtime": "automatic"}` as an option to `@babel/plugin-transform-react-jsx` or `@babel/preset-react`:

```
// If you are using @babel/preset-react
{
  "presets": [
    ["@babel/preset-react", {
      "runtime": "automatic"
    }]
  ]
}
```

```
// If you're using @babel/plugin-transform-react-jsx
{
  "plugins": [
    ["@babel/plugin-transform-react-jsx", {
      "runtime": "automatic"
    }]
  ]
}
```

Starting from Babel 8, `"automatic"` will be the default runtime for both plugins. For more information, check out the Babel documentation for [@babel/plugin-transform-react-jsx](https://babeljs.io/docs/en/babel-plugin-transform-react-jsx) and [@babel/preset-react](https://babeljs.io/docs/en/babel-preset-react).

> Note
>
> If you use JSX with a library other than React, you can use [the `importSource` option](https://babeljs.io/docs/en/babel-preset-react#importsource) to import from that library instead — as long as it provides the necessary entry points. Alternatively, you can keep using the classic transform which will continue to be supported.
>
> If you’re a library author and you are implementing the `/jsx-runtime` entry point for your library, keep in mind that [there is a case](https://github.com/facebook/react/issues/20031#issuecomment-710346866) in which even the new transform has to fall back to `createElement` for backwards compatibility. In that case, it will auto-import `createElement` directly from the *root* entry point specified by `importSource`.

### [](#eslint)ESLint

If you are using [eslint-plugin-react](https://github.com/yannickcr/eslint-plugin-react), the `react/jsx-uses-react` and `react/react-in-jsx-scope` rules are no longer necessary and can be turned off or removed.

```
{
  // ...
  "rules": {
    // ...
    "react/jsx-uses-react": "off",
    "react/react-in-jsx-scope": "off"
  }
}
```

### [](#typescript)TypeScript

TypeScript supports the new JSX transform in [v4.1](https://devblogs.microsoft.com/typescript/announcing-typescript-4-1/#jsx-factories) and up.

### [](#flow)Flow

Flow supports the new JSX transform in [v0.126.0](https://github.com/facebook/flow/releases/tag/v0.126.0) and up, by adding `react.runtime=automatic` to your Flow configuration options.

## [](#removing-unused-react-imports)Removing Unused React Imports

Because the new JSX transform will automatically import the necessary `react/jsx-runtime` functions, React will no longer need to be in scope when you use JSX. This might lead to unused React imports in your code. It doesn’t hurt to keep them, but if you’d like to remove them, we recommend running a [“codemod”](https://medium.com/@cpojer/effective-javascript-codemods-5a6686bb46fb) script to remove them automatically:

```
cd your_project
npx react-codemod update-react-imports
```

> Note
>
> If you’re getting errors when running the codemod, try specifying a different JavaScript dialect when `npx react-codemod update-react-imports` asks you to choose one. In particular, at this moment the “JavaScript with Flow” setting supports newer syntax than the “JavaScript” setting even if you don’t use Flow. [File an issue](https://github.com/reactjs/react-codemod/issues) if you run into problems.
>
> Keep in mind that the codemod output will not always match your project’s coding style, so you might want to run [Prettier](https://prettier.io/) after the codemod finishes for consistent formatting.

Running this codemod will:

* Remove all unused React imports as a result of upgrading to the new JSX transform.
* Change all default React imports (i.e. `import React from "react"`) to destructured named imports (ex. `import { useState } from "react"`) which is the preferred style going into the future. This codemod **will not** affect the existing namespace imports (i.e. `import * as React from "react"`) which is also a valid style. The default imports will keep working in React 17, but in the longer term we encourage moving away from them.

For example,

```
import React from 'react';

function App() {
  return <h1>Hello World</h1>;
}
```

will be replaced with

```
function App() {
  return <h1>Hello World</h1>;
}
```

If you use some other import from React — for example, a Hook — then the codemod will convert it to a named import.

For example,

```
import React from 'react';

function App() {
  const [text, setText] = React.useState('Hello World');
  return <h1>{text}</h1>;
}
```

will be replaced with

```
import { useState } from 'react';

function App() {
  const [text, setText] = useState('Hello World');
  return <h1>{text}</h1>;
}
```

In addition to cleaning up unused imports, this will also help you prepare for a future major version of React (not React 17) which will support ES Modules and not have a default export.

## [](#thanks)Thanks

We’d like to thank Babel, TypeScript, Create React App, Next.js, Gatsby, ESLint, and Flow maintainers for their help implementing and integrating the new JSX transform. We also want to thank the React community for their feedback and discussion on the related [technical RFC](https://github.com/reactjs/rfcs/pull/107).

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2020-09-22-introducing-the-new-jsx-transform.md)

----
url: https://18.react.dev/reference/react/useTransition
----

[API Reference](/reference/react)

[Hooks](/reference/react/hooks)

# useTransition[](#undefined "Link for this heading")

`useTransition` is a React Hook that lets you update the state without blocking the UI.

```
const [isPending, startTransition] = useTransition()
```

* [Reference](#reference)

  * [`useTransition()`](#usetransition)
  * [`startTransition` function](#starttransition)

* [Usage](#usage)

  * [Marking a state update as a non-blocking Transition](#marking-a-state-update-as-a-non-blocking-transition)
  * [Updating the parent component in a Transition](#updating-the-parent-component-in-a-transition)
  * [Displaying a pending visual state during the Transition](#displaying-a-pending-visual-state-during-the-transition)
  * [Preventing unwanted loading indicators](#preventing-unwanted-loading-indicators)
  * [Building a Suspense-enabled router](#building-a-suspense-enabled-router)
  * [Displaying an error to users with an error boundary](#displaying-an-error-to-users-with-error-boundary)

* [Troubleshooting](#troubleshooting)

  * [Updating an input in a Transition doesn’t work](#updating-an-input-in-a-transition-doesnt-work)
  * [React doesn’t treat my state update as a Transition](#react-doesnt-treat-my-state-update-as-a-transition)
  * [I want to call `useTransition` from outside a component](#i-want-to-call-usetransition-from-outside-a-component)
  * [The function I pass to `startTransition` executes immediately](#the-function-i-pass-to-starttransition-executes-immediately)

***

## Reference[](#reference "Link for Reference ")

### `useTransition()`[](#usetransition "Link for this heading")

Call `useTransition` at the top level of your component to mark some state updates as Transitions.

```
import { useTransition } from 'react';



function TabContainer() {

  const [isPending, startTransition] = useTransition();

  // ...

}
```

[See more examples below.](#usage)

#### Parameters[](#parameters "Link for Parameters ")

`useTransition` does not take any parameters.

#### Returns[](#returns "Link for Returns ")

`useTransition` returns an array with exactly two items:

1. The `isPending` flag that tells you whether there is a pending Transition.
2. The [`startTransition` function](#starttransition) that lets you mark a state update as a Transition.

***

### `startTransition` function[](#starttransition "Link for this heading")

The `startTransition` function returned by `useTransition` lets you mark a state update as a Transition.

```
function TabContainer() {

  const [isPending, startTransition] = useTransition();

  const [tab, setTab] = useState('about');



  function selectTab(nextTab) {

    startTransition(() => {

      setTab(nextTab);

    });

  }

  // ...

}
```

#### Parameters[](#starttransition-parameters "Link for Parameters ")

* `scope`: A function that updates some state by calling one or more [`set` functions.](/reference/react/useState#setstate) React immediately calls `scope` with no parameters and marks all state updates scheduled synchronously during the `scope` function call as Transitions. They will be [non-blocking](#marking-a-state-update-as-a-non-blocking-transition) and [will not display unwanted loading indicators.](#preventing-unwanted-loading-indicators)

#### Returns[](#starttransition-returns "Link for Returns ")

`startTransition` does not return anything.

#### Caveats[](#starttransition-caveats "Link for Caveats ")

* `useTransition` is a Hook, so it can only be called inside components or custom Hooks. If you need to start a Transition somewhere else (for example, from a data library), call the standalone [`startTransition`](/reference/react/startTransition) instead.

* You can wrap an update into a Transition only if you have access to the `set` function of that state. If you want to start a Transition in response to some prop or a custom Hook value, try [`useDeferredValue`](/reference/react/useDeferredValue) instead.

* The function you pass to `startTransition` must be synchronous. React immediately executes this function, marking all state updates that happen while it executes as Transitions. If you try to perform more state updates later (for example, in a timeout), they won’t be marked as Transitions.

* The `startTransition` function has a stable identity, so you will often see it omitted from Effect dependencies, but including it will not cause the Effect to fire. If the linter lets you omit a dependency without errors, it is safe to do. [Learn more about removing Effect dependencies.](/learn/removing-effect-dependencies#move-dynamic-objects-and-functions-inside-your-effect)

* A state update marked as a Transition will be interrupted by other state updates. For example, if you update a chart component inside a Transition, but then start typing into an input while the chart is in the middle of a re-render, React will restart the rendering work on the chart component after handling the input update.

* Transition updates can’t be used to control text inputs.

* If there are multiple ongoing Transitions, React currently batches them together. This is a limitation that will likely be removed in a future release.

***

## Usage[](#usage "Link for Usage ")

### Marking a state update as a non-blocking Transition[](#marking-a-state-update-as-a-non-blocking-transition "Link for Marking a state update as a non-blocking Transition ")

Call `useTransition` at the top level of your component to mark state updates as non-blocking *Transitions*.

```
import { useState, useTransition } from 'react';



function TabContainer() {

  const [isPending, startTransition] = useTransition();

  // ...

}
```

`useTransition` returns an array with exactly two items:

1. The `isPending` flag that tells you whether there is a pending Transition.
2. The `startTransition` function that lets you mark a state update as a Transition.

You can then mark a state update as a Transition like this:

```
function TabContainer() {

  const [isPending, startTransition] = useTransition();

  const [tab, setTab] = useState('about');



  function selectTab(nextTab) {

    startTransition(() => {

      setTab(nextTab);

    });

  }

  // ...

}
```

Transitions let you keep the user interface updates responsive even on slow devices.

With a Transition, your UI stays responsive in the middle of a re-render. For example, if the user clicks a tab but then change their mind and click another tab, they can do that without waiting for the first re-render to finish.

#### The difference between useTransition and regular state updates[](#examples "Link for The difference between useTransition and regular state updates")

#### Example 1 of 2:Updating the current tab in a Transition[](#updating-the-current-tab-in-a-transition "Link for this heading")

In this example, the “Posts” tab is **artificially slowed down** so that it takes at least a second to render.

Click “Posts” and then immediately click “Contact”. Notice that this interrupts the slow render of “Posts”. The “Contact” tab shows immediately. Because this state update is marked as a Transition, a slow re-render did not freeze the user interface.

```
import { useState, useTransition } from 'react';
import TabButton from './TabButton.js';
import AboutTab from './AboutTab.js';
import PostsTab from './PostsTab.js';
import ContactTab from './ContactTab.js';

export default function TabContainer() {
  const [isPending, startTransition] = useTransition();
  const [tab, setTab] = useState('about');

  function selectTab(nextTab) {
    startTransition(() => {
      setTab(nextTab);
    });
  }

  return (
    <>
      <TabButton
        isActive={tab === 'about'}
        onClick={() => selectTab('about')}
      >
        About
      </TabButton>
      <TabButton
        isActive={tab === 'posts'}
        onClick={() => selectTab('posts')}
      >
        Posts (slow)
      </TabButton>
      <TabButton
        isActive={tab === 'contact'}
        onClick={() => selectTab('contact')}
      >
        Contact
      </TabButton>
      <hr />
      {tab === 'about' && <AboutTab />}
      {tab === 'posts' && <PostsTab />}
      {tab === 'contact' && <ContactTab />}
    </>
  );
}
```

***

### Updating the parent component in a Transition[](#updating-the-parent-component-in-a-transition "Link for Updating the parent component in a Transition ")

You can update a parent component’s state from the `useTransition` call, too. For example, this `TabButton` component wraps its `onClick` logic in a Transition:

```
export default function TabButton({ children, isActive, onClick }) {

  const [isPending, startTransition] = useTransition();

  if (isActive) {

    return <b>{children}</b>

  }

  return (

    <button onClick={() => {

      startTransition(() => {

        onClick();

      });

    }}>

      {children}

    </button>

  );

}
```

Because the parent component updates its state inside the `onClick` event handler, that state update gets marked as a Transition. This is why, like in the earlier example, you can click on “Posts” and then immediately click “Contact”. Updating the selected tab is marked as a Transition, so it does not block user interactions.

```
import { useTransition } from 'react';

export default function TabButton({ children, isActive, onClick }) {
  const [isPending, startTransition] = useTransition();
  if (isActive) {
    return <b>{children}</b>
  }
  return (
    <button onClick={() => {
      startTransition(() => {
        onClick();
      });
    }}>
      {children}
    </button>
  );
}
```

***

### Displaying a pending visual state during the Transition[](#displaying-a-pending-visual-state-during-the-transition "Link for Displaying a pending visual state during the Transition ")

You can use the `isPending` boolean value returned by `useTransition` to indicate to the user that a Transition is in progress. For example, the tab button can have a special “pending” visual state:

```
function TabButton({ children, isActive, onClick }) {

  const [isPending, startTransition] = useTransition();

  // ...

  if (isPending) {

    return <b className="pending">{children}</b>;

  }

  // ...
```

Notice how clicking “Posts” now feels more responsive because the tab button itself updates right away:

```
import { useTransition } from 'react';

export default function TabButton({ children, isActive, onClick }) {
  const [isPending, startTransition] = useTransition();
  if (isActive) {
    return <b>{children}</b>
  }
  if (isPending) {
    return <b className="pending">{children}</b>;
  }
  return (
    <button onClick={() => {
      startTransition(() => {
        onClick();
      });
    }}>
      {children}
    </button>
  );
}
```

***

### Preventing unwanted loading indicators[](#preventing-unwanted-loading-indicators "Link for Preventing unwanted loading indicators ")

In this example, the `PostsTab` component fetches some data using a [Suspense-enabled](/reference/react/Suspense) data source. When you click the “Posts” tab, the `PostsTab` component *suspends*, causing the closest loading fallback to appear:

```
import { Suspense, useState } from 'react';
import TabButton from './TabButton.js';
import AboutTab from './AboutTab.js';
import PostsTab from './PostsTab.js';
import ContactTab from './ContactTab.js';

export default function TabContainer() {
  const [tab, setTab] = useState('about');
  return (
    <Suspense fallback={<h1>🌀 Loading...</h1>}>
      <TabButton
        isActive={tab === 'about'}
        onClick={() => setTab('about')}
      >
        About
      </TabButton>
      <TabButton
        isActive={tab === 'posts'}
        onClick={() => setTab('posts')}
      >
        Posts
      </TabButton>
      <TabButton
        isActive={tab === 'contact'}
        onClick={() => setTab('contact')}
      >
        Contact
      </TabButton>
      <hr />
      {tab === 'about' && <AboutTab />}
      {tab === 'posts' && <PostsTab />}
      {tab === 'contact' && <ContactTab />}
    </Suspense>
  );
}
```

Hiding the entire tab container to show a loading indicator leads to a jarring user experience. If you add `useTransition` to `TabButton`, you can instead indicate display the pending state in the tab button instead.

Notice that clicking “Posts” no longer replaces the entire tab container with a spinner:

```
import { useTransition } from 'react';

export default function TabButton({ children, isActive, onClick }) {
  const [isPending, startTransition] = useTransition();
  if (isActive) {
    return <b>{children}</b>
  }
  if (isPending) {
    return <b className="pending">{children}</b>;
  }
  return (
    <button onClick={() => {
      startTransition(() => {
        onClick();
      });
    }}>
      {children}
    </button>
  );
}
```

[Read more about using Transitions with Suspense.](/reference/react/Suspense#preventing-already-revealed-content-from-hiding)

### Note

Transitions will only “wait” long enough to avoid hiding *already revealed* content (like the tab container). If the Posts tab had a [nested `<Suspense>` boundary,](/reference/react/Suspense#revealing-nested-content-as-it-loads) the Transition would not “wait” for it.

***

### Building a Suspense-enabled router[](#building-a-suspense-enabled-router "Link for Building a Suspense-enabled router ")

If you’re building a React framework or a router, we recommend marking page navigations as Transitions.

```
function Router() {

  const [page, setPage] = useState('/');

  const [isPending, startTransition] = useTransition();



  function navigate(url) {

    startTransition(() => {

      setPage(url);

    });

  }

  // ...
```

This is recommended for two reasons:

* [Transitions are interruptible,](#marking-a-state-update-as-a-non-blocking-transition) which lets the user click away without waiting for the re-render to complete.
* [Transitions prevent unwanted loading indicators,](#preventing-unwanted-loading-indicators) which lets the user avoid jarring jumps on navigation.

Here is a tiny simplified router example using Transitions for navigations.

```
import { Suspense, useState, useTransition } from 'react';
import IndexPage from './IndexPage.js';
import ArtistPage from './ArtistPage.js';
import Layout from './Layout.js';

export default function App() {
  return (
    <Suspense fallback={<BigSpinner />}>
      <Router />
    </Suspense>
  );
}

function Router() {
  const [page, setPage] = useState('/');
  const [isPending, startTransition] = useTransition();

  function navigate(url) {
    startTransition(() => {
      setPage(url);
    });
  }

  let content;
  if (page === '/') {
    content = (
      <IndexPage navigate={navigate} />
    );
  } else if (page === '/the-beatles') {
    content = (
      <ArtistPage
        artist={{
          id: 'the-beatles',
          name: 'The Beatles',
        }}
      />
    );
  }
  return (
    <Layout isPending={isPending}>
      {content}
    </Layout>
  );
}

function BigSpinner() {
  return <h2>🌀 Loading...</h2>;
}
```

### Note

[Suspense-enabled](/reference/react/Suspense) routers are expected to wrap the navigation updates into Transitions by default.

***

### Displaying an error to users with an error boundary[](#displaying-an-error-to-users-with-error-boundary "Link for Displaying an error to users with an error boundary ")

### Canary

Error Boundary for useTransition is currently only available in React’s canary and experimental channels. Learn more about [React’s release channels here](/community/versioning-policy#all-release-channels).

If a function passed to `startTransition` throws an error, you can display an error to your user with an [error boundary](/reference/react/Component#catching-rendering-errors-with-an-error-boundary). To use an error boundary, wrap the component where you are calling the `useTransition` in an error boundary. Once the function passed to `startTransition` errors, the fallback for the error boundary will be displayed.

```
import { useTransition } from "react";
import { ErrorBoundary } from "react-error-boundary";

export function AddCommentContainer() {
  return (
    <ErrorBoundary fallback={<p>⚠️Something went wrong</p>}>
      <AddCommentButton />
    </ErrorBoundary>
  );
}

function addComment(comment) {
  // For demonstration purposes to show Error Boundary
  if (comment == null) {
    throw new Error("Example Error: An error thrown to trigger error boundary");
  }
}

function AddCommentButton() {
  const [pending, startTransition] = useTransition();

  return (
    <button
      disabled={pending}
      onClick={() => {
        startTransition(() => {
          // Intentionally not passing a comment
          // so error gets thrown
          addComment();
        });
      }}
    >
      Add comment
    </button>
  );
}
```

***

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### Updating an input in a Transition doesn’t work[](#updating-an-input-in-a-transition-doesnt-work "Link for Updating an input in a Transition doesn’t work ")

You can’t use a Transition for a state variable that controls an input:

```
const [text, setText] = useState('');

// ...

function handleChange(e) {

  // ❌ Can't use Transitions for controlled input state

  startTransition(() => {

    setText(e.target.value);

  });

}

// ...

return <input value={text} onChange={handleChange} />;
```

This is because Transitions are non-blocking, but updating an input in response to the change event should happen synchronously. If you want to run a Transition in response to typing, you have two options:

1. You can declare two separate state variables: one for the input state (which always updates synchronously), and one that you will update in a Transition. This lets you control the input using the synchronous state, and pass the Transition state variable (which will “lag behind” the input) to the rest of your rendering logic.
2. Alternatively, you can have one state variable, and add [`useDeferredValue`](/reference/react/useDeferredValue) which will “lag behind” the real value. It will trigger non-blocking re-renders to “catch up” with the new value automatically.

***

### React doesn’t treat my state update as a Transition[](#react-doesnt-treat-my-state-update-as-a-transition "Link for React doesn’t treat my state update as a Transition ")

When you wrap a state update in a Transition, make sure that it happens *during* the `startTransition` call:

```
startTransition(() => {

  // ✅ Setting state *during* startTransition call

  setPage('/about');

});
```

The function you pass to `startTransition` must be synchronous.

You can’t mark an update as a Transition like this:

```
startTransition(() => {

  // ❌ Setting state *after* startTransition call

  setTimeout(() => {

    setPage('/about');

  }, 1000);

});
```

Instead, you could do this:

```
setTimeout(() => {

  startTransition(() => {

    // ✅ Setting state *during* startTransition call

    setPage('/about');

  });

}, 1000);
```

Similarly, you can’t mark an update as a Transition like this:

```
startTransition(async () => {

  await someAsyncFunction();

  // ❌ Setting state *after* startTransition call

  setPage('/about');

});
```

However, this works instead:

```
await someAsyncFunction();

startTransition(() => {

  // ✅ Setting state *during* startTransition call

  setPage('/about');

});
```

***

### I want to call `useTransition` from outside a component[](#i-want-to-call-usetransition-from-outside-a-component "Link for this heading")

You can’t call `useTransition` outside a component because it’s a Hook. In this case, use the standalone [`startTransition`](/reference/react/startTransition) method instead. It works the same way, but it doesn’t provide the `isPending` indicator.

***

### The function I pass to `startTransition` executes immediately[](#the-function-i-pass-to-starttransition-executes-immediately "Link for this heading")

If you run this code, it will print 1, 2, 3:

```
console.log(1);

startTransition(() => {

  console.log(2);

  setPage('/about');

});

console.log(3);
```

**It is expected to print 1, 2, 3.** The function you pass to `startTransition` does not get delayed. Unlike with the browser `setTimeout`, it does not run the callback later. React executes your function immediately, but any state updates scheduled *while it is running* are marked as Transitions. You can imagine that it works like this:

```
// A simplified version of how React works



let isInsideTransition = false;



function startTransition(scope) {

  isInsideTransition = true;

  scope();

  isInsideTransition = false;

}



function setState() {

  if (isInsideTransition) {

    // ... schedule a Transition state update ...

  } else {

    // ... schedule an urgent state update ...

  }

}
```

[PrevioususeSyncExternalStore](/reference/react/useSyncExternalStore)

[NextComponents](/reference/react/components)

***

----
url: https://legacy.reactjs.org/docs/conditional-rendering.html
----

> These docs are old and won’t be updated. Go to [react.dev](https://react.dev/) for the new React docs.
>
> These new documentation pages teach modern React and include live examples:
>
> * [Conditional Rendering](https://react.dev/learn/conditional-rendering)

In React, you can create distinct components that encapsulate behavior you need. Then, you can render only some of them, depending on the state of your application.

Conditional rendering in React works the same way conditions work in JavaScript. Use JavaScript operators like [`if`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/if...else) or the [conditional operator](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Conditional_Operator) to create elements representing the current state, and let React update the UI to match them.

Consider these two components:

```
function UserGreeting(props) {
  return <h1>Welcome back!</h1>;
}

function GuestGreeting(props) {
  return <h1>Please sign up.</h1>;
}
```

We’ll create a `Greeting` component that displays either of these components depending on whether a user is logged in:

```
function Greeting(props) {
  const isLoggedIn = props.isLoggedIn;
  if (isLoggedIn) {    return <UserGreeting />;  }  return <GuestGreeting />;}
const root = ReactDOM.createRoot(document.getElementById('root')); 
// Try changing to isLoggedIn={true}:
root.render(<Greeting isLoggedIn={false} />);
```

[**Try it on CodePen**](https://codepen.io/gaearon/pen/ZpVxNq?editors=0011)

This example renders a different greeting depending on the value of `isLoggedIn` prop.

### [](#element-variables)Element Variables

You can use variables to store elements. This can help you conditionally render a part of the component while the rest of the output doesn’t change.

Consider these two new components representing Logout and Login buttons:

```
function LoginButton(props) {
  return (
    <button onClick={props.onClick}>
      Login
    </button>
  );
}

function LogoutButton(props) {
  return (
    <button onClick={props.onClick}>
      Logout
    </button>
  );
}
```

In the example below, we will create a [stateful component](/docs/state-and-lifecycle.html#adding-local-state-to-a-class) called `LoginControl`.

It will render either `<LoginButton />` or `<LogoutButton />` depending on its current state. It will also render a `<Greeting />` from the previous example:

```
class LoginControl extends React.Component {
  constructor(props) {
    super(props);
    this.handleLoginClick = this.handleLoginClick.bind(this);
    this.handleLogoutClick = this.handleLogoutClick.bind(this);
    this.state = {isLoggedIn: false};
  }

  handleLoginClick() {
    this.setState({isLoggedIn: true});
  }

  handleLogoutClick() {
    this.setState({isLoggedIn: false});
  }

  render() {
    const isLoggedIn = this.state.isLoggedIn;
    let button;
    if (isLoggedIn) {      button = <LogoutButton onClick={this.handleLogoutClick} />;    } else {      button = <LoginButton onClick={this.handleLoginClick} />;    }
    return (
      <div>
        <Greeting isLoggedIn={isLoggedIn} />        {button}      </div>
    );
  }
}

const root = ReactDOM.createRoot(document.getElementById('root')); 
root.render(<LoginControl />);
```

[**Try it on CodePen**](https://codepen.io/gaearon/pen/QKzAgB?editors=0010)

While declaring a variable and using an `if` statement is a fine way to conditionally render a component, sometimes you might want to use a shorter syntax. There are a few ways to inline conditions in JSX, explained below.

### [](#inline-if-with-logical--operator)Inline If with Logical && Operator

You may [embed expressions in JSX](/docs/introducing-jsx.html#embedding-expressions-in-jsx) by wrapping them in curly braces. This includes the JavaScript logical `&&` operator. It can be handy for conditionally including an element:

```
function Mailbox(props) {
  const unreadMessages = props.unreadMessages;
  return (
    <div>
      <h1>Hello!</h1>
      {unreadMessages.length > 0 &&        <h2>          You have {unreadMessages.length} unread messages.        </h2>      }    </div>
  );
}

const messages = ['React', 'Re: React', 'Re:Re: React'];

const root = ReactDOM.createRoot(document.getElementById('root')); 
root.render(<Mailbox unreadMessages={messages} />);
```

[**Try it on CodePen**](https://codepen.io/gaearon/pen/ozJddz?editors=0010)

It works because in JavaScript, `true && expression` always evaluates to `expression`, and `false && expression` always evaluates to `false`.

Therefore, if the condition is `true`, the element right after `&&` will appear in the output. If it is `false`, React will ignore and skip it.

Note that returning a falsy expression will still cause the element after `&&` to be skipped but will return the falsy expression. In the example below, `<div>0</div>` will be returned by the render method.

```
render() {
  const count = 0;  return (
    <div>
      {count && <h1>Messages: {count}</h1>}    </div>
  );
}
```

### [](#inline-if-else-with-conditional-operator)Inline If-Else with Conditional Operator

Another method for conditionally rendering elements inline is to use the JavaScript conditional operator [`condition ? true : false`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Conditional_Operator).

In the example below, we use it to conditionally render a small block of text.

```
render() {
  const isLoggedIn = this.state.isLoggedIn;
  return (
    <div>
      The user is <b>{isLoggedIn ? 'currently' : 'not'}</b> logged in.    </div>
  );
}
```

It can also be used for larger expressions although it is less obvious what’s going on:

```
render() {
  const isLoggedIn = this.state.isLoggedIn;
  return (
    <div>
      {isLoggedIn        ? <LogoutButton onClick={this.handleLogoutClick} />
        : <LoginButton onClick={this.handleLoginClick} />      }
    </div>  );
}
```

Just like in JavaScript, it is up to you to choose an appropriate style based on what you and your team consider more readable. Also remember that whenever conditions become too complex, it might be a good time to [extract a component](/docs/components-and-props.html#extracting-components).

### [](#preventing-component-from-rendering)Preventing Component from Rendering

In rare cases you might want a component to hide itself even though it was rendered by another component. To do this return `null` instead of its render output.

In the example below, the `<WarningBanner />` is rendered depending on the value of the prop called `warn`. If the value of the prop is `false`, then the component does not render:

```
function WarningBanner(props) {
  if (!props.warn) {    return null;  }
  return (
    <div className="warning">
      Warning!
    </div>
  );
}

class Page extends React.Component {
  constructor(props) {
    super(props);
    this.state = {showWarning: true};
    this.handleToggleClick = this.handleToggleClick.bind(this);
  }

  handleToggleClick() {
    this.setState(state => ({
      showWarning: !state.showWarning
    }));
  }

  render() {
    return (
      <div>
        <WarningBanner warn={this.state.showWarning} />        <button onClick={this.handleToggleClick}>
          {this.state.showWarning ? 'Hide' : 'Show'}
        </button>
      </div>
    );
  }
}

const root = ReactDOM.createRoot(document.getElementById('root')); 
root.render(<Page />);
```

[**Try it on CodePen**](https://codepen.io/gaearon/pen/Xjoqwm?editors=0010)

Returning `null` from a component’s `render` method does not affect the firing of the component’s lifecycle methods. For instance `componentDidUpdate` will still be called.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/conditional-rendering.md)

* Previous article

  [Handling Events](/docs/handling-events.html)

* Next article

  [Lists and Keys](/docs/lists-and-keys.html)

----
url: https://react.dev/reference/react/addTransitionType
----

[API Reference](/reference/react)

[APIs](/reference/react/apis)

# addTransitionType[](#undefined "Link for this heading")

### Canary

**The `addTransitionType` API is currently only available in React’s Canary and Experimental channels.**

[Learn more about React’s release channels here.](/community/versioning-policy#all-release-channels)

`addTransitionType` lets you specify the cause of a transition.

```
startTransition(() => {

  addTransitionType('my-transition-type');

  setState(newState);

});
```

* [Reference](#reference)
  * [`addTransitionType`](#addtransitiontype)

* [Usage](#usage)

  * [Adding the cause of a transition](#adding-the-cause-of-a-transition)
  * [Customize animations using browser view transition types](#customize-animations-using-browser-view-transition-types)
  * [Customize animations using `View Transition` Class](#customize-animations-using-view-transition-class)
  * [Customize animations using `ViewTransition` events](#customize-animations-using-viewtransition-events)

***

## Reference[](#reference "Link for Reference ")

### `addTransitionType`[](#addtransitiontype "Link for this heading")

#### Parameters[](#parameters "Link for Parameters ")

* `type`: The type of transition to add. This can be any string.

#### Returns[](#returns "Link for Returns ")

`addTransitionType` does not return anything.

#### Caveats[](#caveats "Link for Caveats ")

* If multiple transitions are combined, all Transition Types are collected. You can also add more than one type to a Transition.
* Transition Types are reset after each commit. This means a `<Suspense>` fallback will associate the types after a `startTransition`, but revealing the content does not.

***

## Usage[](#usage "Link for Usage ")

### Adding the cause of a transition[](#adding-the-cause-of-a-transition "Link for Adding the cause of a transition ")

Call `addTransitionType` inside of `startTransition` to indicate the cause of a transition:

```
import { startTransition, addTransitionType } from 'react';



function Submit({action) {

  function handleClick() {

    startTransition(() => {

      addTransitionType('submit-click');

      action();

    });

  }



  return <button onClick={handleClick}>Click me</button>;

}
```

When you call addTransitionType inside the scope of startTransition, React will associate submit-click as one of the causes for the Transition.

Currently, Transition Types can be used to customize different animations based on what caused the Transition. You have three different ways to choose from for how to use them:

* [Customize animations using browser view transition types](#customize-animations-using-browser-view-transition-types)
* [Customize animations using `View Transition` Class](#customize-animations-using-view-transition-class)
* [Customize animations using `ViewTransition` events](#customize-animations-using-viewtransition-events)

In the future, we plan to support more use cases for using the cause of a transition.

***

### Customize animations using browser view transition types[](#customize-animations-using-browser-view-transition-types "Link for Customize animations using browser view transition types ")

When a [`ViewTransition`](/reference/react/ViewTransition) activates from a transition, React adds all the Transition Types as browser [view transition types](https://www.w3.org/TR/css-view-transitions-2/#active-view-transition-pseudo-examples) to the element.

This allows you to customize different animations based on CSS scopes:

```
function Component() {

  return (

    <ViewTransition>

      <div>Hello</div>

    </ViewTransition>

  );

}



startTransition(() => {

  addTransitionType('my-transition-type');

  setShow(true);

});
```

```
:root:active-view-transition-type(my-transition-type) {

  &::view-transition-...(...) {

    ...

  }

}
```

***

### Customize animations using `View Transition` Class[](#customize-animations-using-view-transition-class "Link for this heading")

You can customize animations for an activated `ViewTransition` based on type by passing an object to the View Transition Class:

```
function Component() {

  return (

    <ViewTransition enter={{

      'my-transition-type': 'my-transition-class',

    }}>

      <div>Hello</div>

    </ViewTransition>

  );

}



// ...

startTransition(() => {

  addTransitionType('my-transition-type');

  setState(newState);

});
```

If multiple types match, then they’re joined together. If no types match then the special “default” entry is used instead. If any type has the value “none” then that wins and the ViewTransition is disabled (not assigned a name).

These can be combined with enter/exit/update/layout/share props to match based on kind of trigger and Transition Type.

```
<ViewTransition enter={{

  'navigation-back': 'enter-right',

  'navigation-forward': 'enter-left',

}}

exit={{

  'navigation-back': 'exit-right',

  'navigation-forward': 'exit-left',

}}>
```

***

### Customize animations using `ViewTransition` events[](#customize-animations-using-viewtransition-events "Link for this heading")

You can imperatively customize animations for an activated `ViewTransition` based on type using View Transition events:

```
<ViewTransition onUpdate={(inst, types) => {

  if (types.includes('navigation-back')) {

    ...

  } else if (types.includes('navigation-forward')) {

    ...

  } else {

    ...

  }

}}>
```

This allows you to pick different imperative Animations based on the cause.

[Previousact](/reference/react/act)

[Nextcache](/reference/react/cache)

***

----
url: https://18.react.dev/reference/react/PureComponent
----

[API Reference](/reference/react)

[Legacy React APIs](/reference/react/legacy)

# PureComponent[](#undefined "Link for this heading")

### Pitfall

We recommend defining components as functions instead of classes. [See how to migrate.](#alternatives)

`PureComponent` is similar to [`Component`](/reference/react/Component) but it skips re-renders for same props and state. Class components are still supported by React, but we don’t recommend using them in new code.

```
class Greeting extends PureComponent {

  render() {

    return <h1>Hello, {this.props.name}!</h1>;

  }

}
```

* [Reference](#reference)
  * [`PureComponent`](#purecomponent)
* [Usage](#usage)
  * [Skipping unnecessary re-renders for class components](#skipping-unnecessary-re-renders-for-class-components)
* [Alternatives](#alternatives)
  * [Migrating from a `PureComponent` class component to a function](#migrating-from-a-purecomponent-class-component-to-a-function)

***

## Reference[](#reference "Link for Reference ")

### `PureComponent`[](#purecomponent "Link for this heading")

To skip re-rendering a class component for same props and state, extend `PureComponent` instead of [`Component`:](/reference/react/Component)

```
import { PureComponent } from 'react';



class Greeting extends PureComponent {

  render() {

    return <h1>Hello, {this.props.name}!</h1>;

  }

}
```

`PureComponent` is a subclass of `Component` and supports [all the `Component` APIs.](/reference/react/Component#reference) Extending `PureComponent` is equivalent to defining a custom [`shouldComponentUpdate`](/reference/react/Component#shouldcomponentupdate) method that shallowly compares props and state.

[See more examples below.](#usage)

***

## Usage[](#usage "Link for Usage ")

### Skipping unnecessary re-renders for class components[](#skipping-unnecessary-re-renders-for-class-components "Link for Skipping unnecessary re-renders for class components ")

React normally re-renders a component whenever its parent re-renders. As an optimization, you can create a component that React will not re-render when its parent re-renders so long as its new props and state are the same as the old props and state. [Class components](/reference/react/Component) can opt into this behavior by extending `PureComponent`:

```
class Greeting extends PureComponent {

  render() {

    return <h1>Hello, {this.props.name}!</h1>;

  }

}
```

A React component should always have [pure rendering logic.](/learn/keeping-components-pure) This means that it must return the same output if its props, state, and context haven’t changed. By using `PureComponent`, you are telling React that your component complies with this requirement, so React doesn’t need to re-render as long as its props and state haven’t changed. However, your component will still re-render if a context that it’s using changes.

In this example, notice that the `Greeting` component re-renders whenever `name` is changed (because that’s one of its props), but not when `address` is changed (because it’s not passed to `Greeting` as a prop):

```
import { PureComponent, useState } from 'react';

class Greeting extends PureComponent {
  render() {
    console.log("Greeting was rendered at", new Date().toLocaleTimeString());
    return <h3>Hello{this.props.name && ', '}{this.props.name}!</h3>;
  }
}

export default function MyApp() {
  const [name, setName] = useState('');
  const [address, setAddress] = useState('');
  return (
    <>
      <label>
        Name{': '}
        <input value={name} onChange={e => setName(e.target.value)} />
      </label>
      <label>
        Address{': '}
        <input value={address} onChange={e => setAddress(e.target.value)} />
      </label>
      <Greeting name={name} />
    </>
  );
}
```

### Pitfall

We recommend defining components as functions instead of classes. [See how to migrate.](#alternatives)

***

## Alternatives[](#alternatives "Link for Alternatives ")

### Migrating from a `PureComponent` class component to a function[](#migrating-from-a-purecomponent-class-component-to-a-function "Link for this heading")

We recommend using function components instead of [class components](/reference/react/Component) in new code. If you have some existing class components using `PureComponent`, here is how you can convert them. This is the original code:

```
import { PureComponent, useState } from 'react';

class Greeting extends PureComponent {
  render() {
    console.log("Greeting was rendered at", new Date().toLocaleTimeString());
    return <h3>Hello{this.props.name && ', '}{this.props.name}!</h3>;
  }
}

export default function MyApp() {
  const [name, setName] = useState('');
  const [address, setAddress] = useState('');
  return (
    <>
      <label>
        Name{': '}
        <input value={name} onChange={e => setName(e.target.value)} />
      </label>
      <label>
        Address{': '}
        <input value={address} onChange={e => setAddress(e.target.value)} />
      </label>
      <Greeting name={name} />
    </>
  );
}
```

When you [convert this component from a class to a function,](/reference/react/Component#alternatives) wrap it in [`memo`:](/reference/react/memo)

```
import { memo, useState } from 'react';

const Greeting = memo(function Greeting({ name }) {
  console.log("Greeting was rendered at", new Date().toLocaleTimeString());
  return <h3>Hello{name && ', '}{name}!</h3>;
});

export default function MyApp() {
  const [name, setName] = useState('');
  const [address, setAddress] = useState('');
  return (
    <>
      <label>
        Name{': '}
        <input value={name} onChange={e => setName(e.target.value)} />
      </label>
      <label>
        Address{': '}
        <input value={address} onChange={e => setAddress(e.target.value)} />
      </label>
      <Greeting name={name} />
    </>
  );
}
```

### Note

Unlike `PureComponent`, [`memo`](/reference/react/memo) does not compare the new and the old state. In function components, calling the [`set` function](/reference/react/useState#setstate) with the same state [already prevents re-renders by default,](/reference/react/memo#updating-a-memoized-component-using-state) even without `memo`.

[PreviousisValidElement](/reference/react/isValidElement)

***

----
url: https://legacy.reactjs.org/blog/2021/12/17/react-conf-2021-recap.html
----

December 17, 2021 by [Jesslyn Tannady](https://twitter.com/jtannady) and [Rick Hanlon](https://twitter.com/rickhanlonii)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

Last week we hosted our 6th React Conf. In previous years, we’ve used the React Conf stage to deliver industry changing announcements such as [*React Native*](https://engineering.fb.com/2015/03/26/android/react-native-bringing-modern-web-techniques-to-mobile/) and [*React Hooks*](https://reactjs.org/docs/hooks-intro.html). This year, we shared our multi-platform vision for React, starting with the release of React 18 and gradual adoption of concurrent features.

This was the first time React Conf was hosted online, and it was streamed for free, translated to 8 different languages. Participants from all over the world joined our conference Discord and the replay event for accessibility in all timezones. Over 50,000 people registered, with over 60,000 views of 19 talks, and 5,000 participants in Discord across both events.

All the talks are [available to stream online](https://www.youtube.com/watch?v=FZ0cG47msEk\&list=PLNG_1j3cPCaZZ7etkzWA7JfdmKWT0pMsa).

Here’s a summary of what was shared on stage:

## [](#react-18-and-concurrent-features)React 18 and concurrent features

In the keynote, we shared our vision for the future of React starting with React 18.

React 18 adds the long-awaited concurrent renderer and updates to Suspense without any major breaking changes. Apps can upgrade to React 18 and begin gradually adopting concurrent features with the amount of effort on par with any other major release.

**This means there is no concurrent mode, only concurrent features.**

In the keynote, we also shared our vision for Suspense, Server Components, new React working groups, and our long-term many-platform vision for React Native.

Watch the full keynote from [Andrew Clark](https://twitter.com/acdlite), [Juan Tejada](https://twitter.com/_jstejada), [Lauren Tan](https://twitter.com/potetotes), and [Rick Hanlon](https://twitter.com/rickhanlonii) here:

## [](#react-18-for-application-developers)React 18 for Application Developers

In the keynote, we also announced that the React 18 RC is available to try now. Pending further feedback, this is the exact version of React that we will publish to stable early next year.

To try the React 18 RC, upgrade your dependencies:

```
npm install react@rc react-dom@rc
```

and switch to the new `createRoot` API:

```
// before
const container = document.getElementById('root');
ReactDOM.render(<App />, container);

// after
const container = document.getElementById('root');
const root = ReactDOM.createRoot(container);
root.render(<App/>);
```

For a demo of upgrading to React 18, see [Shruti Kapoor](https://twitter.com/shrutikapoor08)’s talk here:

## [](#streaming-server-rendering-with-suspense)Streaming Server Rendering with Suspense

React 18 also includes improvements to server-side rendering performance using Suspense.

Streaming server rendering lets you generate HTML from React components on the server, and stream that HTML to your users. In React 18, you can use `Suspense` to break down your app into smaller independent units which can be streamed independently of each other without blocking the rest of the app. This means users will see your content sooner and be able to start interacting with it much faster.

For a deep dive, see [Shaundai Person](https://twitter.com/shaundai)’s talk here:

## [](#the-first-react-working-group)The first React working group

For React 18, we created our first Working Group to collaborate with a panel of experts, developers, library maintainers, and educators. Together we worked to create our gradual adoption strategy and refine new APIs such as `useId`, `useSyncExternalStore`, and `useInsertionEffect`.

For an overview of this work, see [Aakansha’ Doshi](https://twitter.com/aakansha1216)’s talk:

## [](#react-developer-tooling)React Developer Tooling

To support the new features in this release, we also announced the newly formed React DevTools team and a new Timeline Profiler to help developers debug their React apps.

For more information and a demo of new DevTools features, see [Brian Vaughn](https://twitter.com/brian_d_vaughn)’s talk:

## [](#react-without-memo)React without memo

Looking further into the future, [Xuan Huang (黄玄)](https://twitter.com/Huxpro) shared an update from our React Labs research into an auto-memoizing compiler. Check out this talk for more information and a demo of the compiler prototype:

## [](#react-docs-keynote)React docs keynote

[Rachel Nabors](https://twitter.com/rachelnabors) kicked off a section of talks about learning and designing with React with a keynote about our investment in React’s [new docs](https://react.dev/):

# [](#and-more)And more…

# [](#thank-you)Thank you

This was our first year planning a conference ourselves, and we have a lot of people to thank.

First, thanks to all of our speakers [Aakansha Doshi](https://twitter.com/aakansha1216), [Andrew Clark](https://twitter.com/acdlite), [Brian Vaughn](https://twitter.com/brian_d_vaughn), [Daishi Kato](https://twitter.com/dai_shi), [Debbie O’Brien](https://twitter.com/debs_obrien), [Delba de Oliveira](https://twitter.com/delba_oliveira), [Diego Haz](https://twitter.com/diegohaz), [Eric Rozell](https://twitter.com/EricRozell), [Helen Lin](https://twitter.com/wizardlyhel), [Juan Tejada](https://twitter.com/_jstejada), [Lauren Tan](https://twitter.com/potetotes), [Linton Ye](https://twitter.com/lintonye), [Lyle Troxell](https://twitter.com/lyle), [Rachel Nabors](https://twitter.com/rachelnabors), [Rick Hanlon](https://twitter.com/rickhanlonii), [Robert Balicki](https://twitter.com/StatisticsFTW), [Roman Rädle](https://twitter.com/raedle), [Sarah Rainsberger](https://twitter.com/sarah11918), [Shaundai Person](https://twitter.com/shaundai), [Shruti Kapoor](https://twitter.com/shrutikapoor08), [Steven Moyes](https://twitter.com/moyessa), [Tafu Nakazaki](https://twitter.com/hawaiiman0), and [Xuan Huang (黄玄)](https://twitter.com/Huxpro).

Thanks to everyone who helped provide feedback on talks including [Andrew Clark](https://twitter.com/acdlite), [Dan Abramov](https://twitter.com/dan_abramov), [Dave McCabe](https://twitter.com/mcc_abe), [Eli White](https://twitter.com/Eli_White), [Joe Savona](https://twitter.com/en_JS), [Lauren Tan](https://twitter.com/potetotes), [Rachel Nabors](https://twitter.com/rachelnabors), and [Tim Yung](https://twitter.com/yungsters).

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2021-12-17-react-conf-2021-recap.md)

----
url: https://legacy.reactjs.org/languages
----

# Languages

The React documentation is available in the following languages:

* Arabic

  [العربية](https://ar.reactjs.org/)

  [Contribute](https://github.com/reactjs/ar.reactjs.org/)

* Azerbaijani

  [Azərbaycanca](https://az.reactjs.org/)

  [Contribute](https://github.com/reactjs/az.reactjs.org/)

* English

  [English](https://reactjs.org/)

  [Contribute](https://github.com/reactjs/reactjs.org/)

* Spanish

  [Español](https://es.reactjs.org/)

  [Contribute](https://github.com/reactjs/es.reactjs.org/)

* French

  [Français](https://fr.reactjs.org/)

  [Contribute](https://github.com/reactjs/fr.reactjs.org/)

* Hungarian

  [magyar](https://hu.reactjs.org/)

  [Contribute](https://github.com/reactjs/hu.reactjs.org/)

* Italian

  [Italiano](https://it.reactjs.org/)

  [Contribute](https://github.com/reactjs/it.reactjs.org/)

* Japanese

  [日本語](https://ja.reactjs.org/)

  [Contribute](https://github.com/reactjs/ja.reactjs.org/)

* Korean

  [한국어](https://ko.reactjs.org/)

  [Contribute](https://github.com/reactjs/ko.reactjs.org/)

* Mongolian

  [Монгол хэл](https://mn.reactjs.org/)

  [Contribute](https://github.com/reactjs/mn.reactjs.org/)

* Polish

  [Polski](https://pl.reactjs.org/)

  [Contribute](https://github.com/reactjs/pl.reactjs.org/)

* Portuguese (Brazil)

  [Português do Brasil](https://pt-br.reactjs.org/)

  [Contribute](https://github.com/reactjs/pt-br.reactjs.org/)

* Russian

  [Русский](https://ru.reactjs.org/)

  [Contribute](https://github.com/reactjs/ru.reactjs.org/)

* Turkish

  [Türkçe](https://tr.reactjs.org/)

  [Contribute](https://github.com/reactjs/tr.reactjs.org/)

* Ukrainian

  [Українська](https://uk.reactjs.org/)

  [Contribute](https://github.com/reactjs/uk.reactjs.org/)

* Simplified Chinese

  [简体中文](https://zh-hans.reactjs.org/)

  [Contribute](https://github.com/reactjs/zh-hans.reactjs.org/)

* Traditional Chinese

  [繁體中文](https://zh-hant.reactjs.org/)

  [Contribute](https://github.com/reactjs/zh-hant.reactjs.org/)

## In Progress

* Bulgarian

  [Български](https://bg.reactjs.org/)

  [Contribute](https://github.com/reactjs/bg.reactjs.org/)

* Bengali

  [বাংলা](https://bn.reactjs.org/)

  [Contribute](https://github.com/reactjs/bn.reactjs.org/)

* Catalan

  [Català](https://ca.reactjs.org/)

  [Contribute](https://github.com/reactjs/ca.reactjs.org/)

* German

  [Deutsch](https://de.reactjs.org/)

  [Contribute](https://github.com/reactjs/de.reactjs.org/)

* Greek

  [Ελληνικά](https://el.reactjs.org/)

  [Contribute](https://github.com/reactjs/el.reactjs.org/)

* Persian

  [فارسی](https://fa.reactjs.org/)

  [Contribute](https://github.com/reactjs/fa.reactjs.org/)

* Hebrew

  [עברית](https://he.reactjs.org/)

  [Contribute](https://github.com/reactjs/he.reactjs.org/)

* Indonesian

  [Bahasa Indonesia](https://id.reactjs.org/)

  [Contribute](https://github.com/reactjs/id.reactjs.org/)

* Vietnamese

  [Tiếng Việt](https://vi.reactjs.org/)

  [Contribute](https://github.com/reactjs/vi.reactjs.org/)

## Needs Contributors

* Gujarati

  ગુજરાતી

  [Contribute](https://github.com/reactjs/gu.reactjs.org/)

* Hindi

  हिन्दी

  [Contribute](https://github.com/reactjs/hi.reactjs.org/)

* Haitian Creole

  Kreyòl ayisyen

  [Contribute](https://github.com/reactjs/ht.reactjs.org/)

* Armenian

  Հայերեն

  [Contribute](https://github.com/reactjs/hy.reactjs.org/)

* Georgian

  ქართული

  [Contribute](https://github.com/reactjs/ka.reactjs.org/)

* Central Khmer

  ភាសាខ្មែរ

  [Contribute](https://github.com/reactjs/km.reactjs.org/)

* Kannada

  ಕನ್ನಡ

  [Contribute](https://github.com/reactjs/kn.reactjs.org/)

* Kurdish

  کوردی‎

  [Contribute](https://github.com/reactjs/ku.reactjs.org/)

* Lithuanian

  Lietuvių kalba

  [Contribute](https://github.com/reactjs/lt.reactjs.org/)

* Malayalam

  മലയാളം

  [Contribute](https://github.com/reactjs/ml.reactjs.org/)

* Nepali

  नेपाली

  [Contribute](https://github.com/reactjs/ne.reactjs.org/)

* Dutch

  Nederlands

  [Contribute](https://github.com/reactjs/nl.reactjs.org/)

* Portuguese (Portugal)

  Português europeu

  [Contribute](https://github.com/reactjs/pt-pt.reactjs.org/)

* Romanian

  Română

  [Contribute](https://github.com/reactjs/ro.reactjs.org/)

* Sinhala

  සිංහල

  [Contribute](https://github.com/reactjs/si.reactjs.org/)

* Swedish

  Svenska

  [Contribute](https://github.com/reactjs/sv.reactjs.org/)

* Tamil

  தமிழ்

  [Contribute](https://github.com/reactjs/ta.reactjs.org/)

* Telugu

  తెలుగు

  [Contribute](https://github.com/reactjs/te.reactjs.org/)

* Thai

  ไทย

  [Contribute](https://github.com/reactjs/th.reactjs.org/)

* Tagalog

  Wikang Tagalog

  [Contribute](https://github.com/reactjs/tl.reactjs.org/)

* Urdu

  اردو

  [Contribute](https://github.com/reactjs/ur.reactjs.org/)

* Uzbek

  Oʻzbekcha

  [Contribute](https://github.com/reactjs/uz.reactjs.org/)

Don't see your language above? [Let us know](https://github.com/reactjs/reactjs.org-translation#reactjsorg-translation).

----
url: https://react.dev/blog/2021/06/08/the-plan-for-react-18
----

[Blog](/blog)

# The Plan for React 18[](#undefined "Link for this heading")

June 8, 2021 by [Andrew Clark](https://twitter.com/acdlite), [Brian Vaughn](https://github.com/bvaughn), [Christine Abernathy](https://twitter.com/abernathyca), [Dan Abramov](https://bsky.app/profile/danabra.mov), [Rachel Nabors](https://twitter.com/rachelnabors), [Rick Hanlon](https://twitter.com/rickhanlonii), [Sebastian Markbåge](https://twitter.com/sebmarkbage), and [Seth Webster](https://twitter.com/sethwebster)

***

The React team is excited to share a few updates:

1. We’ve started work on the React 18 release, which will be our next major version.
2. We’ve created a Working Group to prepare the community for gradual adoption of new features in React 18.
3. We’ve published a React 18 Alpha so that library authors can try it and provide feedback.

These updates are primarily aimed at maintainers of third-party libraries. If you’re learning, teaching, or using React to build user-facing applications, you can safely ignore this post. But you are welcome to follow the discussions in the React 18 Working Group if you’re curious!

***

## What’s coming in React 18[](#whats-coming-in-react-18 "Link for What’s coming in React 18 ")

When it’s released, React 18 will include out-of-the-box improvements (like [automatic batching](https://github.com/reactwg/react-18/discussions/21)), new APIs (like [`startTransition`](https://github.com/reactwg/react-18/discussions/41)), and a [new streaming server renderer](https://github.com/reactwg/react-18/discussions/37) with built-in support for `React.lazy`.

These features are possible thanks to a new opt-in mechanism we’re adding in React 18. It’s called “concurrent rendering” and it lets React prepare multiple versions of the UI at the same time. This change is mostly behind-the-scenes, but it unlocks new possibilities to improve both real and perceived performance of your app.

If you’ve been following our research into the future of React (we don’t expect you to!), you might have heard of something called “concurrent mode” or that it might break your app. In response to this feedback from the community, we’ve redesigned the upgrade strategy for gradual adoption. Instead of an all-or-nothing “mode”, concurrent rendering will only be enabled for updates triggered by one of the new features. In practice, this means **you will be able to adopt React 18 without rewrites and try the new features at your own pace.**

## A gradual adoption strategy[](#a-gradual-adoption-strategy "Link for A gradual adoption strategy ")

Since concurrency in React 18 is opt-in, there are no significant out-of-the-box breaking changes to component behavior. **You can upgrade to React 18 with minimal or no changes to your application code, with a level of effort comparable to a typical major React release**. Based on our experience converting several apps to React 18, we expect that many users will be able to upgrade within a single afternoon.

We successfully shipped concurrent features to tens of thousands of components at Facebook, and in our experience, we’ve found that most React components “just work” without additional changes. We’re committed to making sure this is a smooth upgrade for the entire community, so today we’re announcing the React 18 Working Group.

## Working with the community[](#working-with-the-community "Link for Working with the community ")

We’re trying something new for this release: We’ve invited a panel of experts, developers, library authors, and educators from across the React community to participate in our [React 18 Working Group](https://github.com/reactwg/react-18) to provide feedback, ask questions, and collaborate on the release. We couldn’t invite everyone we wanted to this initial, small group, but if this experiment works out, we hope there will be more in the future!

**The goal of the React 18 Working Group is to prepare the ecosystem for a smooth, gradual adoption of React 18 by existing applications and libraries.** The Working Group is hosted on [GitHub Discussions](https://github.com/reactwg/react-18/discussions) and is available for the public to read. Members of the working group can leave feedback, ask questions, and share ideas. The core team will also use the discussions repo to share our research findings. As the stable release gets closer, any important information will also be posted on this blog.

For more information on upgrading to React 18, or additional resources about the release, see the [React 18 announcement post](https://github.com/reactwg/react-18/discussions/4).

## Accessing the React 18 Working Group[](#accessing-the-react-18-working-group "Link for Accessing the React 18 Working Group ")

Everyone can read the discussions in the [React 18 Working Group repo](https://github.com/reactwg/react-18).

Because we expect an initial surge of interest in the Working Group, only invited members will be allowed to create or comment on threads. However, the threads are fully visible to the public, so everyone has access to the same information. We believe this is a good compromise between creating a productive environment for working group members, while maintaining transparency with the wider community.

As always, you can submit bug reports, questions, and general feedback to our [issue tracker](https://github.com/facebook/react/issues).

## How to try React 18 Alpha today[](#how-to-try-react-18-alpha-today "Link for How to try React 18 Alpha today ")

New alphas are [regularly published to npm using the `@alpha` tag](https://github.com/reactwg/react-18/discussions/9). These releases are built using the most recent commit to our main repo. When a feature or bugfix is merged, it will appear in an alpha the following weekday.

There may be significant behavioral or API changes between alpha releases. Please remember that **alpha releases are not recommended for user-facing, production applications**.

## Projected React 18 release timeline[](#projected-react-18-release-timeline "Link for Projected React 18 release timeline ")

We don’t have a specific release date scheduled, but we expect it will take several months of feedback and iteration before React 18 is ready for most production applications.

* Library Alpha: Available today
* Public Beta: At least several months
* Release Candidate (RC): At least several weeks after Beta
* General Availability: At least several weeks after RC

More details about our projected release timeline are [available in the Working Group](https://github.com/reactwg/react-18/discussions/9). We’ll post updates on this blog when we’re closer to a public release.

[PreviousReact Conf 2021 Recap](/blog/2021/12/17/react-conf-2021-recap)

[NextIntroducing Server Components](/blog/2020/12/21/data-fetching-with-react-server-components)

***

----
url: https://react.dev/learn/build-a-react-app-from-scratch
----

[Learn React](/learn)

[Installation](/learn/installation)

# Build a React app from Scratch[](#undefined "Link for this heading")

If your app has constraints not well-served by existing frameworks, you prefer to build your own framework, or you just want to learn the basics of a React app, you can build a React app from scratch.

##### Deep Dive#### Consider using a framework[](#consider-using-a-framework "Link for Consider using a framework ")

Starting from scratch is an easy way to get started using React, but a major tradeoff to be aware of is that going this route is often the same as building your own adhoc framework. As your requirements evolve, you may need to solve more framework-like problems that our recommended frameworks already have well developed and supported solutions for.

For example, if in the future your app needs support for server-side rendering (SSR), static site generation (SSG), and/or React Server Components (RSC), you will have to implement those on your own. Similarly, future React features that require integrating at the framework level will have to be implemented on your own if you want to use them.

Our recommended frameworks also help you build better performing apps. For example, reducing or eliminating waterfalls from network requests makes for a better user experience. This might not be a high priority when you are building a toy project, but if your app gains users you may want to improve its performance.

Going this route also makes it more difficult to get support, since the way you develop routing, data-fetching, and other features will be unique to your situation. You should only choose this option if you are comfortable tackling these problems on your own, or if you’re confident that you will never need these features.

For a list of recommended frameworks, check out [Creating a React App](/learn/creating-a-react-app).

## Step 1: Install a build tool[](#step-1-install-a-build-tool "Link for Step 1: Install a build tool ")

The first step is to install a build tool like `vite`, `parcel`, or `rsbuild`. These build tools provide features to package and run source code, provide a development server for local development and a build command to deploy your app to a production server.

### Vite[](#vite "Link for Vite ")

[Vite](https://vite.dev/) is a build tool that aims to provide a faster and leaner development experience for modern web projects.

Terminal

```
npm create vite@latest my-app -- --template react-ts
```

Vite is opinionated and comes with sensible defaults out of the box. Vite has a rich ecosystem of plugins to support fast refresh, JSX, Babel/SWC, and other common features. See Vite’s [React plugin](https://vite.dev/plugins/#vitejs-plugin-react) or [React SWC plugin](https://vite.dev/plugins/#vitejs-plugin-react-swc) and [React SSR example project](https://vite.dev/guide/ssr.html#example-projects) to get started.

Vite is already being used as a build tool in one of our [recommended frameworks](/learn/creating-a-react-app): [React Router](https://reactrouter.com/start/framework/installation).

### Parcel[](#parcel "Link for Parcel ")

[Parcel](https://parceljs.org/) combines a great out-of-the-box development experience with a scalable architecture that can take your project from just getting started to massive production applications.

Terminal

```
npm install --save-dev parcel
```

Parcel supports fast refresh, JSX, TypeScript, Flow, and styling out of the box. See [Parcel’s React recipe](https://parceljs.org/recipes/react/#getting-started) to get started.

### Rsbuild[](#rsbuild "Link for Rsbuild ")

[Rsbuild](https://rsbuild.dev/) is an Rspack-powered build tool that provides a seamless development experience for React applications. It comes with carefully tuned defaults and performance optimizations ready to use.

Terminal

```
npx create-rsbuild --template react
```

Rsbuild includes built-in support for React features like fast refresh, JSX, TypeScript, and styling. See [Rsbuild’s React guide](https://rsbuild.dev/guide/framework/react) to get started.

### Note

#### Metro for React Native[](#react-native "Link for Metro for React Native ")

If you’re starting from scratch with React Native you’ll need to use [Metro](https://metrobundler.dev/), the JavaScript bundler for React Native. Metro supports bundling for platforms like iOS and Android, but lacks many features when compared to the tools here. We recommend starting with Vite, Parcel, or Rsbuild unless your project requires React Native support.

## Step 2: Build Common Application Patterns[](#step-2-build-common-application-patterns "Link for Step 2: Build Common Application Patterns ")

The build tools listed above start off with a client-only, single-page app (SPA), but don’t include any further solutions for common functionality like routing, data fetching, or styling.

The React ecosystem includes many tools for these problems. We’ve listed a few that are widely used as a starting point, but feel free to choose other tools if those work better for you.

### Routing[](#routing "Link for Routing ")

Routing determines what content or pages to display when a user visits a particular URL. You need to set up a router to map URLs to different parts of your app. You’ll also need to handle nested routes, route parameters, and query parameters. Routers can be configured within your code, or defined based on your component folder and file structures.

Routers are a core part of modern applications, and are usually integrated with data fetching (including prefetching data for a whole page for faster loading), code splitting (to minimize client bundle sizes), and page rendering approaches (to decide how each page gets generated).

We suggest using:

* [React Router](https://reactrouter.com/start/data/custom)
* [Tanstack Router](https://tanstack.com/router/latest)

### Data Fetching[](#data-fetching "Link for Data Fetching ")

Fetching data from a server or other data source is a key part of most applications. Doing this properly requires handling loading states, error states, and caching the fetched data, which can be complex.

Purpose-built data fetching libraries do the hard work of fetching and caching the data for you, letting you focus on what data your app needs and how to display it. These libraries are typically used directly in your components, but can also be integrated into routing loaders for faster pre-fetching and better performance, and in server rendering as well.

Note that fetching data directly in components can lead to slower loading times due to network request waterfalls, so we recommend prefetching data in router loaders or on the server as much as possible! This allows a page’s data to be fetched all at once as the page is being displayed.

If you’re fetching data from most backends or REST-style APIs, we suggest using:

* [TanStack Query](https://tanstack.com/query/)
* [SWR](https://swr.vercel.app/)
* [RTK Query](https://redux-toolkit.js.org/rtk-query/overview)

If you’re fetching data from a GraphQL API, we suggest using:

* [Apollo](https://www.apollographql.com/docs/react)
* [Relay](https://relay.dev/)

### Code-splitting[](#code-splitting "Link for Code-splitting ")

Code-splitting is the process of breaking your app into smaller bundles that can be loaded on demand. An app’s code size increases with every new feature and additional dependency. Apps can become slow to load because all of the code for the entire app needs to be sent before it can be used. Caching, reducing features/dependencies, and moving some code to run on the server can help mitigate slow loading but are incomplete solutions that can sacrifice functionality if overused.

Similarly, if you rely on the apps using your framework to split the code, you might encounter situations where loading becomes slower than if no code splitting were happening at all. For example, [lazily loading](/reference/react/lazy) a chart delays sending the code needed to render the chart, splitting the chart code from the rest of the app. [Parcel supports code splitting with React.lazy](https://parceljs.org/recipes/react/#code-splitting). However, if the chart loads its data *after* it has been initially rendered you are now waiting twice. This is a waterfall: rather than fetching the data for the chart and sending the code to render it simultaneously, you must wait for each step to complete one after the other.

Splitting code by route, when integrated with bundling and data fetching, can reduce the initial load time of your app and the time it takes for the largest visible content of the app to render ([Largest Contentful Paint](https://web.dev/articles/lcp)).

For code-splitting instructions, see your build tool docs:

* [Vite build optimizations](https://vite.dev/guide/features.html#build-optimizations)
* [Parcel code splitting](https://parceljs.org/features/code-splitting/)
* [Rsbuild code splitting](https://rsbuild.dev/guide/optimization/code-splitting)

### Improving Application Performance[](#improving-application-performance "Link for Improving Application Performance ")

Since the build tool you select only supports single page apps (SPAs), you’ll need to implement other [rendering patterns](https://www.patterns.dev/vanilla/rendering-patterns) like server-side rendering (SSR), static site generation (SSG), and/or React Server Components (RSC). Even if you don’t need these features at first, in the future there may be some routes that would benefit SSR, SSG or RSC.

* **Single-page apps (SPA)** load a single HTML page and dynamically updates the page as the user interacts with the app. SPAs are easier to get started with, but they can have slower initial load times. SPAs are the default architecture for most build tools.

* **Streaming Server-side rendering (SSR)** renders a page on the server and sends the fully rendered page to the client. SSR can improve performance, but it can be more complex to set up and maintain than a single-page app. With the addition of streaming, SSR can be very complex to set up and maintain. See [Vite’s SSR guide](https://vite.dev/guide/ssr).

* **Static site generation (SSG)** generates static HTML files for your app at build time. SSG can improve performance, but it can be more complex to set up and maintain than server-side rendering. See [Vite’s SSG guide](https://vite.dev/guide/ssr.html#pre-rendering-ssg).

* **React Server Components (RSC)** lets you mix build-time, server-only, and interactive components in a single React tree. RSC can improve performance, but it currently requires deep expertise to set up and maintain. See [Parcel’s RSC examples](https://github.com/parcel-bundler/rsc-examples).

Your rendering strategies need to integrate with your router so apps built with your framework can choose the rendering strategy on a per-route level. This will enable different rendering strategies without having to rewrite your whole app. For example, the landing page for your app might benefit from being statically generated (SSG), while a page with a content feed might perform best with server-side rendering.

Using the right rendering strategy for the right routes can decrease the time it takes for the first byte of content to be loaded ([Time to First Byte](https://web.dev/articles/ttfb)), the first piece of content to render ([First Contentful Paint](https://web.dev/articles/fcp)), and the largest visible content of the app to render ([Largest Contentful Paint](https://web.dev/articles/lcp)).

### And more…[](#and-more "Link for And more… ")

These are just a few examples of the features a new app will need to consider when building from scratch. Many limitations you’ll hit can be difficult to solve as each problem is interconnected with the others and can require deep expertise in problem areas you may not be familiar with.

If you don’t want to solve these problems on your own, you can [get started with a framework](/learn/creating-a-react-app) that provides these features out of the box.

[PreviousCreating a React App](/learn/creating-a-react-app)

[NextAdd React to an Existing Project](/learn/add-react-to-an-existing-project)

***

----
url: https://react.dev/versions
----

[React Docs](/)

# React Versions[](#undefined "Link for this heading")

The React docs at [react.dev](https://react.dev) provide documentation for the latest version of React.

We aim to keep the docs updated within major versions, and do not publish versions for each minor or patch version. When a new major is released, we archive the docs for the previous version as `x.react.dev`. See our [versioning policy](/community/versioning-policy) for more info.

You can find an archive of previous major versions below.

## Latest version: 19.2[](#latest-version "Link for Latest version: 19.2 ")

* [react.dev](https://react.dev)

## Previous versions[](#previous-versions "Link for Previous versions ")

* [18.react.dev](https://18.react.dev)
* [17.react.dev](https://17.react.dev)
* [16.react.dev](https://16.react.dev)
* [15.react.dev](https://15.react.dev)

### Note

#### Legacy Docs[](#legacy-docs "Link for Legacy Docs ")

In 2023, we [launched our new docs](/blog/2023/03/16/introducing-react-dev) for React 18 as [react.dev](https://react.dev). The legacy React 18 docs are available at [legacy.reactjs.org](https://legacy.reactjs.org). Versions 17 and below are hosted on legacy sites.

For versions older than React 15, see [15.react.dev](https://15.react.dev).

## Changelog[](#changelog "Link for Changelog ")

### React 19[](#react-19 "Link for React 19 ")

**Blog Posts**

* [React v19](/blog/2024/12/05/react-19)
* [React 19 Upgrade Guide](/blog/2024/04/25/react-19-upgrade-guide)
* [React Compiler Beta Release](/blog/2024/10/21/react-compiler-beta-release)
* [React Compiler v1.0](/blog/2025/10/07/react-compiler-1)
* [React 19.2](/blog/2025/10/01/react-19-2)

**Talks**

* [React 19 Keynote](https://www.youtube.com/watch?v=lyEKhv8-3n0)
* [A Roadmap to React 19](https://www.youtube.com/watch?v=R0B2HsSM78s)
* [What’s new in React 19](https://www.youtube.com/watch?v=AJOGzVygGcY)
* [React for Two Computers](https://www.youtube.com/watch?v=ozI4V_29fj4)
* [React Compiler Deep Dive](https://www.youtube.com/watch?v=uA_PVyZP7AI)
* [React Compiler Case Studies](https://www.youtube.com/watch?v=lvhPq5chokM)
* [React 19 Deep Dive: Coordinating HTML](https://www.youtube.com/watch?v=IBBN-s77YSI)

**Releases**

* [v19.2.1 (December, 2025)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1922-dec-11-2025)
* [v19.2.1 (December, 2025)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1921-dec-3-2025)
* [v19.2.0 (October, 2025)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1920-october-1st-2025)
* [v19.1.3 (December, 2025)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1913-dec-11-2025)
* [v19.1.2 (December, 2025)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1912-dec-3-2025)
* [v19.1.1 (July, 2025)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1911-july-28-2025)
* [v19.1.0 (March, 2025)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1910-march-28-2025)
* [v19.0.2 (December, 2025)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1902-dec-11-2025)
* [v19.0.1 (December, 2025)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1901-dec-3-2025)
* [v19.0.0 (December, 2024)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1900-december-5-2024)

### React 18[](#react-18 "Link for React 18 ")

**Blog Posts**

* [React v18.0](/blog/2022/03/29/react-v18)
* [How to Upgrade to React 18](/blog/2022/03/08/react-18-upgrade-guide)
* [The Plan for React 18](/blog/2021/06/08/the-plan-for-react-18)

**Talks**

* [React 18 Keynote](https://www.youtube.com/watch?v=FZ0cG47msEk)
* [React 18 for app developers](https://www.youtube.com/watch?v=ytudH8je5ko)
* [Streaming Server Rendering with Suspense](https://www.youtube.com/watch?v=pj5N-Khihgc)
* [React without memo](https://www.youtube.com/watch?v=lGEMwh32soc)
* [React Docs Keynote](https://www.youtube.com/watch?v=mneDaMYOKP8)
* [React Developer Tooling](https://www.youtube.com/watch?v=oxDfrke8rZg)
* [The first React Working Group](https://www.youtube.com/watch?v=qn7gRClrC9U)
* [React 18 for External Store Libraries](https://www.youtube.com/watch?v=oPfSC5bQPR8)

**Releases**

* [v18.3.1 (April, 2024)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1831-april-26-2024)
* [v18.3.0 (April, 2024)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1830-april-25-2024)
* [v18.2.0 (June, 2022)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1820-june-14-2022)
* [v18.1.0 (April, 2022)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1810-april-26-2022)
* [v18.0.0 (March 2022)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1800-march-29-2022)

### React 17[](#react-17 "Link for React 17 ")

**Blog Posts**

* [React v17.0](https://legacy.reactjs.org/blog/2020/10/20/react-v17.html)
* [Introducing the New JSX Transform](https://legacy.reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html)
* [React v17.0 Release Candidate: No New Features](https://legacy.reactjs.org/blog/2020/08/10/react-v17-rc.html)

**Releases**

* [v17.0.2 (March 2021)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1702-march-22-2021)
* [v17.0.1 (October 2020)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1701-october-22-2020)
* [v17.0.0 (October 2020)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1700-october-20-2020)

### React 16[](#react-16 "Link for React 16 ")

**Blog Posts**

* [React v16.0](https://legacy.reactjs.org/blog/2017/09/26/react-v16.0.html)
* [DOM Attributes in React 16](https://legacy.reactjs.org/blog/2017/09/08/dom-attributes-in-react-16.html)
* [Error Handling in React 16](https://legacy.reactjs.org/blog/2017/07/26/error-handling-in-react-16.html)
* [React v16.2.0: Improved Support for Fragments](https://legacy.reactjs.org/blog/2017/11/28/react-v16.2.0-fragment-support.html)
* [React v16.4.0: Pointer Events](https://legacy.reactjs.org/blog/2018/05/23/react-v-16-4.html)
* [React v16.4.2: Server-side vulnerability fix](https://legacy.reactjs.org/blog/2018/08/01/react-v-16-4-2.html)
* [React v16.6.0: lazy, memo and contextType](https://legacy.reactjs.org/blog/2018/10/23/react-v-16-6.html)
* [React v16.7: No, This Is Not the One With Hooks](https://legacy.reactjs.org/blog/2018/12/19/react-v-16-7.html)
* [React v16.8: The One With Hooks](https://legacy.reactjs.org/blog/2019/02/06/react-v16.8.0.html)
* [React v16.9.0 and the Roadmap Update](https://legacy.reactjs.org/blog/2019/08/08/react-v16.9.0.html)
* [React v16.13.0](https://legacy.reactjs.org/blog/2020/02/26/react-v16.13.0.html)

**Releases**

* [v16.14.0 (October 2020)](https://github.com/facebook/react/blob/main/CHANGELOG.md#16140-october-14-2020)
* [v16.13.1 (March 2020)](https://github.com/facebook/react/blob/main/CHANGELOG.md#16131-march-19-2020)
* [v16.13.0 (February 2020)](https://github.com/facebook/react/blob/main/CHANGELOG.md#16130-february-26-2020)
* [v16.12.0 (November 2019)](https://github.com/facebook/react/blob/main/CHANGELOG.md#16120-november-14-2019)
* [v16.11.0 (October 2019)](https://github.com/facebook/react/blob/main/CHANGELOG.md#16110-october-22-2019)
* [v16.10.2 (October 2019)](https://github.com/facebook/react/blob/main/CHANGELOG.md#16102-october-3-2019)
* [v16.10.1 (September 2019)](https://github.com/facebook/react/blob/main/CHANGELOG.md#16101-september-28-2019)
* [v16.10.0 (September 2019)](https://github.com/facebook/react/blob/main/CHANGELOG.md#16100-september-27-2019)
* [v16.9.0 (August 2019)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1690-august-8-2019)
* [v16.8.6 (March 2019)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1686-march-27-2019)
* [v16.8.5 (March 2019)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1685-march-22-2019)
* [v16.8.4 (March 2019)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1684-march-5-2019)
* [v16.8.3 (February 2019)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1683-february-21-2019)
* [v16.8.2 (February 2019)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1682-february-14-2019)
* [v16.8.1 (February 2019)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1681-february-6-2019)
* [v16.8.0 (February 2019)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1680-february-6-2019)
* [v16.7.0 (December 2018)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1670-december-19-2018)
* [v16.6.3 (November 2018)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1663-november-12-2018)
* [v16.6.2 (November 2018)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1662-november-12-2018)
* [v16.6.1 (November 2018)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1661-november-6-2018)
* [v16.6.0 (October 2018)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1660-october-23-2018)
* [v16.5.2 (September 2018)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1652-september-18-2018)
* [v16.5.1 (September 2018)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1651-september-13-2018)
* [v16.5.0 (September 2018)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1650-september-5-2018)
* [v16.4.2 (August 2018)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1642-august-1-2018)
* [v16.4.1 (June 2018)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1641-june-13-2018)
* [v16.4.0 (May 2018)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1640-may-23-2018)
* [v16.3.3 (August 2018)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1633-august-1-2018)
* [v16.3.2 (April 2018)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1632-april-16-2018)
* [v16.3.1 (April 2018)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1631-april-3-2018)
* [v16.3.0 (March 2018)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1630-march-29-2018)
* [v16.2.1 (August 2018)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1621-august-1-2018)
* [v16.2.0 (November 2017)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1620-november-28-2017)
* [v16.1.2 (August 2018)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1612-august-1-2018)
* [v16.1.1 (November 2017)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1611-november-13-2017)
* [v16.1.0 (November 2017)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1610-november-9-2017)
* [v16.0.1 (August 2018)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1601-august-1-2018)
* [v16.0 (September 2017)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1600-september-26-2017)

### React 15[](#react-15 "Link for React 15 ")

**Blog Posts**

* [React v15.0](https://legacy.reactjs.org/blog/2016/04/07/react-v15.html)
* [React v15.0 Release Candidate 2](https://legacy.reactjs.org/blog/2016/03/16/react-v15-rc2.html)
* [React v15.0 Release Candidate](https://legacy.reactjs.org/blog/2016/03/07/react-v15-rc1.html)
* [New Versioning Scheme](https://legacy.reactjs.org/blog/2016/02/19/new-versioning-scheme.html)
* [Discontinuing IE 8 Support in React DOM](https://legacy.reactjs.org/blog/2016/01/12/discontinuing-ie8-support.html)
* [Introducing React’s Error Code System](https://legacy.reactjs.org/blog/2016/07/11/introducing-reacts-error-code-system.html)
* [React v15.0.1](https://legacy.reactjs.org/blog/2016/04/08/react-v15.0.1.html)
* [React v15.4.0](https://legacy.reactjs.org/blog/2016/11/16/react-v15.4.0.html)
* [React v15.5.0](https://legacy.reactjs.org/blog/2017/04/07/react-v15.5.0.html)
* [React v15.6.0](https://legacy.reactjs.org/blog/2017/06/13/react-v15.6.0.html)
* [React v15.6.2](https://legacy.reactjs.org/blog/2017/09/25/react-v15.6.2.html)

**Releases**

* [v15.7.0 (October 2017)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1570-october-14-2020)
* [v15.6.2 (September 2017)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1562-september-25-2017)
* [v15.6.1 (June 2017)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1561-june-14-2017)
* [v15.6.0 (June 2017)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1560-june-13-2017)
* [v15.5.4 (April 2017)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1554-april-11-2017)
* [v15.5.3 (April 2017)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1553-april-7-2017)
* [v15.5.2 (April 2017)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1552-april-7-2017)
* [v15.5.1 (April 2017)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1551-april-7-2017)
* [v15.5.0 (April 2017)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1550-april-7-2017)
* [v15.4.2 (January 2016)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1542-january-6-2017)
* [v15.4.1 (November 2016)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1541-november-22-2016)
* [v15.4.0 (November 2016)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1540-november-16-2016)
* [v15.3.2 (September 2016)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1532-september-19-2016)
* [v15.3.1 (August 2016)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1531-august-19-2016)
* [v15.3.0 (July 2016)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1530-july-29-2016)
* [v15.2.1 (July 2016)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1521-july-8-2016)
* [v15.2.0 (July 2016)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1520-july-1-2016)
* [v15.1.0 (May 2016)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1510-may-20-2016)
* [v15.0.2 (April 2016)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1502-april-29-2016)
* [v15.0.1 (April 2016)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1501-april-8-2016)
* [v15.0.0 (April 2016)](https://github.com/facebook/react/blob/main/CHANGELOG.md#1500-april-7-2016)

### React 0.14[](#react-14 "Link for React 0.14 ")

**Blog Posts**

* [React v0.14](https://legacy.reactjs.org/blog/2015/10/07/react-v0.14.html)
* [React v0.14 Release Candidate](https://legacy.reactjs.org/blog/2015/09/10/react-v0.14-rc1.html)
* [React v0.14 Beta 1](https://legacy.reactjs.org/blog/2015/07/03/react-v0.14-beta-1.html)
* [New React Developer Tools](https://legacy.reactjs.org/blog/2015/09/02/new-react-developer-tools.html)
* [New React Devtools Beta](https://legacy.reactjs.org/blog/2015/08/03/new-react-devtools-beta.html)
* [React v0.14.1](https://legacy.reactjs.org/blog/2015/10/28/react-v0.14.1.html)
* [React v0.14.2](https://legacy.reactjs.org/blog/2015/11/02/react-v0.14.2.html)
* [React v0.14.3](https://legacy.reactjs.org/blog/2015/11/18/react-v0.14.3.html)
* [React v0.14.4](https://legacy.reactjs.org/blog/2015/12/29/react-v0.14.4.html)
* [React v0.14.8](https://legacy.reactjs.org/blog/2016/03/29/react-v0.14.8.html)

**Releases**

* [v0.14.10 (October 2020)](https://github.com/facebook/react/blob/main/CHANGELOG.md#01410-october-14-2020)
* [v0.14.8 (March 2016)](https://github.com/facebook/react/blob/main/CHANGELOG.md#0148-march-29-2016)
* [v0.14.7 (January 2016)](https://github.com/facebook/react/blob/main/CHANGELOG.md#0147-january-28-2016)
* [v0.14.6 (January 2016)](https://github.com/facebook/react/blob/main/CHANGELOG.md#0146-january-6-2016)
* [v0.14.5 (December 2015)](https://github.com/facebook/react/blob/main/CHANGELOG.md#0145-december-29-2015)
* [v0.14.4 (December 2015)](https://github.com/facebook/react/blob/main/CHANGELOG.md#0144-december-29-2015)
* [v0.14.3 (November 2015)](https://github.com/facebook/react/blob/main/CHANGELOG.md#0143-november-18-2015)
* [v0.14.2 (November 2015)](https://github.com/facebook/react/blob/main/CHANGELOG.md#0142-november-2-2015)
* [v0.14.1 (October 2015)](https://github.com/facebook/react/blob/main/CHANGELOG.md#0141-october-28-2015)
* [v0.14.0 (October 2015)](https://github.com/facebook/react/blob/main/CHANGELOG.md#0140-october-7-2015)

### React 0.13[](#react-13 "Link for React 0.13 ")

**Blog Posts**

* [React Native v0.4](https://legacy.reactjs.org/blog/2015/04/17/react-native-v0.4.html)
* [React v0.13](https://legacy.reactjs.org/blog/2015/03/10/react-v0.13.html)
* [React v0.13 RC2](https://legacy.reactjs.org/blog/2015/03/03/react-v0.13-rc2.html)
* [React v0.13 RC](https://legacy.reactjs.org/blog/2015/02/24/react-v0.13-rc1.html)
* [React v0.13.0 Beta 1](https://legacy.reactjs.org/blog/2015/01/27/react-v0.13.0-beta-1.html)
* [Streamlining React Elements](https://legacy.reactjs.org/blog/2015/02/24/streamlining-react-elements.html)
* [Introducing Relay and GraphQL](https://legacy.reactjs.org/blog/2015/02/20/introducing-relay-and-graphql.html)
* [Introducing React Native](https://legacy.reactjs.org/blog/2015/03/26/introducing-react-native.html)
* [React v0.13.1](https://legacy.reactjs.org/blog/2015/03/16/react-v0.13.1.html)
* [React v0.13.2](https://legacy.reactjs.org/blog/2015/04/18/react-v0.13.2.html)
* [React v0.13.3](https://legacy.reactjs.org/blog/2015/05/08/react-v0.13.3.html)

**Releases**

* [v0.13.3 (May 2015)](https://github.com/facebook/react/blob/main/CHANGELOG.md#0133-may-8-2015)
* [v0.13.2 (April 2015)](https://github.com/facebook/react/blob/main/CHANGELOG.md#0132-april-18-2015)
* [v0.13.1 (March 2015)](https://github.com/facebook/react/blob/main/CHANGELOG.md#0131-march-16-2015)
* [v0.13.0 (March 2015)](https://github.com/facebook/react/blob/main/CHANGELOG.md#0130-march-10-2015)

### React 0.12[](#react-12 "Link for React 0.12 ")

**Blog Posts**

* [React v0.12](https://legacy.reactjs.org/blog/2014/10/28/react-v0.12.html)
* [React v0.12 RC](https://legacy.reactjs.org/blog/2014/10/16/react-v0.12-rc1.html)
* [Introducing React Elements](https://legacy.reactjs.org/blog/2014/10/14/introducing-react-elements.html)
* [React v0.12.2](https://legacy.reactjs.org/blog/2014/12/18/react-v0.12.2.html)

**Releases**

* [v0.12.2 (December 2014)](https://github.com/facebook/react/blob/main/CHANGELOG.md#0122-december-18-2014)
* [v0.12.1 (November 2014)](https://github.com/facebook/react/blob/main/CHANGELOG.md#0121-november-18-2014)
* [v0.12.0 (October 2014)](https://github.com/facebook/react/blob/main/CHANGELOG.md#0120-october-28-2014)

### React 0.11[](#react-11 "Link for React 0.11 ")

**Blog Posts**

* [React v0.11](https://legacy.reactjs.org/blog/2014/07/17/react-v0.11.html)
* [React v0.11 RC](https://legacy.reactjs.org/blog/2014/07/13/react-v0.11-rc1.html)
* [One Year of Open-Source React](https://legacy.reactjs.org/blog/2014/05/29/one-year-of-open-source-react.html)
* [The Road to 1.0](https://legacy.reactjs.org/blog/2014/03/28/the-road-to-1.0.html)
* [React v0.11.1](https://legacy.reactjs.org/blog/2014/07/25/react-v0.11.1.html)
* [React v0.11.2](https://legacy.reactjs.org/blog/2014/09/16/react-v0.11.2.html)
* [Introducing the JSX Specificaion](https://legacy.reactjs.org/blog/2014/09/03/introducing-the-jsx-specification.html)

**Releases**

* [v0.11.2 (September 2014)](https://github.com/facebook/react/blob/main/CHANGELOG.md#0112-september-16-2014)
* [v0.11.1 (July 2014)](https://github.com/facebook/react/blob/main/CHANGELOG.md#0111-july-24-2014)
* [v0.11.0 (July 2014)](https://github.com/facebook/react/blob/main/CHANGELOG.md#0110-july-17-2014)

### React 0.10 and below[](#react-10-and-below "Link for React 0.10 and below ")

**Blog Posts**

* [React v0.10](https://legacy.reactjs.org/blog/2014/03/21/react-v0.10.html)
* [React v0.10 RC](https://legacy.reactjs.org/blog/2014/03/19/react-v0.10-rc1.html)
* [React v0.9](https://legacy.reactjs.org/blog/2014/02/20/react-v0.9.html)
* [React v0.9 RC](https://legacy.reactjs.org/blog/2014/02/16/react-v0.9-rc1.html)
* [React Chrome Developer Tools](https://legacy.reactjs.org/blog/2014/01/02/react-chrome-developer-tools.html)
* [React v0.8](https://legacy.reactjs.org/blog/2013/12/19/react-v0.8.0.html)
* [React v0.5.2, v0.4.2](https://legacy.reactjs.org/blog/2013/12/18/react-v0.5.2-v0.4.2.html)
* [React v0.5.1](https://legacy.reactjs.org/blog/2013/10/29/react-v0-5-1.html)
* [React v0.5](https://legacy.reactjs.org/blog/2013/10/16/react-v0.5.0.html)
* [React v0.4.1](https://legacy.reactjs.org/blog/2013/07/26/react-v0-4-1.html)
* [React v0.4.0](https://legacy.reactjs.org/blog/2013/07/17/react-v0-4-0.html)
* [New in React v0.4: Prop Validation and Default Values](https://legacy.reactjs.org/blog/2013/07/11/react-v0-4-prop-validation-and-default-values.html)
* [New in React v0.4: Autobind by Default](https://legacy.reactjs.org/blog/2013/07/02/react-v0-4-autobind-by-default.html)
* [React v0.3.3](https://legacy.reactjs.org/blog/2013/07/02/react-v0-4-autobind-by-default.html)

**Releases**

* [v0.10.0 (March 2014)](https://github.com/facebook/react/blob/main/CHANGELOG.md#0100-march-21-2014)
* [v0.9.0 (February 2014)](https://github.com/facebook/react/blob/main/CHANGELOG.md#090-february-20-2014)
* [v0.8.0 (December 2013)](https://github.com/facebook/react/blob/main/CHANGELOG.md#080-december-19-2013)
* [v0.5.2 (December 2013)](https://github.com/facebook/react/blob/main/CHANGELOG.md#052-042-december-18-2013)
* [v0.5.1 (October 2013)](https://github.com/facebook/react/blob/main/CHANGELOG.md#051-october-29-2013)
* [v0.5.0 (October 2013)](https://github.com/facebook/react/blob/main/CHANGELOG.md#050-october-16-2013)
* [v0.4.1 (July 2013)](https://github.com/facebook/react/blob/main/CHANGELOG.md#041-july-26-2013)
* [v0.4.0 (July 2013)](https://github.com/facebook/react/blob/main/CHANGELOG.md#040-july-17-2013)
* [v0.3.3 (June 2013)](https://github.com/facebook/react/blob/main/CHANGELOG.md#033-june-20-2013)
* [v0.3.2 (May 2013)](https://github.com/facebook/react/blob/main/CHANGELOG.md#032-may-31-2013)
* [v0.3.1 (May 2013)](https://github.com/facebook/react/blob/main/CHANGELOG.md#031-may-30-2013)
* [v0.3.0 (May 2013)](https://github.com/facebook/react/blob/main/CHANGELOG.md#031-may-30-2013)

### Initial Commit[](#initial-commit "Link for Initial Commit ")

React was open-sourced on May 29, 2013. The initial commit is: [`75897c`: Initial public release](https://github.com/facebook/react/commit/75897c2dcd1dd3a6ca46284dd37e13d22b4b16b4)

See the first blog post: [Why did we build React?](https://legacy.reactjs.org/blog/2013/06/05/why-react.html)

React was open sourced at Facebook Seattle in 2013:

***

----
url: https://react.dev/learn/your-first-component
----

```
<article>

  <h1>My First Component</h1>

  <ol>

    <li>Components: UI Building Blocks</li>

    <li>Defining a Component</li>

    <li>Using a Component</li>

  </ol>

</article>
```

This markup represents this article `<article>`, its heading `<h1>`, and an (abbreviated) table of contents as an ordered list `<ol>`. Markup like this, combined with CSS for style, and JavaScript for interactivity, lies behind every sidebar, avatar, modal, dropdown—every piece of UI you see on the Web.

React lets you combine your markup, CSS, and JavaScript into custom “components”, **reusable UI elements for your app.** The table of contents code you saw above could be turned into a `<TableOfContents />` component you could render on every page. Under the hood, it still uses the same HTML tags like `<article>`, `<h1>`, etc.

Just like with HTML tags, you can compose, order and nest components to design whole pages. For example, the documentation page you’re reading is made out of React components:

```
<PageLayout>

  <NavigationHeader>

    <SearchBar />

    <Link to="/docs">Docs</Link>

  </NavigationHeader>

  <Sidebar />

  <PageContent>

    <TableOfContents />

    <DocumentationText />

  </PageContent>

</PageLayout>
```

As your project grows, you will notice that many of your designs can be composed by reusing components you already wrote, speeding up your development. Our table of contents above could be added to any screen with `<TableOfContents />`! You can even jumpstart your project with the thousands of components shared by the React open source community like [Chakra UI](https://chakra-ui.com/) and [Material UI.](https://material-ui.com/)

## Defining a component[](#defining-a-component "Link for Defining a component ")

Traditionally when creating web pages, web developers marked up their content and then added interaction by sprinkling on some JavaScript. This worked great when interaction was a nice-to-have on the web. Now it is expected for many sites and all apps. React puts interactivity first while still using the same technology: **a React component is a JavaScript function that you can *sprinkle with markup*.** Here’s what that looks like (you can edit the example below):

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
export default function Profile() {
  return (
    <img
      src="https://react.dev/images/docs/scientists/MK3eW3Am.jpg"
      alt="Katherine Johnson"
    />
  )
}
```

```
return <img src="https://react.dev/images/docs/scientists/MK3eW3As.jpg" alt="Katherine Johnson" />;
```

But if your markup isn’t all on the same line as the `return` keyword, you must wrap it in a pair of parentheses:

```
return (

  <div>

    <img src="https://react.dev/images/docs/scientists/MK3eW3As.jpg" alt="Katherine Johnson" />

  </div>

);
```

### Pitfall

Without parentheses, any code on the lines after `return` [will be ignored](https://stackoverflow.com/questions/2846283/what-are-the-rules-for-javascripts-automatic-semicolon-insertion-asi)!

## Using a component[](#using-a-component "Link for Using a component ")

Now that you’ve defined your `Profile` component, you can nest it inside other components. For example, you can export a `Gallery` component that uses multiple `Profile` components:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
function Profile() {
  return (
    <img
      src="https://react.dev/images/docs/scientists/MK3eW3As.jpg"
      alt="Katherine Johnson"
    />
  );
}

export default function Gallery() {
  return (
    <section>
      <h1>Amazing scientists</h1>
      <Profile />
      <Profile />
      <Profile />
    </section>
  );
}
```

### What the browser sees[](#what-the-browser-sees "Link for What the browser sees ")

Notice the difference in casing:

* `<section>` is lowercase, so React knows we refer to an HTML tag.
* `<Profile />` starts with a capital `P`, so React knows that we want to use our component called `Profile`.

And `Profile` contains even more HTML: `<img />`. In the end, this is what the browser sees:

```
<section>

  <h1>Amazing scientists</h1>

  <img src="https://react.dev/images/docs/scientists/MK3eW3As.jpg" alt="Katherine Johnson" />

  <img src="https://react.dev/images/docs/scientists/MK3eW3As.jpg" alt="Katherine Johnson" />

  <img src="https://react.dev/images/docs/scientists/MK3eW3As.jpg" alt="Katherine Johnson" />

</section>
```

### Nesting and organizing components[](#nesting-and-organizing-components "Link for Nesting and organizing components ")

Components are regular JavaScript functions, so you can keep multiple components in the same file. This is convenient when components are relatively small or tightly related to each other. If this file gets crowded, you can always move `Profile` to a separate file. You will learn how to do this shortly on the [page about imports.](/learn/importing-and-exporting-components)

Because the `Profile` components are rendered inside `Gallery`—even several times!—we can say that `Gallery` is a **parent component,** rendering each `Profile` as a “child”. This is part of the magic of React: you can define a component once, and then use it in as many places and as many times as you like.

### Pitfall

Components can render other components, but **you must never nest their definitions:**

```
export default function Gallery() {

  // 🔴 Never define a component inside another component!

  function Profile() {

    // ...

  }

  // ...

}
```

The snippet above is [very slow and causes bugs.](/learn/preserving-and-resetting-state#different-components-at-the-same-position-reset-state) Instead, define every component at the top level:

```
export default function Gallery() {

  // ...

}



// ✅ Declare components at the top level

function Profile() {

  // ...

}
```

When a child component needs some data from a parent, [pass it by props](/learn/passing-props-to-a-component) instead of nesting definitions.

##### Deep Dive#### Components all the way down[](#components-all-the-way-down "Link for Components all the way down ")

Your React application begins at a “root” component. Usually, it is created automatically when you start a new project. For example, if you use [CodeSandbox](https://codesandbox.io/) or if you use the framework [Next.js](https://nextjs.org/), the root component is defined in `pages/index.js`. In these examples, you’ve been exporting root components.

Most React apps use components all the way down. This means that you won’t only use components for reusable pieces like buttons, but also for larger pieces like sidebars, lists, and ultimately, complete pages! Components are a handy way to organize UI code and markup, even if some of them are only used once.

[React-based frameworks](/learn/creating-a-react-app) take this a step further. Instead of using an empty HTML file and letting React “take over” managing the page with JavaScript, they *also* generate the HTML automatically from your React components. This allows your app to show some content before the JavaScript code loads.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
function Profile() {
  return (
    <img
      src="https://react.dev/images/docs/scientists/lICfvbD.jpg"
      alt="Aklilu Lemma"
    />
  );
}
```

Try to fix it yourself before looking at the solution!

[PreviousDescribing the UI](/learn/describing-the-ui)

[NextImporting and Exporting Components](/learn/importing-and-exporting-components)

***

----
url: https://legacy.reactjs.org/blog/2014/03/21/react-v0.10.html
----

March 21, 2014 by [Paul O’Shannessy](https://twitter.com/zpao)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

Hot on the heels of the [release candidate earlier this week](/blog/2014/03/19/react-v0.10-rc1.html), we’re ready to call v0.10 done. The only major issue we discovered had to do with the `react-tools` package, which has been updated. We’ve copied over the changelog from the RC with some small clarifying changes.

The release is available for download from the CDN:

* **React**\
  Dev build with warnings: <https://fb.me/react-0.10.0.js>\
  Minified build for production: <https://fb.me/react-0.10.0.min.js>
* **React with Add-Ons**\
  Dev build with warnings: <https://fb.me/react-with-addons-0.10.0.js>\
  Minified build for production: <https://fb.me/react-with-addons-0.10.0.min.js>
* **In-Browser JSX transformer**\
  <https://fb.me/JSXTransformer-0.10.0.js>

We’ve also published version `0.10.0` of the `react` and `react-tools` packages on npm and the `react` package on bower.

Please try these builds out and [file an issue on GitHub](https://github.com/facebook/react/issues/new) if you see anything awry.

## [](#clone-on-mount)Clone On Mount

The main purpose of this release is to provide a smooth upgrade path as we evolve some of the implementation of core. In v0.9 we started warning in cases where you called methods on unmounted components. This is part of an effort to enforce the idea that the return value of a component (`React.DOM.div()`, `MyComponent()`) is in fact not a reference to the component instance React uses in the virtual DOM. The return value is instead a light-weight object that React knows how to use. Since the return value currently is a reference to the same object React uses internally, we need to make this transition in stages as many people have come to depend on this implementation detail.

In 0.10, we’re adding more warnings to catch a similar set of patterns. When a component is mounted we clone it and use that object for our internal representation. This allows us to capture calls you think you’re making to a mounted component. We’ll forward them on to the right object, but also warn you that this is breaking. See “Access to the Mounted Instance” on [this page](https://fb.me/react-warning-descriptors). Most of the time you can solve your pattern by using refs.

Storing a reference to your top level component is a pattern touched upon on that page, but another examples that demonstrates what we see a lot of:

```
// This is a common pattern. However instance here really refers to a
// "descriptor", not necessarily the mounted instance.
var instance = <MyComponent/>;
React.renderComponent(instance);
// ...
instance.setProps(...);

// The change here is very simple. The return value of renderComponent will be
// the mounted instance.
var instance = React.renderComponent(<MyComponent/>)
// ...
instance.setProps(...);
```

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2014-03-21-react-v0.10.md)

----
url: https://legacy.reactjs.org/blog/2016/04/07/react-v15.html
----

April 07, 2016 by [Dan Abramov](https://twitter.com/dan_abramov)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

We would like to thank the React community for reporting issues and regressions in the release candidates on our [issue tracker](https://github.com/facebook/react/issues/). Over the last few weeks we fixed those issues, and now, after two release candidates, we are excited to finally release the stable version of React 15.

As a reminder, [we’re switching to major versions](/blog/2016/02/19/new-versioning-scheme.html) to indicate that we have been using React in production for a long time. This 15.0 release follows our previous 0.14 version and we’ll continue to follow semver like we’ve been doing since 2013. It’s also worth noting that [we no longer actively support Internet Explorer 8](/blog/2016/01/12/discontinuing-ie8-support.html). We believe React will work in its current form there but we will not be prioritizing any efforts to fix new issues that only affect IE8.

React 15 brings significant improvements to how we interact with the DOM:

* We are now using `document.createElement` instead of setting `innerHTML` when mounting components. This allows us to get rid of the `data-reactid` attribute on every node and make the DOM lighter. Using `document.createElement` is also faster in modern browsers and fixes a number of edge cases related to SVG elements and running multiple copies of React on the same page.
* Historically our support for SVG has been incomplete, and many tags and attributes were missing. We heard you, and in React 15 we [added support for all the SVG attributes that are recognized by today’s browsers](https://github.com/facebook/react/pull/6243). If we missed any of the attributes you’d like to use, please [let us know](https://github.com/facebook/react/issues/1657). As a bonus, thanks to using `document.createElement`, we no longer need to maintain a list of SVG tags, so any SVG tags that were previously unsupported should work just fine in React 15.
* We received some amazing contributions from the community in this release, and we would like to highlight [this pull request](https://github.com/facebook/react/pull/5753) by [Michael Wiencek](https://github.com/mwiencek) in particular. Thanks to Michael’s work, React 15 no longer emits extra `<span>` nodes around the text, making the DOM output much cleaner. This was a longstanding annoyance for React users so it’s exciting to accept this as an outside contribution.

While this isn’t directly related to the release, we understand that in order to receive more community contributions like Michael’s, we need to communicate our goals and priorities more openly, and review pull requests more decisively. As a first step towards this, we started publishing [React core team weekly meeting notes](https://github.com/reactjs/core-notes) again. We also intend to introduce an RFC process inspired by [Ember RFCs](https://github.com/emberjs/rfcs) so external contributors can have more insight and influence in the future development of React. We will keep you updated about this on our blog.

We are also experimenting with a new changelog format in this post. Every change now links to the corresponding pull request and mentions the author. Let us know whether you find this useful!

## [](#upgrade-guide)Upgrade Guide

As usual with major releases, React 15 will remove support for some of the patterns deprecated nine months ago in React 0.14. We know changes can be painful (the Facebook codebase has over 20,000 React components, and that’s not even counting React Native), so we always try to make changes gradually in order to minimize the pain.

If your code is free of warnings when running under React 0.14, upgrading should be easy. The bulk of changes in this release are actually behind the scenes, impacting the way that React interacts with the DOM. The other substantial change is that React now supports the full range of SVG elements and attributes. Beyond that we have a large number of incremental improvements and additional warnings aimed to aid developers. We’ve also laid some groundwork in the core to bring you some new capabilities in future releases.

  Dev build with warnings: <https://fb.me/react-15.0.0.js>\
  Minified build for production: <https://fb.me/react-15.0.0.min.js>
* **React with Add-Ons**\
  Dev build with warnings: <https://fb.me/react-with-addons-15.0.0.js>\
  Minified build for production: <https://fb.me/react-with-addons-15.0.0.min.js>
* **React DOM** (include React in the page before React DOM)\
  Dev build with warnings: <https://fb.me/react-dom-15.0.0.js>\
  Minified build for production: <https://fb.me/react-dom-15.0.0.min.js>

## [](#changelog)Changelog

### [](#major-changes)Major changes

* #### [](#documentcreateelement-is-in-and-data-reactid-is-out)`document.createElement` is in and `data-reactid` is out

  There were a number of large changes to our interactions with the DOM. One of the most noticeable changes is that we no longer set the `data-reactid` attribute for each DOM node. While this will make it more difficult to know if a website is using React, the advantage is that the DOM is much more lightweight. This change was made possible by us switching to use `document.createElement` on initial render. Previously we would generate a large string of HTML and then set `node.innerHTML`. At the time, this was decided to be faster than using `document.createElement` for the majority of cases and browsers that we supported. Browsers have continued to improve and so overwhelmingly this is no longer true. By using `createElement` we can make other parts of React faster. The ids were used to map back from events to the original React component, meaning we had to do a bunch of work on every event, even though we cached this data heavily. As we’ve all experienced, caching and in particularly invalidating caches, can be error prone and we saw many hard to reproduce issues over the years as a result. Now we can build up a direct mapping at render time since we already have a handle on the node.

  **Note:** `data-reactid` is still present for server-rendered content, however it is much smaller than before and is simply an auto-incrementing counter.

  [@sophiebits](https://github.com/sophiebits) in [#5205](https://github.com/facebook/react/pull/5205)

* #### [](#no-more-extra-spans)No more extra `<span>`s

  Another big change with our DOM interaction is how we render text blocks. Previously you may have noticed that React rendered a lot of extra `<span>`s. For example, in our most basic example on the home page we render `<div>Hello {this.props.name}</div>`, resulting in markup that contained 2 `<span>`s. Now we’ll render plain text nodes interspersed with comment nodes that are used for demarcation. This gives us the same ability to update individual pieces of text, without creating extra nested nodes. Very few people have depended on the actual markup generated here so it’s likely you are not impacted. However if you were targeting these `<span>`s in your CSS, you will need to adjust accordingly. You can always render them explicitly in your components.

  [@mwiencek](https://github.com/mwiencek) in [#5753](https://github.com/facebook/react/pull/5753)

* #### [](#rendering-null-now-uses-comment-nodes)Rendering `null` now uses comment nodes

  We’ve also made use of these comment nodes to change what `null` renders to. Rendering to `null` was a feature we added in React 0.11 and was implemented by rendering `<noscript>` elements. By rendering to comment nodes now, there’s a chance some of your CSS will be targeting the wrong thing, specifically if you are making use of `:nth-child` selectors. React’s use of the `<noscript>` tag has always been considered an implementation detail of how React targets the DOM. We believe they are safe changes to make without going through a release with warnings detailing the subtle differences as they are details that should not be depended upon. Additionally, we have seen that these changes have improved React performance for many typical applications.

  [@sophiebits](https://github.com/sophiebits) in [#5451](https://github.com/facebook/react/pull/5451)

* #### [](#function-components-can-now-return-null-too)Function components can now return `null` too

  We added support for [defining stateless components as functions](/blog/2015/09/10/react-v0.14-rc1.html#stateless-function-components) in React 0.14. However, React 0.14 still allowed you to define a class component without extending `React.Component` or using `React.createClass()`, so [we couldn’t reliably tell if your component is a function or a class](https://github.com/facebook/react/issues/5355), and did not allow returning `null` from it. This issue is solved in React 15, and you can now return `null` from any component, whether it is a class or a function.

  [@jimfb](https://github.com/jimfb) in [#5884](https://github.com/facebook/react/pull/5884)

* #### [](#improved-svg-support)Improved SVG support

  All SVG tags are now fully supported. (Uncommon SVG tags are not present on the `React.DOM` element helper, but JSX and `React.createElement` work on all tag names.) All SVG attributes that are implemented by the browsers should be supported too. If you find any attributes that we have missed, please [let us know in this issue](https://github.com/facebook/react/issues/1657).

  [@zpao](https://github.com/zpao) in [#6243](https://github.com/facebook/react/pull/6243)

### [](#breaking-changes)Breaking changes

* #### [](#no-more-extra-spans-1)No more extra `<span>`s

  It’s worth calling out the DOM structure changes above again, in particular the change from `<span>`s. In the course of updating the Facebook codebase, we found a very small amount of code that was depending on the markup that React generated. Some of these cases were integration tests like WebDriver which were doing very specific XPath queries to target nodes. Others were simply tests using `ReactDOM.renderToStaticMarkup` and comparing markup. Again, there were a very small number of changes that had to be made, but we don’t want anybody to be blindsided. We encourage everybody to run their test suites when upgrading and consider alternative approaches when possible. One approach that will work for some cases is to explicitly use `<span>`s in your `render` method.

  [@mwiencek](https://github.com/mwiencek) in [#5753](https://github.com/facebook/react/pull/5753)

* #### [](#reactcloneelement-now-resolves-defaultprops)`React.cloneElement()` now resolves `defaultProps`

  We fixed a bug in `React.cloneElement()` that some components may rely on. If some of the `props` received by `cloneElement()` are `undefined`, it used to return an element with `undefined` values for those props. In React 15, we’re changing it to be consistent with `createElement()`. Now any `undefined` props passed to `cloneElement()` are resolved to the corresponding component’s `defaultProps`. Only one of our 20,000 React components was negatively affected by this so we feel comfortable releasing this change without keeping the old behavior for another release cycle.

  [@truongduy134](https://github.com/truongduy134) in [#5997](https://github.com/facebook/react/pull/5997)

* #### [](#reactperfgetlastmeasurements-is-opaque)`ReactPerf.getLastMeasurements()` is opaque

  This change won’t affect applications but may break some third-party tools. We are [revamping `ReactPerf` implementation](https://github.com/facebook/react/pull/6046) and plan to release it during the 15.x cycle. The internal performance measurement format is subject to change so, for the time being, we consider the return value of `ReactPerf.getLastMeasurements()` an opaque data structure that should not be relied upon.

  [@gaearon](https://github.com/gaearon) in [#6286](https://github.com/facebook/react/pull/6286)

* #### [](#removed-deprecations)Removed deprecations

  These deprecations were introduced nine months ago in v0.14 with a warning and are removed:

  * Deprecated APIs are removed from the `React` top-level export: `findDOMNode`, `render`, `renderToString`, `renderToStaticMarkup`, and `unmountComponentAtNode`. As a reminder, they are now available on `ReactDOM` and `ReactDOMServer`.\
    [@jimfb](https://github.com/jimfb) in [#5832](https://github.com/facebook/react/pull/5832)
  * Deprecated addons are removed: `batchedUpdates` and `cloneWithProps`.\
    [@jimfb](https://github.com/jimfb) in [#5859](https://github.com/facebook/react/pull/5859), [@zpao](https://github.com/zpao) in [#6016](https://github.com/facebook/react/pull/6016)
  * Deprecated component instance methods are removed: `setProps`, `replaceProps`, and `getDOMNode`.\
    [@jimfb](https://github.com/jimfb) in [#5570](https://github.com/facebook/react/pull/5570)
  * Deprecated CommonJS `react/addons` entry point is removed. As a reminder, you should use separate `react-addons-*` packages instead. This only applies if you use the CommonJS builds.\
    [@gaearon](https://github.com/gaearon) in [#6285](https://github.com/facebook/react/pull/6285)
  * Passing `children` to void elements like `<input>` was deprecated, and now throws an error.\
    [@jonhester](https://github.com/jonhester) in [#3372](https://github.com/facebook/react/pull/3372)
  * React-specific properties on DOM `refs` (e.g. `this.refs.div.props`) were deprecated, and are removed now.\
    [@jimfb](https://github.com/jimfb) in [#5495](https://github.com/facebook/react/pull/5495)

### [](#new-deprecations-introduced-with-a-warning)New deprecations, introduced with a warning

Each of these changes will continue to work as before with a new warning until the release of React 16 so you can upgrade your code gradually.

* `LinkedStateMixin` and `valueLink` are now deprecated due to very low popularity. If you need this, you can use a wrapper component that implements the same behavior: [react-linked-input](https://www.npmjs.com/package/react-linked-input).\
  [@jimfb](https://github.com/jimfb) in [#6127](https://github.com/facebook/react/pull/6127)
* Future versions of React will treat `<input value={null}>` as a request to clear the input. However, React 0.14 has been ignoring `value={null}`. React 15 warns you on a `null` input value and offers you to clarify your intention. To fix the warning, you may explicitly pass an empty string to clear a controlled input, or pass `undefined` to make the input uncontrolled.\
  [@antoaravinth](https://github.com/antoaravinth) in [#5048](https://github.com/facebook/react/pull/5048)
* `ReactPerf.printDOM()` was renamed to `ReactPerf.printOperations()`, and `ReactPerf.getMeasurementsSummaryMap()` was renamed to `ReactPerf.getWasted()`.\
  [@gaearon](https://github.com/gaearon) in [#6287](https://github.com/facebook/react/pull/6287)

### [](#new-helpful-warnings)New helpful warnings

* If you use a minified copy of the *development* build, React DOM kindly encourages you to use the faster production build instead.\
  [@sophiebits](https://github.com/sophiebits) in [#5083](https://github.com/facebook/react/pull/5083)
* React DOM: When specifying a unit-less CSS value as a string, a future version will not add `px` automatically. This version now warns in this case (ex: writing `style={{width: '300'}}`. Unitless *number* values like `width: 300` are unchanged.\
  [@pluma](https://github.com/pluma) in [#5140](https://github.com/facebook/react/pull/5140)
* Synthetic Events will now warn when setting and accessing properties (which will not get cleared appropriately), as well as warn on access after an event has been returned to the pool.\
  [@kentcdodds](https://github.com/kentcdodds) in [#5940](https://github.com/facebook/react/pull/5940) and [@koba04](https://github.com/koba04) in [#5947](https://github.com/facebook/react/pull/5947)
* Elements will now warn when attempting to read `ref` and `key` from the props.\
  [@prometheansacrifice](https://github.com/prometheansacrifice) in [#5744](https://github.com/facebook/react/pull/5744)
* React will now warn if you pass a different `props` object to `super()` in the constructor.\
  [@prometheansacrifice](https://github.com/prometheansacrifice) in [#5346](https://github.com/facebook/react/pull/5346)
* React will now warn if you call `setState()` inside `getChildContext()`.\
  [@raineroviir](https://github.com/raineroviir) in [#6121](https://github.com/facebook/react/pull/6121)
* React DOM now attempts to warn for mistyped event handlers on DOM elements, such as `onclick` which should be `onClick`.\
  [@ali](https://github.com/ali) in [#5361](https://github.com/facebook/react/pull/5361)
* React DOM now warns about `NaN` values in `style`.\
  [@jontewks](https://github.com/jontewks) in [#5811](https://github.com/facebook/react/pull/5811)
* React DOM now warns if you specify both `value` and `defaultValue` for an input.\
  [@mgmcdermott](https://github.com/mgmcdermott) in [#5823](https://github.com/facebook/react/pull/5823)
* React DOM now warns if an input switches between being controlled and uncontrolled.\
  [@TheBlasfem](https://github.com/TheBlasfem) in [#5864](https://github.com/facebook/react/pull/5864)
* React DOM now warns if you specify `onFocusIn` or `onFocusOut` handlers as they are unnecessary in React.\
  [@jontewks](https://github.com/jontewks) in [#6296](https://github.com/facebook/react/pull/6296)
* React now prints a descriptive error message when you pass an invalid callback as the last argument to `ReactDOM.render()`, `this.setState()`, or `this.forceUpdate()`.\
  [@conorhastings](https://github.com/conorhastings) in [#5193](https://github.com/facebook/react/pull/5193) and [@gaearon](https://github.com/gaearon) in [#6310](https://github.com/facebook/react/pull/6310)
* Add-Ons: `TestUtils.Simulate()` now prints a helpful message if you attempt to use it with shallow rendering.\
  [@conorhastings](https://github.com/conorhastings) in [#5358](https://github.com/facebook/react/pull/5358)
* PropTypes: `arrayOf()` and `objectOf()` provide better error messages for invalid arguments.\
  [@chicoxyzzy](https://github.com/chicoxyzzy) in [#5390](https://github.com/facebook/react/pull/5390)

### [](#notable-bug-fixes)Notable bug fixes

* Fixed multiple small memory leaks.\
  [@sophiebits](https://github.com/sophiebits) in [#4983](https://github.com/facebook/react/pull/4983) and [@victor-homyakov](https://github.com/victor-homyakov) in [#6309](https://github.com/facebook/react/pull/6309)
* Input events are handled more reliably in IE 10 and IE 11; spurious events no longer fire when using a placeholder.\
  [@jquense](https://github.com/jquense) in [#4051](https://github.com/facebook/react/pull/4051)
* The `componentWillReceiveProps()` lifecycle method is now consistently called when `context` changes.\
  [@milesj](https://github.com/milesj) in [#5787](https://github.com/facebook/react/pull/5787)
* `React.cloneElement()` doesn’t append slash to an existing `key` when used inside `React.Children.map()`.\
  [@ianobermiller](https://github.com/ianobermiller) in [#5892](https://github.com/facebook/react/pull/5892)
* React DOM now supports the `cite` and `profile` HTML attributes.\
  [@AprilArcus](https://github.com/AprilArcus) in [#6094](https://github.com/facebook/react/pull/6094) and [@saiichihashimoto](https://github.com/saiichihashimoto) in [#6032](https://github.com/facebook/react/pull/6032)
* React DOM now supports `cssFloat`, `gridRow` and `gridColumn` CSS properties.\
  [@stevenvachon](https://github.com/stevenvachon) in [#6133](https://github.com/facebook/react/pull/6133) and [@mnordick](https://github.com/mnordick) in [#4779](https://github.com/facebook/react/pull/4779)
* React DOM now correctly handles `borderImageOutset`, `borderImageWidth`, `borderImageSlice`, `floodOpacity`, `strokeDasharray`, and `strokeMiterlimit` as unitless CSS properties.\
  [@rofrischmann](https://github.com/rofrischmann) in [#6210](https://github.com/facebook/react/pull/6210) and [#6270](https://github.com/facebook/react/pull/6270)
* React DOM now supports the `onAnimationStart`, `onAnimationEnd`, `onAnimationIteration`, `onTransitionEnd`, and `onInvalid` events. Support for `onLoad` has been added to `object` elements.\
  [@tomduncalf](https://github.com/tomduncalf) in [#5187](https://github.com/facebook/react/pull/5187), [@milesj](https://github.com/milesj) in [#6005](https://github.com/facebook/react/pull/6005), and [@ara4n](https://github.com/ara4n) in [#5781](https://github.com/facebook/react/pull/5781)
* React DOM now defaults to using DOM attributes instead of properties, which fixes a few edge case bugs. Additionally the nullification of values (ex: `href={null}`) now results in the forceful removal, no longer trying to set to the default value used by browsers in the absence of a value.\
  [@syranide](https://github.com/syranide) in [#1510](https://github.com/facebook/react/pull/1510)
* React DOM does not mistakingly coerce `children` to strings for Web Components.\
  [@jimfb](https://github.com/jimfb) in [#5093](https://github.com/facebook/react/pull/5093)
* React DOM now correctly normalizes SVG `<use>` events.\
  [@edmellum](https://github.com/edmellum) in [#5720](https://github.com/facebook/react/pull/5720)
* React DOM does not throw if a `<select>` is unmounted while its `onChange` handler is executing.\
  [@sambev](https://github.com/sambev) in [#6028](https://github.com/facebook/react/pull/6028)
* React DOM does not throw in Windows 8 apps.\
  [@Andrew8xx8](https://github.com/Andrew8xx8) in [#6063](https://github.com/facebook/react/pull/6063)
* React DOM does not throw when asynchronously unmounting a child with a `ref`.\
  [@yiminghe](https://github.com/yiminghe) in [#6095](https://github.com/facebook/react/pull/6095)
* React DOM no longer forces synchronous layout because of scroll position tracking.\
  [@syranide](https://github.com/syranide) in [#2271](https://github.com/facebook/react/pull/2271)
* `Object.is` is used in a number of places to compare values, which leads to fewer false positives, especially involving `NaN`. In particular, this affects the `shallowCompare` add-on.\
  [@chicoxyzzy](https://github.com/chicoxyzzy) in [#6132](https://github.com/facebook/react/pull/6132)
* Add-Ons: ReactPerf no longer instruments adding or removing an event listener because they don’t really touch the DOM due to event delegation.\
  [@antoaravinth](https://github.com/antoaravinth) in [#5209](https://github.com/facebook/react/pull/5209)

### [](#improvements) Other improvements

* React now uses `loose-envify` instead of `envify` so it installs fewer transitive dependencies.\
  [@qerub](https://github.com/qerub) in [#6303](https://github.com/facebook/react/pull/6303)
* Shallow renderer now exposes `getMountedInstance()`.\
  [@glenjamin](https://github.com/glenjamin) in [#4918](https://github.com/facebook/react/pull/4918)
* Shallow renderer now returns the rendered output from `render()`.\
  [@simonewebdesign](https://github.com/simonewebdesign) in [#5411](https://github.com/facebook/react/pull/5411)
* React no longer depends on ES5 *shams* for `Object.create` and `Object.freeze` in older environments. It still, however, requires ES5 *shims* in those environments.\
  [@dgreensp](https://github.com/dgreensp) in [#4959](https://github.com/facebook/react/pull/4959)
* React DOM now allows `data-` attributes with names that start with numbers.\
  [@nLight](https://github.com/nLight) in [#5216](https://github.com/facebook/react/pull/5216)
* React DOM adds a new `suppressContentEditableWarning` prop for components like [Draft.js](https://facebook.github.io/draft-js/) that intentionally manage `contentEditable` children with React.\
  [@mxstbr](https://github.com/mxstbr) in [#6112](https://github.com/facebook/react/pull/6112)
* React improves the performance for `createClass()` on complex specs.\
  [@sophiebits](https://github.com/sophiebits) in [#5550](https://github.com/facebook/react/pull/5550)

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2016-04-07-react-v15.md)

----
url: https://legacy.reactjs.org/blog/2013/07/17/react-v0-4-0.html
----

July 17, 2013 by [Paul O’Shannessy](https://twitter.com/zpao)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

Over the past 2 months we’ve been taking feedback and working hard to make React even better. We fixed some bugs, made some under-the-hood improvements, and added several features that we think will improve the experience developing with React. Today we’re proud to announce the availability of React v0.4!

This release could not have happened without the support of our growing community. Since launch day, the community has contributed blog posts, questions to the [Google Group](https://groups.google.com/group/reactjs), and issues and pull requests on GitHub. We’ve had contributions ranging from documentation improvements to major changes to React’s rendering. We’ve seen people integrate React into the tools they’re using and the products they’re building, and we’re all very excited to see what our budding community builds next!

React v0.4 has some big changes. We’ve also restructured the documentation to better communicate how to use React. We’ve summarized the changes below and linked to documentation where we think it will be especially useful.

When you’re ready, [go download it](/docs/installation.html)!

### [](#react)React

* Switch from using `id` attribute to `data-reactid` to track DOM nodes. This allows you to integrate with other JS and CSS libraries more easily.
* Support for more DOM elements and attributes (e.g., `<canvas>`)
* Improved server-side rendering APIs. `React.renderComponentToString(<component>, callback)` allows you to use React on the server and generate markup which can be sent down to the browser.
* `prop` improvements: validation and default values. [Read our blog post for details…](/blog/2013/07/11/react-v0-4-prop-validation-and-default-values.html)
* Support for the `key` prop, which allows for finer control over reconciliation. [Read the docs for details…](/docs/multiple-components.html)
* Removed `React.autoBind`. [Read our blog post for details…](/blog/2013/07/02/react-v0-4-autobind-by-default.html)
* Improvements to forms. We’ve written wrappers around `<input>`, `<textarea>`, `<option>`, and `<select>` in order to standardize many inconsistencies in browser implementations. This includes support for `defaultValue`, and improved implementation of the `onChange` event, and circuit completion. [Read the docs for details…](/docs/forms.html)
* We’ve implemented an improved synthetic event system that conforms to the W3C spec.
* Updates to your component are batched now, which may result in a significantly faster re-render of components. `this.setState` now takes an optional callback as its second parameter. If you were using `onClick={this.setState.bind(this, state)}` previously, you’ll want to make sure you add a third parameter so that the event is not treated as the callback.

### [](#jsx)JSX

* Support for comment nodes `<div>{/* this is a comment and won't be rendered */}</div>`
* Children are now transformed directly into arguments instead of being wrapped in an array E.g. `<div><Component1/><Component2/></div>` is transformed into `React.DOM.div(null, Component1(null), Component2(null))`. Previously this would be transformed into `React.DOM.div(null, [Component1(null), Component2(null)])`. If you were using React without JSX previously, your code should still work.

### [](#react-tools)react-tools

* Fixed a number of bugs when transforming directories
* No longer re-write `require()`s to be relative unless specified

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2013-07-17-react-v0-4-0.md)

----
url: https://react.dev/reference/react-dom/server/resume
----

[API Reference](/reference/react)

[Server APIs](/reference/react-dom/server)

# resume[](#undefined "Link for this heading")

`resume` streams a pre-rendered React tree to a [Readable Web Stream.](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream)

```
const stream = await resume(reactNode, postponedState, options?)
```

* [Reference](#reference)
  * [`resume(node, postponedState, options?)`](#resume)

* [Usage](#usage)

  * [Resuming a prerender](#resuming-a-prerender)
  * [Further reading](#further-reading)

### Note

This API depends on [Web Streams.](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API) For Node.js, use [`resumeToNodeStream`](/reference/react-dom/server/renderToPipeableStream) instead.

***

## Reference[](#reference "Link for Reference ")

### `resume(node, postponedState, options?)`[](#resume "Link for this heading")

Call `resume` to resume rendering a pre-rendered React tree as HTML into a [Readable Web Stream.](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream)

```
import { resume } from 'react-dom/server';

import {getPostponedState} from './storage';



async function handler(request, writable) {

  const postponed = await getPostponedState(request);

  const resumeStream = await resume(<App />, postponed);

  return resumeStream.pipeTo(writable)

}
```


#### Returns[](#returns "Link for Returns ")

`resume` returns a Promise:

* If `resume` successfully produced a [shell](/reference/react-dom/server/renderToReadableStream#specifying-what-goes-into-the-shell), that Promise will resolve to a [Readable Web Stream.](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream) that can be piped to a [Writable Web Stream.](https://developer.mozilla.org/en-US/docs/Web/API/WritableStream).
* If an error happens in the shell, the Promise will reject with that error.

The returned stream has an additional property:

* `allReady`: A Promise that resolves when all rendering is complete. You can `await stream.allReady` before returning a response [for crawlers and static generation.](/reference/react-dom/server/renderToReadableStream#waiting-for-all-content-to-load-for-crawlers-and-static-generation) If you do that, you won’t get any progressive loading. The stream will contain the final HTML.

#### Caveats[](#caveats "Link for Caveats ")

* `resume` does not accept options for `bootstrapScripts`, `bootstrapScriptContent`, or `bootstrapModules`. Instead, you need to pass these options to the `prerender` call that generates the `postponedState`. You can also inject bootstrap content into the writable stream manually.
* `resume` does not accept `identifierPrefix` since the prefix needs to be the same in both `prerender` and `resume`.
* Since `nonce` cannot be provided to prerender, you should only provide `nonce` to `resume` if you’re not providing scripts to prerender.
* `resume` re-renders from the root until it finds a component that was not fully pre-rendered. Only fully prerendered Components (the Component and its children finished prerendering) are skipped entirely.

## Usage[](#usage "Link for Usage ")

### Resuming a prerender[](#resuming-a-prerender "Link for Resuming a prerender ")

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import {
  flushReadableStreamToFrame,
  getUser,
  Postponed,
  sleep,
} from "./demo-helpers";
import { StrictMode, Suspense, use, useEffect } from "react";
import { prerender } from "react-dom/static";
import { resume } from "react-dom/server";
import { hydrateRoot } from "react-dom/client";

function Header() {
  return <header>Me and my descendants can be prerendered</header>;
}

const { promise: cookies, resolve: resolveCookies } = Promise.withResolvers();

function Main() {
  const { sessionID } = use(cookies);
  const user = getUser(sessionID);

  useEffect(() => {
    console.log("reached interactivity!");
  }, []);

  return (
    <main>
      Hello, {user.name}!
      <button onClick={() => console.log("hydrated!")}>
        Clicking me requires hydration.
      </button>
    </main>
  );
}

function Shell({ children }) {
  // In a real app, this is where you would put your html and body.
  // We're just using tags here we can include in an existing body for demonstration purposes
  return (
    <html>
      <body>{children}</body>
    </html>
  );
}

function App() {
  return (
    <Shell>
      <Suspense fallback="loading header">
        <Header />
      </Suspense>
      <Suspense fallback="loading main">
        <Main />
      </Suspense>
    </Shell>
  );
}

async function main(frame) {
  // Layer 1
  const controller = new AbortController();
  const prerenderedApp = prerender(<App />, {
    signal: controller.signal,
    onError(error) {
      if (error instanceof Postponed) {
      } else {
        console.error(error);
      }
    },
  });
  // We're immediately aborting in a macrotask.
  // Any data fetching that's not available synchronously, or in a microtask, will not have finished.
  setTimeout(() => {
    controller.abort(new Postponed());
  });

  const { prelude, postponed } = await prerenderedApp;
  await flushReadableStreamToFrame(prelude, frame);

  // Layer 2
  // Just waiting here for demonstration purposes.
  // In a real app, the prelude and postponed state would've been serialized in Layer 1 and Layer would deserialize them.
  // The prelude content could be flushed immediated as plain HTML while
  // React is continuing to render from where the prerender left off.
  await sleep(2000);

  // You would get the cookies from the incoming HTTP request
  resolveCookies({ sessionID: "abc" });

  const stream = await resume(<App />, postponed);

  await flushReadableStreamToFrame(stream, frame);

  // Layer 3
  // Just waiting here for demonstration purposes.
  await sleep(2000);

  hydrateRoot(frame.contentWindow.document, <App />);
}

main(document.getElementById("container"));
```

### Further reading[](#further-reading "Link for Further reading ")

Resuming behaves like `renderToReadableStream`. For more examples, check out the [usage section of `renderToReadableStream`](/reference/react-dom/server/renderToReadableStream#usage). The [usage section of `prerender`](/reference/react-dom/static/prerender#usage) includes examples of how to use `prerender` specifically.

[PreviousrenderToString](/reference/react-dom/server/renderToString)

[NextresumeToPipeableStream](/reference/react-dom/server/resumeToPipeableStream)

***

----
url: https://react.dev/reference/rsc/use-server
----

[API Reference](/reference/react)

[Directives](/reference/rsc/directives)

# 'use server'[](#undefined "Link for this heading")

### React Server Components

`'use server'` is for use with [using React Server Components](/reference/rsc/server-components).

`'use server'` marks server-side functions that can be called from client-side code.

* [Reference](#reference)

  * [`'use server'`](#use-server)
  * [Security considerations](#security)
  * [Serializable arguments and return values](#serializable-parameters-and-return-values)

* [Usage](#usage)

  * [Server Functions in forms](#server-functions-in-forms)
  * [Calling a Server Function outside of `<form>`](#calling-a-server-function-outside-of-form)

***

## Reference[](#reference "Link for Reference ")

### `'use server'`[](#use-server "Link for this heading")

Add `'use server'` at the top of an async function body to mark the function as callable by the client. We call these functions [*Server Functions*](/reference/rsc/server-functions).

```
async function addToCart(data) {

  'use server';

  // ...

}
```

When calling a Server Function on the client, it will make a network request to the server that includes a serialized copy of any arguments passed. If the Server Function returns a value, that value will be serialized and returned to the client.

Instead of individually marking functions with `'use server'`, you can add the directive to the top of a file to mark all exports within that file as Server Functions that can be used anywhere, including imported in client code.

#### Caveats[](#caveats "Link for Caveats ")

* `'use server'` must be at the very beginning of their function or module; above any other code including imports (comments above directives are OK). They must be written with single or double quotes, not backticks.
* `'use server'` can only be used in server-side files. The resulting Server Functions can be passed to Client Components through props. See supported [types for serialization](#serializable-parameters-and-return-values).
* To import a Server Functions from [client code](/reference/rsc/use-client), the directive must be used on a module level.
* Because the underlying network calls are always asynchronous, `'use server'` can only be used on async functions.
* Always treat arguments to Server Functions as untrusted input and authorize any mutations. See [security considerations](#security).
* Server Functions should be called in a [Transition](/reference/react/useTransition). Server Functions passed to [`<form action>`](/reference/react-dom/components/form#props) or [`formAction`](/reference/react-dom/components/input#props) will automatically be called in a transition.
* Server Functions are designed for mutations that update server-side state; they are not recommended for data fetching. Accordingly, frameworks implementing Server Functions typically process one action at a time and do not have a way to cache the return value.

### Security considerations[](#security "Link for Security considerations ")

Arguments to Server Functions are fully client-controlled. For security, always treat them as untrusted input, and make sure to validate and escape arguments as appropriate.

In any Server Function, make sure to validate that the logged-in user is allowed to perform that action.

### Under Construction

To prevent sending sensitive data from a Server Function, there are experimental taint APIs to prevent unique values and objects from being passed to client code.

See [experimental\_taintUniqueValue](/reference/react/experimental_taintUniqueValue) and [experimental\_taintObjectReference](/reference/react/experimental_taintObjectReference).

### Serializable arguments and return values[](#serializable-parameters-and-return-values "Link for Serializable arguments and return values ")

Since client code calls the Server Function over the network, any arguments passed will need to be serializable.

Here are supported types for Server Function arguments:

* Functions that are Server Functions

* [Promises](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)

Notably, these are not supported:

* React elements, or [JSX](/learn/writing-markup-with-jsx)
* Functions, including component functions or any other function that is not a Server Function
* [Classes](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Classes_in_JavaScript)
* Objects that are instances of any class (other than the built-ins mentioned) or objects with [a null prototype](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object#null-prototype_objects)
* Symbols not registered globally, ex. `Symbol('my new symbol')`
* Events from event handlers

Supported serializable return values are the same as [serializable props](/reference/rsc/use-client#serializable-types) for a boundary Client Component.

## Usage[](#usage "Link for Usage ")

### Server Functions in forms[](#server-functions-in-forms "Link for Server Functions in forms ")

The most common use case of Server Functions will be calling functions that mutate data. On the browser, the [HTML form element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form) is the traditional approach for a user to submit a mutation. With React Server Components, React introduces first-class support for Server Functions as Actions in [forms](/reference/react-dom/components/form).

Here is a form that allows a user to request a username.

```
// App.js



async function requestUsername(formData) {

  'use server';

  const username = formData.get('username');

  // ...

}



export default function App() {

  return (

    <form action={requestUsername}>

      <input type="text" name="username" />

      <button type="submit">Request</button>

    </form>

  );

}
```

In this example `requestUsername` is a Server Function passed to a `<form>`. When a user submits this form, there is a network request to the server function `requestUsername`. When calling a Server Function in a form, React will supply the form’s [FormData](https://developer.mozilla.org/en-US/docs/Web/API/FormData) as the first argument to the Server Function.

By passing a Server Function to the form `action`, React can [progressively enhance](https://developer.mozilla.org/en-US/docs/Glossary/Progressive_Enhancement) the form. This means that forms can be submitted before the JavaScript bundle is loaded.

#### Handling return values in forms[](#handling-return-values "Link for Handling return values in forms ")

In the username request form, there might be the chance that a username is not available. `requestUsername` should tell us if it fails or not.

To update the UI based on the result of a Server Function while supporting progressive enhancement, use [`useActionState`](/reference/react/useActionState).

```
// requestUsername.js

'use server';



export default async function requestUsername(formData) {

  const username = formData.get('username');

  if (canRequest(username)) {

    // ...

    return 'successful';

  }

  return 'failed';

}
```

```
// UsernameForm.js

'use client';



import { useActionState } from 'react';

import requestUsername from './requestUsername';



function UsernameForm() {

  const [state, action] = useActionState(requestUsername, null, 'n/a');



  return (

    <>

      <form action={action}>

        <input type="text" name="username" />

        <button type="submit">Request</button>

      </form>

      <p>Last submission request returned: {state}</p>

    </>

  );

}
```

Note that like most Hooks, `useActionState` can only be called in [client code](/reference/rsc/use-client).

### Calling a Server Function outside of `<form>`[](#calling-a-server-function-outside-of-form "Link for this heading")

Server Functions are exposed server endpoints and can be called anywhere in client code.

When using a Server Function outside a [form](/reference/react-dom/components/form), call the Server Function in a [Transition](/reference/react/useTransition), which allows you to display a loading indicator, show [optimistic state updates](/reference/react/useOptimistic), and handle unexpected errors. Forms will automatically wrap Server Functions in transitions.

```
import incrementLike from './actions';

import { useState, useTransition } from 'react';



function LikeButton() {

  const [isPending, startTransition] = useTransition();

  const [likeCount, setLikeCount] = useState(0);



  const onClick = () => {

    startTransition(async () => {

      const currentCount = await incrementLike();

      setLikeCount(currentCount);

    });

  };



  return (

    <>

      <p>Total Likes: {likeCount}</p>

      <button onClick={onClick} disabled={isPending}>Like</button>;

    </>

  );

}
```

```
// actions.js

'use server';



let likeCount = 0;

export default async function incrementLike() {

  likeCount++;

  return likeCount;

}
```

To read a Server Function return value, you’ll need to `await` the promise returned.

[Previous'use client'](/reference/rsc/use-client)

***

----
url: https://18.react.dev/reference/react-dom
----

[API Reference](/reference/react)

# React DOM APIs[](#undefined "Link for this heading")

The `react-dom` package contains methods that are only supported for the web applications (which run in the browser DOM environment). They are not supported for React Native.

***

## APIs[](#apis "Link for APIs ")

These APIs can be imported from your components. They are rarely used:

* [`createPortal`](/reference/react-dom/createPortal) lets you render child components in a different part of the DOM tree.
* [`flushSync`](/reference/react-dom/flushSync) lets you force React to flush a state update and update the DOM synchronously.

## Resource Preloading APIs[](#resource-preloading-apis "Link for Resource Preloading APIs ")

These APIs can be used to make apps faster by pre-loading resources such as scripts, stylesheets, and fonts as soon as you know you need them, for example before navigating to another page where the resources will be used.

[React-based frameworks](/learn/start-a-new-react-project) frequently handle resource loading for you, so you might not have to call these APIs yourself. Consult your framework’s documentation for details.

* [`prefetchDNS`](/reference/react-dom/prefetchDNS) lets you prefetch the IP address of a DNS domain name that you expect to connect to.
* [`preconnect`](/reference/react-dom/preconnect) lets you connect to a server you expect to request resources from, even if you don’t know what resources you’ll need yet.
* [`preload`](/reference/react-dom/preload) lets you fetch a stylesheet, font, image, or external script that you expect to use.
* [`preloadModule`](/reference/react-dom/preloadModule) lets you fetch an ESM module that you expect to use.
* [`preinit`](/reference/react-dom/preinit) lets you fetch and evaluate an external script or fetch and insert a stylesheet.
* [`preinitModule`](/reference/react-dom/preinitModule) lets you fetch and evaluate an ESM module.

***

## Entry points[](#entry-points "Link for Entry points ")

The `react-dom` package provides two additional entry points:

* [`react-dom/client`](/reference/react-dom/client) contains APIs to render React components on the client (in the browser).
* [`react-dom/server`](/reference/react-dom/server) contains APIs to render React components on the server.

***

## Deprecated APIs[](#deprecated-apis "Link for Deprecated APIs ")

### Deprecated

These APIs will be removed in a future major version of React.

* [`findDOMNode`](/reference/react-dom/findDOMNode) finds the closest DOM node corresponding to a class component instance.
* [`hydrate`](/reference/react-dom/hydrate) mounts a tree into the DOM created from server HTML. Deprecated in favor of [`hydrateRoot`](/reference/react-dom/client/hydrateRoot).
* [`render`](/reference/react-dom/render) mounts a tree into the DOM. Deprecated in favor of [`createRoot`](/reference/react-dom/client/createRoot).
* [`unmountComponentAtNode`](/reference/react-dom/unmountComponentAtNode) unmounts a tree from the DOM. Deprecated in favor of [`root.unmount()`](/reference/react-dom/client/createRoot#root-unmount).

[Previous\<title>](/reference/react-dom/components/title)

[NextcreatePortal](/reference/react-dom/createPortal)

***

----
url: https://legacy.reactjs.org/docs/concurrent-mode-reference.html
----

> Caution:
>
> This page is **somewhat outdated** and only exists for historical purposes.
>
> React 18 was released with support for concurrency. However, **there is no “mode” anymore,** and the new behavior is fully opt-in and only enabled [when you use the new features](https://reactjs.org/blog/2022/03/29/react-v18.html#gradually-adopting-concurrent-features).
>
> **For up-to-date high-level information, refer to:**
>
> * [React 18 Announcement](https://reactjs.org/blog/2022/03/29/react-v18.html)
> * [Upgrading to React 18](https://reactjs.org/blog/2022/03/08/react-18-upgrade-guide.html)
> * [React Conf 2021 Videos](https://reactjs.org/blog/2021/12/17/react-conf-2021-recap.html)
>
> **For details about concurrent APIs in React 18, refer to:**
>
> * [`React.Suspense`](https://reactjs.org/docs/react-api.html#reactsuspense) reference
> * [`React.startTransition`](https://reactjs.org/docs/react-api.html#starttransition) reference
> * [`React.useTransition`](https://reactjs.org/docs/hooks-reference.html#usetransition) reference
> * [`React.useDeferredValue`](https://reactjs.org/docs/hooks-reference.html#usedeferredvalue) reference
>
> The rest of this page may include content that’s stale, broken, or incorrect.

This page is an API reference for the React [Concurrent Mode](/docs/concurrent-mode-intro.html). If you’re looking for a guided introduction instead, check out [Concurrent UI Patterns](/docs/concurrent-mode-patterns.html).

**Note: This is a Community Preview and not the final stable version. There will likely be future changes to these APIs. Use at your own risk!**

* [Enabling Concurrent Mode](#concurrent-mode)

  * [`createRoot`](#createroot)

* [Suspense](#suspense)

  * [`Suspense`](#suspensecomponent)
  * [`SuspenseList`](#suspenselist)
  * [`useTransition`](#usetransition)
  * [`useDeferredValue`](#usedeferredvalue)

## [](#concurrent-mode)Enabling Concurrent Mode

> Caution:
>
> This explanation is outdated. The strategy of a separate “mode” was abandoned in React 18. Instead, concurrent rendering is only enabled when you use concurrent features.

### [](#createroot)`createRoot`

```
ReactDOM.createRoot(rootNode).render(<App />);
```

Replaces `ReactDOM.render(<App />, rootNode)` and enables Concurrent Mode.

For more information on Concurrent Mode, check out the [Concurrent Mode documentation.](/docs/concurrent-mode-intro.html)

## [](#suspense)Suspense API

### [](#suspensecomponent)`Suspense`

```
<Suspense fallback={<h1>Loading...</h1>}>
  <ProfilePhoto />
  <ProfileDetails />
</Suspense>
```

`Suspense` lets your components “wait” for something before they can render, showing a fallback while waiting.

In this example, `ProfileDetails` is waiting for an asynchronous API call to fetch some data. While we wait for `ProfileDetails` and `ProfilePhoto`, we will show the `Loading...` fallback instead. It is important to note that until all children inside `<Suspense>` have loaded, we will continue to show the fallback.

`Suspense` takes two props:

* **fallback** takes a loading indicator. The fallback is shown until all of the children of the `Suspense` component have finished rendering.
* **unstable\_avoidThisFallback** takes a boolean. It tells React whether to “skip” revealing this boundary during the initial load. This API will likely be removed in a future release.

### [](#suspenselist)`<SuspenseList>`

```
<SuspenseList revealOrder="forwards">
  <Suspense fallback={'Loading...'}>
    <ProfilePicture id={1} />
  </Suspense>
  <Suspense fallback={'Loading...'}>
    <ProfilePicture id={2} />
  </Suspense>
  <Suspense fallback={'Loading...'}>
    <ProfilePicture id={3} />
  </Suspense>
  ...
</SuspenseList>
```

`SuspenseList` helps coordinate many components that can suspend by orchestrating the order in which these components are revealed to the user.

When multiple components need to fetch data, this data may arrive in an unpredictable order. However, if you wrap these items in a `SuspenseList`, React will not show an item in the list until previous items have been displayed (this behavior is adjustable).

`SuspenseList` takes two props:

* **revealOrder (forwards, backwards, together)** defines the order in which the `SuspenseList` children should be revealed.

  * `together` reveals *all* of them when they’re ready instead of one by one.

* **tail (collapsed, hidden)** dictates how unloaded items in a `SuspenseList` is shown.

  * By default, `SuspenseList` will show all fallbacks in the list.
  * `collapsed` shows only the next fallback in the list.
  * `hidden` doesn’t show any unloaded items.

Note that `SuspenseList` only operates on the closest `Suspense` and `SuspenseList` components below it. It does not search for boundaries deeper than one level. However, it is possible to nest multiple `SuspenseList` components in each other to build grids.

### [](#usetransition)`useTransition`

```
const [isPending, startTransition] = useTransition();
```

`useTransition` allows components to avoid undesirable loading states by waiting for content to load before **transitioning to the next screen**. It also allows components to defer slower, data fetching updates until subsequent renders so that more crucial updates can be rendered immediately.

* `isPending` is a boolean. It’s React’s way of informing us whether we’re waiting for the transition to finish. The `useTransition` hook returns two values in an array.
* `startTransition` is a function that takes a callback. We can use it to tell React which state we want to defer.

**If some state update causes a component to suspend, that state update should be wrapped in a transition.**

```
function App() {
  const [resource, setResource] = useState(initialResource);
  const [isPending, startTransition] = useTransition();
  return (
    <>
      <button
        disabled={isPending}
        onClick={() => {
          startTransition(() => {
            const nextUserId = getNextId(resource.userId);
            setResource(fetchProfileData(nextUserId));
          });
        }}
      >
        Next
      </button>
      {isPending ? " Loading..." : null}
      <Suspense fallback={<Spinner />}>
        <ProfilePage resource={resource} />
      </Suspense>
    </>
  );
}
```

In this code, we’ve wrapped our data fetching with `startTransition`. This allows us to start fetching the profile data right away, while deferring the render of the next profile page and its associated `Spinner`.

The `isPending` boolean lets React know that our component is transitioning, so we are able to let the user know this by showing some loading text on the previous profile page.

**For an in-depth look at transitions, you can read [Concurrent UI Patterns](/docs/concurrent-mode-patterns.html#transitions).**

### [](#usedeferredvalue)`useDeferredValue`

```
const deferredValue = useDeferredValue(value);
```

Returns a deferred version of the value that may “lag behind” it.

This is commonly used to keep the interface responsive when you have something that renders immediately based on user input and something that needs to wait for a data fetch.

A good example of this is a text input.

```
function App() {
  const [text, setText] = useState("hello");
  const deferredText = useDeferredValue(text); 

  return (
    <div className="App">
      {/* Keep passing the current text to the input */}
      <input value={text} onChange={handleChange} />
      ...
      {/* But the list is allowed to "lag behind" when necessary */}
      <MySlowList text={deferredText} />
    </div>
  );
 }
```

This allows us to start showing the new text for the `input` immediately, which allows the webpage to feel responsive. Meanwhile, `MySlowList` “lags behind”, allowing it to render with the current text in the background.

**For an in-depth look at deferring values, you can read [Concurrent UI Patterns](/docs/concurrent-mode-patterns.html#deferring-a-value).**

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/concurrent-mode-reference.md)

----
url: https://react.dev/learn/creating-a-react-app
----

[Learn React](/learn)

[Installation](/learn/installation)

# Creating a React App[](#undefined "Link for this heading")

If you want to build a new app or website with React, we recommend starting with a framework.

If your app has constraints not well-served by existing frameworks, you prefer to build your own framework, or you just want to learn the basics of a React app, you can [build a React app from scratch](/learn/build-a-react-app-from-scratch).

## Full-stack frameworks[](#full-stack-frameworks "Link for Full-stack frameworks ")

These recommended frameworks support all the features you need to deploy and scale your app in production. They have integrated the latest React features and take advantage of React’s architecture.

### Note

#### Full-stack frameworks do not require a server.[](#react-frameworks-do-not-require-a-server "Link for Full-stack frameworks do not require a server. ")

All the frameworks on this page support client-side rendering ([CSR](https://developer.mozilla.org/en-US/docs/Glossary/CSR)), single-page apps ([SPA](https://developer.mozilla.org/en-US/docs/Glossary/SPA)), and static-site generation ([SSG](https://developer.mozilla.org/en-US/docs/Glossary/SSG)). These apps can be deployed to a [CDN](https://developer.mozilla.org/en-US/docs/Glossary/CDN) or static hosting service without a server. Additionally, these frameworks allow you to add server-side rendering on a per-route basis, when it makes sense for your use case.

This allows you to start with a client-only app, and if your needs change later, you can opt-in to using server features on individual routes without rewriting your app. See your framework’s documentation for configuring the rendering strategy.

### Next.js (App Router)[](#nextjs-app-router "Link for Next.js (App Router) ")

**[Next.js’s App Router](https://nextjs.org/docs) is a React framework that takes full advantage of React’s architecture to enable full-stack React apps.**

Terminal

```
npx create-next-app@latest
```

Next.js is maintained by [Vercel](https://vercel.com/). You can [deploy a Next.js app](https://nextjs.org/docs/app/building-your-application/deploying) to any hosting provider that supports Node.js or Docker containers, or to your own server. Next.js also supports [static export](https://nextjs.org/docs/app/building-your-application/deploying/static-exports) which doesn’t require a server.

### React Router (v7)[](#react-router-v7 "Link for React Router (v7) ")

**[React Router](https://reactrouter.com/start/framework/installation) is the most popular routing library for React and can be paired with Vite to create a full-stack React framework**. It emphasizes standard Web APIs and has several [ready to deploy templates](https://github.com/remix-run/react-router-templates) for various JavaScript runtimes and platforms.

To create a new React Router framework project, run:

Terminal

```
npx create-react-router@latest
```

React Router is maintained by [Shopify](https://www.shopify.com).

### Expo (for native apps)[](#expo "Link for Expo (for native apps) ")

**[Expo](https://expo.dev/) is a React framework that lets you create universal Android, iOS, and web apps with truly native UIs.** It provides an SDK for [React Native](https://reactnative.dev/) that makes the native parts easier to use. To create a new Expo project, run:

Terminal

```
npx create-expo-app@latest
```

If you’re new to Expo, check out the [Expo tutorial](https://docs.expo.dev/tutorial/introduction/).

Expo is maintained by [Expo (the company)](https://expo.dev/about). Building apps with Expo is free, and you can submit them to the Google and Apple app stores without restrictions. Expo additionally provides opt-in paid cloud services.

## Other frameworks[](#other-frameworks "Link for Other frameworks ")

There are other up-and-coming frameworks that are working towards our full stack React vision:

* [TanStack Start (Beta)](https://tanstack.com/start/): TanStack Start is a full-stack React framework powered by TanStack Router. It provides a full-document SSR, streaming, server functions, bundling, and more using tools like Nitro and Vite.
* [RedwoodSDK](https://rwsdk.com/): Redwood is a full stack React framework with lots of pre-installed packages and configuration that makes it easy to build full-stack web applications.

##### Deep Dive#### Which features make up the React team’s full-stack architecture vision?[](#which-features-make-up-the-react-teams-full-stack-architecture-vision "Link for Which features make up the React team’s full-stack architecture vision? ")

Next.js’s App Router bundler fully implements the official [React Server Components specification](https://github.com/reactjs/rfcs/blob/main/text/0188-server-components.md). This lets you mix build-time, server-only, and interactive components in a single React tree.

For example, you can write a server-only React component as an `async` function that reads from a database or from a file. Then you can pass data down from it to your interactive components:

```
// This component runs *only* on the server (or during the build).

async function Talks({ confId }) {

  // 1. You're on the server, so you can talk to your data layer. API endpoint not required.

  const talks = await db.Talks.findAll({ confId });



  // 2. Add any amount of rendering logic. It won't make your JavaScript bundle larger.

  const videos = talks.map(talk => talk.video);



  // 3. Pass the data down to the components that will run in the browser.

  return <SearchableVideoList videos={videos} />;

}
```

Next.js’s App Router also integrates [data fetching with Suspense](/blog/2022/03/29/react-v18#suspense-in-data-frameworks). This lets you specify a loading state (like a skeleton placeholder) for different parts of your user interface directly in your React tree:

```
<Suspense fallback={<TalksLoading />}>

  <Talks confId={conf.id} />

</Suspense>
```

Server Components and Suspense are React features rather than Next.js features. However, adopting them at the framework level requires buy-in and non-trivial implementation work. At the moment, the Next.js App Router is the most complete implementation. The React team is working with bundler developers to make these features easier to implement in the next generation of frameworks.

## Start From Scratch[](#start-from-scratch "Link for Start From Scratch ")

If your app has constraints not well-served by existing frameworks, you prefer to build your own framework, or you just want to learn the basics of a React app, there are other options available for starting a React project from scratch.

Starting from scratch gives you more flexibility, but does require that you make choices on which tools to use for routing, data fetching, and other common usage patterns. It’s a lot like building your own framework, instead of using a framework that already exists. The [frameworks we recommend](#full-stack-frameworks) have built-in solutions for these problems.

If you want to build your own solutions, see our guide to [build a React app from Scratch](/learn/build-a-react-app-from-scratch) for instructions on how to set up a new React project starting with a build tool like [Vite](https://vite.dev/), [Parcel](https://parceljs.org/), or [RSbuild](https://rsbuild.dev/).

***

*If you’re a framework author interested in being included on this page, [please let us know](https://github.com/reactjs/react.dev/issues/new?assignees=\&labels=type%3A+framework\&projects=\&template=3-framework.yml\&title=%5BFramework%5D%3A+).*

[PreviousInstallation](/learn/installation)

[NextBuild a React App from Scratch](/learn/build-a-react-app-from-scratch)

***

----
url: https://react.dev/reference/react-dom/components/title
----

[API Reference](/reference/react)

[Components](/reference/react-dom/components)

# \<title>[](#undefined "Link for this heading")

The [built-in browser `<title>` component](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/title) lets you specify the title of the document.

```
<title>My Blog</title>
```

* [Reference](#reference)
  * [`<title>`](#title)

* [Usage](#usage)

  * [Set the document title](#set-the-document-title)
  * [Use variables in the title](#use-variables-in-the-title)

***

## Reference[](#reference "Link for Reference ")

### `<title>`[](#title "Link for this heading")

To specify the title of the document, render the [built-in browser `<title>` component](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/title). You can render `<title>` from any component and React will always place the corresponding DOM element in the document head.

```
<title>My Blog</title>
```

[See more examples below.](#usage)

#### Props[](#props "Link for Props ")

`<title>` supports all [common element props.](/reference/react-dom/components/common#common-props)

***

## Usage[](#usage "Link for Usage ")

### Set the document title[](#set-the-document-title "Link for Set the document title ")

Render the `<title>` component from any component with text as its children. React will put a `<title>` DOM node in the document `<head>`.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import ShowRenderedHTML from './ShowRenderedHTML.js';

export default function ContactUsPage() {
  return (
    <ShowRenderedHTML>
      <title>My Site: Contact Us</title>
      <h1>Contact Us</h1>
      <p>Email us at support@example.com</p>
    </ShowRenderedHTML>
  );
}
```

### Use variables in the title[](#use-variables-in-the-title "Link for Use variables in the title ")

The children of the `<title>` component must be a single string of text. (Or a single number or a single object with a `toString` method.) It might not be obvious, but using JSX curly braces like this:

```
<title>Results page {pageNumber}</title> // 🔴 Problem: This is not a single string
```

… actually causes the `<title>` component to get a two-element array as its children (the string `"Results page"` and the value of `pageNumber`). This will cause an error. Instead, use string interpolation to pass `<title>` a single string:

```
<title>{`Results page ${pageNumber}`}</title>
```

[Previous\<style>](/reference/react-dom/components/style)

[NextAPIs](/reference/react-dom)

***

----
url: https://legacy.reactjs.org/docs/jsx-in-depth.html
----

> These docs are old and won’t be updated. Go to [react.dev](https://react.dev/) for the new React docs.

Fundamentally, JSX just provides syntactic sugar for the `React.createElement(component, props, ...children)` function. The JSX code:

```
<MyButton color="blue" shadowSize={2}>
  Click Me
</MyButton>
```

compiles into:

```
React.createElement(
  MyButton,
  {color: 'blue', shadowSize: 2},
  'Click Me'
)
```

You can also use the self-closing form of the tag if there are no children. So:

```
<div className="sidebar" />
```

compiles into:

```
React.createElement(
  'div',
  {className: 'sidebar'}
)
```

If you want to test out how some specific JSX is converted into JavaScript, you can try out [the online Babel compiler](https://babeljs.io/repl/#?presets=react\&code_lz=GYVwdgxgLglg9mABACwKYBt1wBQEpEDeAUIogE6pQhlIA8AJjAG4B8AEhlogO5xnr0AhLQD0jVgG4iAXyJA).

## [](#specifying-the-react-element-type)Specifying The React Element Type

The first part of a JSX tag determines the type of the React element.

Capitalized types indicate that the JSX tag is referring to a React component. These tags get compiled into a direct reference to the named variable, so if you use the JSX `<Foo />` expression, `Foo` must be in scope.

### [](#react-must-be-in-scope)React Must Be in Scope

Since JSX compiles into calls to `React.createElement`, the `React` library must also always be in scope from your JSX code.

For example, both of the imports are necessary in this code, even though `React` and `CustomButton` are not directly referenced from JavaScript:

```
import React from 'react';import CustomButton from './CustomButton';
function WarningButton() {
  // return React.createElement(CustomButton, {color: 'red'}, null);  return <CustomButton color="red" />;
}
```

If you don’t use a JavaScript bundler and loaded React from a `<script>` tag, it is already in scope as the `React` global.

### [](#using-dot-notation-for-jsx-type)Using Dot Notation for JSX Type

You can also refer to a React component using dot-notation from within JSX. This is convenient if you have a single module that exports many React components. For example, if `MyComponents.DatePicker` is a component, you can use it directly from JSX with:

```
import React from 'react';

const MyComponents = {
  DatePicker: function DatePicker(props) {
    return <div>Imagine a {props.color} datepicker here.</div>;
  }
}

function BlueDatePicker() {
  return <MyComponents.DatePicker color="blue" />;}
```

### [](#user-defined-components-must-be-capitalized)User-Defined Components Must Be Capitalized

When an element type starts with a lowercase letter, it refers to a built-in component like `<div>` or `<span>` and results in a string `'div'` or `'span'` passed to `React.createElement`. Types that start with a capital letter like `<Foo />` compile to `React.createElement(Foo)` and correspond to a component defined or imported in your JavaScript file.

We recommend naming components with a capital letter. If you do have a component that starts with a lowercase letter, assign it to a capitalized variable before using it in JSX.

For example, this code will not run as expected:

```
import React from 'react';

// Wrong! This is a component and should have been capitalized:function hello(props) {  // Correct! This use of <div> is legitimate because div is a valid HTML tag:
  return <div>Hello {props.toWhat}</div>;
}

function HelloWorld() {
  // Wrong! React thinks <hello /> is an HTML tag because it's not capitalized:  return <hello toWhat="World" />;}
```

To fix this, we will rename `hello` to `Hello` and use `<Hello />` when referring to it:

```
import React from 'react';

// Correct! This is a component and should be capitalized:function Hello(props) {  // Correct! This use of <div> is legitimate because div is a valid HTML tag:
  return <div>Hello {props.toWhat}</div>;
}

function HelloWorld() {
  // Correct! React knows <Hello /> is a component because it's capitalized.  return <Hello toWhat="World" />;}
```

### [](#choosing-the-type-at-runtime)Choosing the Type at Runtime

You cannot use a general expression as the React element type. If you do want to use a general expression to indicate the type of the element, just assign it to a capitalized variable first. This often comes up when you want to render a different component based on a prop:

```
import React from 'react';
import { PhotoStory, VideoStory } from './stories';

const components = {
  photo: PhotoStory,
  video: VideoStory
};

function Story(props) {
  // Wrong! JSX type can't be an expression.  return <components[props.storyType] story={props.story} />;}
```

To fix this, we will assign the type to a capitalized variable first:

```
import React from 'react';
import { PhotoStory, VideoStory } from './stories';

const components = {
  photo: PhotoStory,
  video: VideoStory
};

function Story(props) {
  // Correct! JSX type can be a capitalized variable.  const SpecificStory = components[props.storyType];  return <SpecificStory story={props.story} />;}
```

## [](#props-in-jsx)Props in JSX

There are several different ways to specify props in JSX.

### [](#javascript-expressions-as-props)JavaScript Expressions as Props

You can pass any JavaScript expression as a prop, by surrounding it with `{}`. For example, in this JSX:

```
<MyComponent foo={1 + 2 + 3 + 4} />
```

For `MyComponent`, the value of `props.foo` will be `10` because the expression `1 + 2 + 3 + 4` gets evaluated.

`if` statements and `for` loops are not expressions in JavaScript, so they can’t be used in JSX directly. Instead, you can put these in the surrounding code. For example:

```
function NumberDescriber(props) {
  let description;
  if (props.number % 2 == 0) {    description = <strong>even</strong>;  } else {    description = <i>odd</i>;  }  return <div>{props.number} is an {description} number</div>;
}
```

You can learn more about [conditional rendering](/docs/conditional-rendering.html) and [loops](/docs/lists-and-keys.html) in the corresponding sections.

### [](#string-literals)String Literals

You can pass a string literal as a prop. These two JSX expressions are equivalent:

```
<MyComponent message="hello world" />

<MyComponent message={'hello world'} />
```

When you pass a string literal, its value is HTML-unescaped. So these two JSX expressions are equivalent:

```
<MyComponent message="&lt;3" />

<MyComponent message={'<3'} />
```

This behavior is usually not relevant. It’s only mentioned here for completeness.

### [](#props-default-to-true)Props Default to “True”

If you pass no value for a prop, it defaults to `true`. These two JSX expressions are equivalent:

```
<MyTextBox autocomplete />

<MyTextBox autocomplete={true} />
```

In general, we don’t recommend *not* passing a value for a prop, because it can be confused with the [ES6 object shorthand](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Object_initializer#New_notations_in_ECMAScript_2015) `{foo}` which is short for `{foo: foo}` rather than `{foo: true}`. This behavior is just there so that it matches the behavior of HTML.

### [](#spread-attributes)Spread Attributes

If you already have `props` as an object, and you want to pass it in JSX, you can use `...` as a “spread” syntax to pass the whole props object. These two components are equivalent:

```
function App1() {
  return <Greeting firstName="Ben" lastName="Hector" />;
}

function App2() {
  const props = {firstName: 'Ben', lastName: 'Hector'};
  return <Greeting {...props} />;}
```

You can also pick specific props that your component will consume while passing all other props using the spread syntax.

```
const Button = props => {
  const { kind, ...other } = props;  const className = kind === "primary" ? "PrimaryButton" : "SecondaryButton";
  return <button className={className} {...other} />;
};

const App = () => {
  return (
    <div>
      <Button kind="primary" onClick={() => console.log("clicked!")}>
        Hello World!
      </Button>
    </div>
  );
};
```

In the example above, the `kind` prop is safely consumed and *is not* passed on to the `<button>` element in the DOM. All other props are passed via the `...other` object making this component really flexible. You can see that it passes an `onClick` and `children` props.

Spread attributes can be useful but they also make it easy to pass unnecessary props to components that don’t care about them or to pass invalid HTML attributes to the DOM. We recommend using this syntax sparingly.

## [](#children-in-jsx)Children in JSX

In JSX expressions that contain both an opening tag and a closing tag, the content between those tags is passed as a special prop: `props.children`. There are several different ways to pass children:

### [](#string-literals-1)String Literals

You can put a string between the opening and closing tags and `props.children` will just be that string. This is useful for many of the built-in HTML elements. For example:

```
<MyComponent>Hello world!</MyComponent>
```

This is valid JSX, and `props.children` in `MyComponent` will simply be the string `"Hello world!"`. HTML is unescaped, so you can generally write JSX just like you would write HTML in this way:

```
<div>This is valid HTML &amp; JSX at the same time.</div>
```

JSX removes whitespace at the beginning and ending of a line. It also removes blank lines. New lines adjacent to tags are removed; new lines that occur in the middle of string literals are condensed into a single space. So these all render to the same thing:

```
<div>Hello World</div>

<div>
  Hello World
</div>

<div>
  Hello
  World
</div>

<div>

  Hello World
</div>
```

### [](#jsx-children)JSX Children

You can provide more JSX elements as the children. This is useful for displaying nested components:

```
<MyContainer>
  <MyFirstComponent />
  <MySecondComponent />
</MyContainer>
```

You can mix together different types of children, so you can use string literals together with JSX children. This is another way in which JSX is like HTML, so that this is both valid JSX and valid HTML:

```
<div>
  Here is a list:
  <ul>
    <li>Item 1</li>
    <li>Item 2</li>
  </ul>
</div>
```

A React component can also return an array of elements:

```
render() {
  // No need to wrap list items in an extra element!
  return [
    // Don't forget the keys :)
    <li key="A">First item</li>,
    <li key="B">Second item</li>,
    <li key="C">Third item</li>,
  ];
}
```

### [](#javascript-expressions-as-children)JavaScript Expressions as Children

You can pass any JavaScript expression as children, by enclosing it within `{}`. For example, these expressions are equivalent:

```
<MyComponent>foo</MyComponent>

<MyComponent>{'foo'}</MyComponent>
```

This is often useful for rendering a list of JSX expressions of arbitrary length. For example, this renders an HTML list:

```
function Item(props) {
  return <li>{props.message}</li>;}

function TodoList() {
  const todos = ['finish doc', 'submit pr', 'nag dan to review'];
  return (
    <ul>
      {todos.map((message) => <Item key={message} message={message} />)}    </ul>
  );
}
```

JavaScript expressions can be mixed with other types of children. This is often useful in lieu of string templates:

```
function Hello(props) {
  return <div>Hello {props.addressee}!</div>;}
```

### [](#functions-as-children)Functions as Children

Normally, JavaScript expressions inserted in JSX will evaluate to a string, a React element, or a list of those things. However, `props.children` works just like any other prop in that it can pass any sort of data, not just the sorts that React knows how to render. For example, if you have a custom component, you could have it take a callback as `props.children`:

```
// Calls the children callback numTimes to produce a repeated component
function Repeat(props) {
  let items = [];
  for (let i = 0; i < props.numTimes; i++) {    items.push(props.children(i));
  }
  return <div>{items}</div>;
}

function ListOfTenThings() {
  return (
    <Repeat numTimes={10}>
      {(index) => <div key={index}>This is item {index} in the list</div>}    </Repeat>
  );
}
```

Children passed to a custom component can be anything, as long as that component transforms them into something React can understand before rendering. This usage is not common, but it works if you want to stretch what JSX is capable of.

### [](#booleans-null-and-undefined-are-ignored)Booleans, Null, and Undefined Are Ignored

`false`, `null`, `undefined`, and `true` are valid children. They simply don’t render. These JSX expressions will all render to the same thing:

```
<div />

<div></div>

<div>{false}</div>

<div>{null}</div>

<div>{undefined}</div>

<div>{true}</div>
```

This can be useful to conditionally render React elements. This JSX renders the `<Header />` component only if `showHeader` is `true`:

```
<div>
  {showHeader && <Header />}  <Content />
</div>
```

One caveat is that some [“falsy” values](https://developer.mozilla.org/en-US/docs/Glossary/Falsy), such as the `0` number, are still rendered by React. For example, this code will not behave as you might expect because `0` will be printed when `props.messages` is an empty array:

```
<div>
  {props.messages.length &&    <MessageList messages={props.messages} />
  }
</div>
```

To fix this, make sure that the expression before `&&` is always boolean:

```
<div>
  {props.messages.length > 0 &&    <MessageList messages={props.messages} />
  }
</div>
```

Conversely, if you want a value like `false`, `true`, `null`, or `undefined` to appear in the output, you have to [convert it to a string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String#String_conversion) first:

```
<div>
  My JavaScript variable is {String(myVariable)}.</div>
```

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/jsx-in-depth.md)

----
url: https://legacy.reactjs.org/docs/strict-mode.html
----

> These docs are old and won’t be updated. Go to [react.dev](https://react.dev/) for the new React docs.
>
> These new documentation pages teach modern React and include live examples:
>
> * [`StrictMode`](https://react.dev/reference/react/StrictMode)

`StrictMode` is a tool for highlighting potential problems in an application. Like `Fragment`, `StrictMode` does not render any visible UI. It activates additional checks and warnings for its descendants.

> Note:
>
> Strict mode checks are run in development mode only; *they do not impact the production build*.

You can enable strict mode for any part of your application. For example:

```
import React from 'react';

function ExampleApplication() {
  return (
    <div>
      <Header />
      <React.StrictMode>        <div>
          <ComponentOne />
          <ComponentTwo />
        </div>
      </React.StrictMode>      <Footer />
    </div>
  );
}
```

In the above example, strict mode checks will *not* be run against the `Header` and `Footer` components. However, `ComponentOne` and `ComponentTwo`, as well as all of their descendants, will have the checks.

`StrictMode` currently helps with:

* [Identifying components with unsafe lifecycles](#identifying-unsafe-lifecycles)
* [Warning about legacy string ref API usage](#warning-about-legacy-string-ref-api-usage)
* [Warning about deprecated findDOMNode usage](#warning-about-deprecated-finddomnode-usage)
* [Detecting unexpected side effects](#detecting-unexpected-side-effects)
* [Detecting legacy context API](#detecting-legacy-context-api)
* [Ensuring reusable state](#ensuring-reusable-state)

Additional functionality will be added with future releases of React.

### [](#identifying-unsafe-lifecycles)Identifying unsafe lifecycles

As explained [in this blog post](/blog/2018/03/27/update-on-async-rendering.html), certain legacy lifecycle methods are unsafe for use in async React applications. However, if your application uses third party libraries, it can be difficult to ensure that these lifecycles aren’t being used. Fortunately, strict mode can help with this!

When strict mode is enabled, React compiles a list of all class components using the unsafe lifecycles, and logs a warning message with information about these components, like so:

[](/static/e4fdbff774b356881123e69ad88eda88/1628f/strict-mode-unsafe-lifecycles-warning.png)

Addressing the issues identified by strict mode *now* will make it easier for you to take advantage of concurrent rendering in future releases of React.

### [](#warning-about-legacy-string-ref-api-usage)Warning about legacy string ref API usage

Previously, React provided two ways for managing refs: the legacy string ref API and the callback API. Although the string ref API was the more convenient of the two, it had [several downsides](https://github.com/facebook/react/issues/1373) and so our official recommendation was to [use the callback form instead](/docs/refs-and-the-dom.html#legacy-api-string-refs).

React 16.3 added a third option that offers the convenience of a string ref without any of the downsides:

```
class MyComponent extends React.Component {
  constructor(props) {
    super(props);

    this.inputRef = React.createRef();  }

  render() {
    return <input type="text" ref={this.inputRef} />;  }

  componentDidMount() {
    this.inputRef.current.focus();  }
}
```

Since object refs were largely added as a replacement for string refs, strict mode now warns about usage of string refs.

> **Note:**
>
> Callback refs will continue to be supported in addition to the new `createRef` API.
>
> You don’t need to replace callback refs in your components. They are slightly more flexible, so they will remain as an advanced feature.

[Learn more about the new `createRef` API here.](/docs/refs-and-the-dom.html)

### [](#warning-about-deprecated-finddomnode-usage)Warning about deprecated findDOMNode usage

React used to support `findDOMNode` to search the tree for a DOM node given a class instance. Normally you don’t need this because you can [attach a ref directly to a DOM node](/docs/refs-and-the-dom.html#creating-refs).

`findDOMNode` can also be used on class components but this was breaking abstraction levels by allowing a parent to demand that certain children were rendered. It creates a refactoring hazard where you can’t change the implementation details of a component because a parent might be reaching into its DOM node. `findDOMNode` only returns the first child, but with the use of Fragments, it is possible for a component to render multiple DOM nodes. `findDOMNode` is a one time read API. It only gave you an answer when you asked for it. If a child component renders a different node, there is no way to handle this change. Therefore `findDOMNode` only worked if components always return a single DOM node that never changes.

You can instead make this explicit by passing a ref to your custom component and pass that along to the DOM using [ref forwarding](/docs/forwarding-refs.html#forwarding-refs-to-dom-components).

You can also add a wrapper DOM node in your component and attach a ref directly to it.

```
class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.wrapper = React.createRef();  }
  render() {
    return <div ref={this.wrapper}>{this.props.children}</div>;  }
}
```

> Note:
>
> In CSS, the [`display: contents`](https://developer.mozilla.org/en-US/docs/Web/CSS/display#display_contents) attribute can be used if you don’t want the node to be part of the layout.

### [](#detecting-unexpected-side-effects)Detecting unexpected side effects

Conceptually, React does work in two phases:

* The **render** phase determines what changes need to be made to e.g. the DOM. During this phase, React calls `render` and then compares the result to the previous render.
* The **commit** phase is when React applies any changes. (In the case of React DOM, this is when React inserts, updates, and removes DOM nodes.) React also calls lifecycles like `componentDidMount` and `componentDidUpdate` during this phase.

The commit phase is usually very fast, but rendering can be slow. For this reason, the upcoming concurrent mode (which is not enabled by default yet) breaks the rendering work into pieces, pausing and resuming the work to avoid blocking the browser. This means that React may invoke render phase lifecycles more than once before committing, or it may invoke them without committing at all (because of an error or a higher priority interruption).

Render phase lifecycles include the following class component methods:

* `constructor`
* `componentWillMount` (or `UNSAFE_componentWillMount`)
* `componentWillReceiveProps` (or `UNSAFE_componentWillReceiveProps`)
* `componentWillUpdate` (or `UNSAFE_componentWillUpdate`)
* `getDerivedStateFromProps`
* `shouldComponentUpdate`
* `render`
* `setState` updater functions (the first argument)

Because the above methods might be called more than once, it’s important that they do not contain side-effects. Ignoring this rule can lead to a variety of problems, including memory leaks and invalid application state. Unfortunately, it can be difficult to detect these problems as they can often be [non-deterministic](https://en.wikipedia.org/wiki/Deterministic_algorithm).

Strict mode can’t automatically detect side effects for you, but it can help you spot them by making them a little more deterministic. This is done by intentionally double-invoking the following functions:

* Class component `constructor`, `render`, and `shouldComponentUpdate` methods
* Class component static `getDerivedStateFromProps` method
* Function component bodies
* State updater functions (the first argument to `setState`)
* Functions passed to `useState`, `useMemo`, or `useReducer`

> Note:
>
> This only applies to development mode. *Lifecycles will not be double-invoked in production mode.*

For example, consider the following code:

```
class TopLevelRoute extends React.Component {
  constructor(props) {
    super(props);

    SharedApplicationState.recordEvent('ExampleComponent');
  }
}
```

At first glance, this code might not seem problematic. But if `SharedApplicationState.recordEvent` is not [idempotent](https://en.wikipedia.org/wiki/Idempotence#Computer_science_meaning), then instantiating this component multiple times could lead to invalid application state. This sort of subtle bug might not manifest during development, or it might do so inconsistently and so be overlooked.

By intentionally double-invoking methods like the component constructor, strict mode makes patterns like this easier to spot.

> Note:
>
> In React 17, React automatically modifies the console methods like `console.log()` to silence the logs in the second call to lifecycle functions. However, it may cause undesired behavior in certain cases where [a workaround can be used](https://github.com/facebook/react/issues/20090#issuecomment-715927125).
>
> Starting from React 18, React does not suppress any logs. However, if you have React DevTools installed, the logs from the second call will appear slightly dimmed. React DevTools also offers a setting (off by default) to suppress them completely.

### [](#detecting-legacy-context-api)Detecting legacy context API

The legacy context API is error-prone, and will be removed in a future major version. It still works for all 16.x releases but will show this warning message in strict mode:

[](/static/fca5c5e1fb2ef2e2d59afb100b432c12/51800/warn-legacy-context-in-strict-mode.png)

Read the [new context API documentation](/docs/context.html) to help migrate to the new version.

### [](#ensuring-reusable-state)Ensuring reusable state

In the future, we’d like to add a feature that allows React to add and remove sections of the UI while preserving state. For example, when a user tabs away from a screen and back, React should be able to immediately show the previous screen. To do this, React will support remounting trees using the same component state used before unmounting.

This feature will give React better performance out-of-the-box, but requires components to be resilient to effects being mounted and destroyed multiple times. Most effects will work without any changes, but some effects do not properly clean up subscriptions in the destroy callback, or implicitly assume they are only mounted or destroyed once.

To help surface these issues, React 18 introduces a new development-only check to Strict Mode. This new check will automatically unmount and remount every component, whenever a component mounts for the first time, restoring the previous state on the second mount.

To demonstrate the development behavior you’ll see in Strict Mode with this feature, consider what happens when React mounts a new component. Without this change, when a component mounts, React creates the effects:

```
* React mounts the component.
  * Layout effects are created.
  * Effects are created.
```

With Strict Mode starting in React 18, whenever a component mounts in development, React will simulate immediately unmounting and remounting the component:

```
* React mounts the component.
    * Layout effects are created.
    * Effects are created.
* React simulates effects being destroyed on a mounted component.
    * Layout effects are destroyed.
    * Effects are destroyed.
* React simulates effects being re-created on a mounted component.
    * Layout effects are created
    * Effect setup code runs
```

On the second mount, React will restore the state from the first mount. This feature simulates user behavior such as a user tabbing away from a screen and back, ensuring that code will properly handle state restoration.

When the component unmounts, effects are destroyed as normal:

```
* React unmounts the component.
  * Layout effects are destroyed.
  * Effects are destroyed.
```

Unmounting and remounting includes:

* `componentDidMount`
* `componentWillUnmount`
* `useEffect`
* `useLayoutEffect`
* `useInsertionEffect`

> Note:
>
> This only applies to development mode, *production behavior is unchanged*.

For help supporting common issues, see:

* [How to support Reusable State in Effects](https://github.com/reactwg/react-18/discussions/18)

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/strict-mode.md)

----
url: https://legacy.reactjs.org/blog/2014/07/17/react-v0.11.html
----

July 17, 2014 by [Paul O’Shannessy](https://twitter.com/zpao)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

**Update:** We missed a few important changes in our initial post and changelog. We’ve updated this post with details about [Descriptors](#descriptors) and [Prop Type Validation](#prop-type-validation).

***

We’re really happy to announce the availability of React v0.11. There seems to be a lot of excitement already and we appreciate everybody who gave the release candidate a try over the weekend. We made a couple small changes in response to the feedback and issues filed. We enabled the destructuring assignment transform when using `jsx --harmony`, fixed a small regression with `statics`, and made sure we actually exposed the new API we said we were shipping: `React.Children.count`.

This version has been cooking for a couple months now and includes a wide array of bug fixes and features. We highlighted some of the most important changes below, along with the full changelog.

The release is available for download from the CDN:

* **React**\
  Dev build with warnings: <https://fb.me/react-0.11.0.js>\
  Minified build for production: <https://fb.me/react-0.11.0.min.js>
* **React with Add-Ons**\
  Dev build with warnings: <https://fb.me/react-with-addons-0.11.0.js>\
  Minified build for production: <https://fb.me/react-with-addons-0.11.0.min.js>
* **In-Browser JSX transformer**\
  <https://fb.me/JSXTransformer-0.11.0.js>

We’ve also published version `0.11.0` of the `react` and `react-tools` packages on npm and the `react` package on bower.

Please try these builds out and [file an issue on GitHub](https://github.com/facebook/react/issues/new) if you see anything awry.

## [](#getdefaultprops)`getDefaultProps`

Starting in React 0.11, `getDefaultProps()` is called only once when `React.createClass()` is called, instead of each time a component is rendered. This means that `getDefaultProps()` can no longer vary its return value based on `this.props` and any objects will be shared across all instances. This change improves performance and will make it possible in the future to do PropTypes checks earlier in the rendering process, allowing us to give better error messages.

## [](#rendering-to-null)Rendering to `null`

Since React’s release, people have been using work arounds to “render nothing”. Usually this means returning an empty `<div/>` or `<span/>`. Some people even got clever and started returning `<noscript/>` to avoid extraneous DOM nodes. We finally provided a “blessed” solution that allows developers to write meaningful code. Returning `null` is an explicit indication to React that you do not want anything rendered. Behind the scenes we make this work with a `<noscript>` element, though in the future we hope to not put anything in the document. In the mean time, `<noscript>` elements do not affect layout in any way, so you can feel safe using `null` today!

```
// Before
render: function() {
  if (!this.state.visible) {
    return <span/>;
  }
  // ...
}

// After
render: function() {
  if (!this.state.visible) {
    return null;
  }
  // ...
}
```

## [](#jsx-namespacing)JSX Namespacing

Another feature request we’ve been hearing for a long time is the ability to have namespaces in JSX. Given that JSX is just JavaScript, we didn’t want to use XML namespacing. Instead we opted for a standard JS approach: object property access. Instead of assigning variables to access components stored in an object (such as a component library), you can now use the component directly as `<Namespace.Component/>`.

```
// Before
var UI = require('UI');
var UILayout = UI.Layout;
var UIButton = UI.Button;
var UILabel = UI.Label;

render: function() {
  return <UILayout><UIButton /><UILabel>text</UILabel></UILayout>;
}

// After
var UI = require('UI');

render: function() {
  return <UI.Layout><UI.Button /><UI.Label>text</UI.Label></UI.Layout>;
}
```

## [](#improved-keyboard-event-normalization)Improved keyboard event normalization

Keyboard events now contain a normalized `e.key` value according to the [DOM Level 3 Events spec](http://www.w3.org/TR/DOM-Level-3-Events/#keys-special), allowing you to write simpler key handling code that works in all browsers, such as:

```
handleKeyDown: function(e) {
  if (e.key === 'Enter') {
    // Handle enter key
  } else if (e.key === ' ') {
    // Handle spacebar
  } else if (e.key === 'ArrowLeft') {
    // Handle left arrow
  }
},
```

Keyboard and mouse events also now include a normalized `e.getModifierState()` that works consistently across browsers.

## [](#descriptors)Descriptors

In our [v0.10 release notes](/blog/2014/03/21/react-v0.10.html#clone-on-mount), we called out that we were deprecating the existing behavior of the component function call (eg `component = MyComponent(props, ...children)` or `component = <MyComponent prop={...}/>`). Previously that would create an instance and React would modify that internally. You could store that reference and then call functions on it (eg `component.setProps(...)`). This no longer works. `component` in the above examples will be a descriptor and not an instance that can be operated on. The v0.10 release notes provide a complete example along with a migration path. The development builds also provided warnings if you called functions on descriptors.

Along with this change to descriptors, `React.isValidComponent` and `React.PropTypes.component` now actually validate that the value is a descriptor. Overwhelmingly, these functions are used to validate the value of `MyComponent()`, which as mentioned is now a descriptor, not a component instance. We opted to reduce code churn and make the migration to 0.11 as easy as possible. However, we realize this is has caused some confusion and we’re working to make sure we are consistent with our terminology.

## [](#prop-type-validation)Prop Type Validation

Previously `React.PropTypes` validation worked by simply logging to the console. Internally, each validator was responsible for doing this itself. Additionally, you could write a custom validator and the expectation was that you would also simply `console.log` your error message. Very shortly into the 0.11 cycle we changed this so that our validators return (*not throw*) an `Error` object. We then log the `error.message` property in a central place in ReactCompositeComponent. Overall the result is the same, but this provides a clearer intent in validation. In addition, to better transition into our descriptor factory changes, we also currently run prop type validation twice in development builds. As a result, custom validators doing their own logging result in duplicate messages. To update, simply return an `Error` with your message instead.

## [](#changelog)Changelog

### [](#react-core)React Core

#### [](#breaking-changes)Breaking Changes

* `getDefaultProps()` is now called once per class and shared across all instances
* `MyComponent()` now returns a descriptor, not an instance
* `React.isValidComponent` and `React.PropTypes.component` validate *descriptors*, not component instances.
* Custom `propType` validators should return an `Error` instead of logging directly

* PureRenderMixin: a mixin which helps optimize “pure” components

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2014-07-17-react-v0.11.md)

----
url: https://legacy.reactjs.org/blog/2015/09/10/react-v0.14-rc1.html
----

September 10, 2015 by [Sophie Alpert](https://sophiebits.com/)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

We’re happy to announce our first release candidate for React 0.14! We gave you a [sneak peek in July](/blog/2015/07/03/react-v0.14-beta-1.html) at the upcoming changes but we’ve now stabilized the release more and we’d love for you to try it out before we release the final version.

Let us know if you run into any problems by filing issues on our [GitHub repo](https://github.com/facebook/react).

## [](#installation)Installation

We recommend using React from `npm` and using a tool like browserify or webpack to build your code into a single package:

* `npm install --save react@0.14.0-rc1`
* `npm install --save react-dom@0.14.0-rc1`

Remember that by default, React runs extra checks and provides helpful warnings in development mode. When deploying your app, set the `NODE_ENV` environment variable to `production` to use the production build of React which does not include the development warnings and runs significantly faster.

If you can’t use `npm` yet, we also provide pre-built browser builds for your convenience:

* **React**\
  Dev build with warnings: <https://fb.me/react-0.14.0-rc1.js>\
  Minified build for production: <https://fb.me/react-0.14.0-rc1.min.js>
* **React with Add-Ons**\
  Dev build with warnings: <https://fb.me/react-with-addons-0.14.0-rc1.js>\
  Minified build for production: <https://fb.me/react-with-addons-0.14.0-rc1.min.js>
* **React DOM** (include React in the page before React DOM)\
  Dev build with warnings: <https://fb.me/react-dom-0.14.0-rc1.js>\
  Minified build for production: <https://fb.me/react-dom-0.14.0-rc1.min.js>

These builds are also available in the `react` package on bower.

  ```
  var React = require('react');
  var ReactDOM = require('react-dom');

  var MyComponent = React.createClass({
    render: function() {
      return <div>Hello World</div>;
    }
  });

  ReactDOM.render(<MyComponent />, node);
  ```

  We’ve published the [automated codemod script](https://github.com/reactjs/react-codemod/blob/master/README.md) we used at Facebook to help you with this transition.

  The add-ons have moved to separate packages as well: `react-addons-clone-with-props`, `react-addons-create-fragment`, `react-addons-css-transition-group`, `react-addons-linked-state-mixin`, `react-addons-perf`, `react-addons-pure-render-mixin`, `react-addons-shallow-compare`, `react-addons-test-utils`, `react-addons-transition-group`, and `react-addons-update`, plus `ReactDOM.unstable_batchedUpdates` in `react-dom`.

  For now, please use matching versions of `react` and `react-dom` in your apps to avoid versioning problems.

* #### [](#dom-node-refs)DOM node refs

  The other big change we’re making in this release is exposing refs to DOM components as the DOM node itself. That means: we looked at what you can do with a `ref` to a React DOM component and realized that the only useful thing you can do with it is call `this.refs.giraffe.getDOMNode()` to get the underlying DOM node. In this release, `this.refs.giraffe` *is* the actual DOM node. **Note that refs to custom (user-defined) components work exactly as before; only the built-in DOM components are affected by this change.**

  ```
  var Zoo = React.createClass({
    render: function() {
      return <div>Giraffe name: <input ref="giraffe" /></div>;
    },
    showName: function() {
      // Previously: var input = this.refs.giraffe.getDOMNode();
      var input = this.refs.giraffe;
      alert(input.value);
    }
  });
  ```

  This change also applies to the return result of `ReactDOM.render` when passing a DOM node as the top component. As with refs, this change does not affect custom components. With these changes, we’re deprecating `.getDOMNode()` and replacing it with `ReactDOM.findDOMNode` (see below).

* #### [](#stateless-function-components)Stateless function components

  In idiomatic React code, most of the components you write will be stateless, simply composing other components. We’re introducing a new, simpler syntax for these components where you can take `props` as an argument and return the element you want to render:

  ```
  // Using an ES2015 (ES6) arrow function:
  var Aquarium = (props) => {
    var fish = getFish(props.species);
    return <Tank>{fish}</Tank>;
  };

  // Or with destructuring and an implicit return, simply:
  var Aquarium = ({species}) => (
    <Tank>
      {getFish(species)}
    </Tank>
  );

  // Then use: <Aquarium species="rainbowfish" />
  ```

  This pattern is designed to encourage the creation of these simple components that should comprise large portions of your apps. In the future, we’ll also be able to make performance optimizations specific to these components by avoiding unnecessary checks and memory allocations.

* #### [](#deprecation-of-react-tools)Deprecation of react-tools

  The `react-tools` package and `JSXTransformer.js` browser file [have been deprecated](/blog/2015/06/12/deprecating-jstransform-and-react-tools.html). You can continue using version `0.13.3` of both, but we no longer support them and recommend migrating to [Babel](http://babeljs.io/), which has built-in support for React and JSX.

* #### [](#compiler-optimizations)Compiler optimizations

  React now supports two compiler optimizations that can be enabled in Babel 5.8.23 and newer. Both of these transforms **should be enabled only in production** (e.g., just before minifying your code) because although they improve runtime performance, they make warning messages more cryptic and skip important checks that happen in development mode, including propTypes.

  **Inlining React elements:** The `optimisation.react.inlineElements` transform converts JSX elements to object literals like `{type: 'div', props: ...}` instead of calls to `React.createElement`.

  **Constant hoisting for React elements:** The `optimisation.react.constantElements` transform hoists element creation to the top level for subtrees that are fully static, which reduces calls to `React.createElement` and the resulting allocations. More importantly, it tells React that the subtree hasn’t changed so React can completely skip it when reconciling.

### [](#breaking-changes)Breaking changes

As always, we have a few breaking changes in this release. Whenever we make large changes, we warn for at least one release so you have time to update your code. The Facebook codebase has over 15,000 React components, so on the React team, we always try to minimize the pain of breaking changes.

These three breaking changes had a warning in 0.13, so you shouldn’t have to do anything if your code is already free of warnings:

* The `props` object is now frozen, so mutating props after creating a component element is no longer supported. In most cases, [`React.cloneElement`](/docs/top-level-api.html#react.cloneelement) should be used instead. This change makes your components easier to reason about and enables the compiler optimizations mentioned above.
* Plain objects are no longer supported as React children; arrays should be used instead. You can use the [`createFragment`](/docs/create-fragment.html) helper to migrate, which now returns an array.
* Add-Ons: `classSet` has been removed. Use [classnames](https://github.com/JedWatson/classnames) instead.

And these two changes did not warn in 0.13 but should be easy to find and clean up:

* `React.initializeTouchEvents` is no longer necessary and has been removed completely. Touch events now work automatically.
* Add-Ons: Due to the DOM node refs change mentioned above, `TestUtils.findAllInRenderedTree` and related helpers are no longer able to take a DOM component, only a custom component.

### [](#new-deprecations-introduced-with-a-warning)New deprecations, introduced with a warning

* Due to the DOM node refs change mentioned above, `this.getDOMNode()` is now deprecated and `ReactDOM.findDOMNode(this)` can be used instead. Note that in most cases, calling `findDOMNode` is now unnecessary – see the example above in the “DOM node refs” section.

  If you have a large codebase, you can use our [automated codemod script](https://github.com/facebook/react/blob/main/packages/react-codemod/README.md) to change your code automatically.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2015-09-10-react-v0.14-rc1.md)

----
url: https://react.dev/reference/react/useCallback
----

[API Reference](/reference/react)

[Hooks](/reference/react/hooks)

# useCallback[](#undefined "Link for this heading")

`useCallback` is a React Hook that lets you cache a function definition between re-renders.

```
const cachedFn = useCallback(fn, dependencies)
```

### Note

[React Compiler](/learn/react-compiler) automatically memoizes values and functions, reducing the need for manual `useCallback` calls. You can use the compiler to handle memoization automatically.

***

## Reference[](#reference "Link for Reference ")

### `useCallback(fn, dependencies)`[](#usecallback "Link for this heading")

Call `useCallback` at the top level of your component to cache a function definition between re-renders:

```
import { useCallback } from 'react';



export default function ProductPage({ productId, referrer, theme }) {

  const handleSubmit = useCallback((orderDetails) => {

    post('/product/' + productId + '/buy', {

      referrer,

      orderDetails,

    });

  }, [productId, referrer]);
```

***

## Usage[](#usage "Link for Usage ")

### Skipping re-rendering of components[](#skipping-re-rendering-of-components "Link for Skipping re-rendering of components ")

When you optimize rendering performance, you will sometimes need to cache the functions that you pass to child components. Let’s first look at the syntax for how to do this, and then see in which cases it’s useful.

To cache a function between re-renders of your component, wrap its definition into the `useCallback` Hook:

```
import { useCallback } from 'react';



function ProductPage({ productId, referrer, theme }) {

  const handleSubmit = useCallback((orderDetails) => {

    post('/product/' + productId + '/buy', {

      referrer,

      orderDetails,

    });

  }, [productId, referrer]);

  // ...
```

```
function ProductPage({ productId, referrer, theme }) {

  // ...

  return (

    <div className={theme}>

      <ShippingForm onSubmit={handleSubmit} />

    </div>

  );
```

You’ve noticed that toggling the `theme` prop freezes the app for a moment, but if you remove `<ShippingForm />` from your JSX, it feels fast. This tells you that it’s worth trying to optimize the `ShippingForm` component.

**By default, when a component re-renders, React re-renders all of its children recursively.** This is why, when `ProductPage` re-renders with a different `theme`, the `ShippingForm` component *also* re-renders. This is fine for components that don’t require much calculation to re-render. But if you verified a re-render is slow, you can tell `ShippingForm` to skip re-rendering when its props are the same as on last render by wrapping it in [`memo`:](/reference/react/memo)

```
import { memo } from 'react';



const ShippingForm = memo(function ShippingForm({ onSubmit }) {

  // ...

});
```

**With this change, `ShippingForm` will skip re-rendering if all of its props are the *same* as on the last render.** This is when caching a function becomes important! Let’s say you defined `handleSubmit` without `useCallback`:

```
function ProductPage({ productId, referrer, theme }) {

  // Every time the theme changes, this will be a different function...

  function handleSubmit(orderDetails) {

    post('/product/' + productId + '/buy', {

      referrer,

      orderDetails,

    });

  }



  return (

    <div className={theme}>

      {/* ... so ShippingForm's props will never be the same, and it will re-render every time */}

      <ShippingForm onSubmit={handleSubmit} />

    </div>

  );

}
```

**In JavaScript, a `function () {}` or `() => {}` always creates a *different* function,** similar to how the `{}` object literal always creates a new object. Normally, this wouldn’t be a problem, but it means that `ShippingForm` props will never be the same, and your [`memo`](/reference/react/memo) optimization won’t work. This is where `useCallback` comes in handy:

```
function ProductPage({ productId, referrer, theme }) {

  // Tell React to cache your function between re-renders...

  const handleSubmit = useCallback((orderDetails) => {

    post('/product/' + productId + '/buy', {

      referrer,

      orderDetails,

    });

  }, [productId, referrer]); // ...so as long as these dependencies don't change...



  return (

    <div className={theme}>

      {/* ...ShippingForm will receive the same props and can skip re-rendering */}

      <ShippingForm onSubmit={handleSubmit} />

    </div>

  );

}
```

**By wrapping `handleSubmit` in `useCallback`, you ensure that it’s the *same* function between the re-renders** (until dependencies change). You don’t *have to* wrap a function in `useCallback` unless you do it for some specific reason. In this example, the reason is that you pass it to a component wrapped in [`memo`,](/reference/react/memo) and this lets it skip re-rendering. There are other reasons you might need `useCallback` which are described further on this page.

### Note

**You should only rely on `useCallback` as a performance optimization.** If your code doesn’t work without it, find the underlying problem and fix it first. Then you may add `useCallback` back.

##### Deep Dive#### How is useCallback related to useMemo?[](#how-is-usecallback-related-to-usememo "Link for How is useCallback related to useMemo? ")

You will often see [`useMemo`](/reference/react/useMemo) alongside `useCallback`. They are both useful when you’re trying to optimize a child component. They let you [memoize](https://en.wikipedia.org/wiki/Memoization) (or, in other words, cache) something you’re passing down:

```
import { useMemo, useCallback } from 'react';



function ProductPage({ productId, referrer }) {

  const product = useData('/product/' + productId);



  const requirements = useMemo(() => { // Calls your function and caches its result

    return computeRequirements(product);

  }, [product]);



  const handleSubmit = useCallback((orderDetails) => { // Caches your function itself

    post('/product/' + productId + '/buy', {

      referrer,

      orderDetails,

    });

  }, [productId, referrer]);



  return (

    <div className={theme}>

      <ShippingForm requirements={requirements} onSubmit={handleSubmit} />

    </div>

  );

}
```

The difference is in *what* they’re letting you cache:

* **[`useMemo`](/reference/react/useMemo) caches the *result* of calling your function.** In this example, it caches the result of calling `computeRequirements(product)` so that it doesn’t change unless `product` has changed. This lets you pass the `requirements` object down without unnecessarily re-rendering `ShippingForm`. When necessary, React will call the function you’ve passed during rendering to calculate the result.
* **`useCallback` caches *the function itself.*** Unlike `useMemo`, it does not call the function you provide. Instead, it caches the function you provided so that `handleSubmit` *itself* doesn’t change unless `productId` or `referrer` has changed. This lets you pass the `handleSubmit` function down without unnecessarily re-rendering `ShippingForm`. Your code won’t run until the user submits the form.

If you’re already familiar with [`useMemo`,](/reference/react/useMemo) you might find it helpful to think of `useCallback` as this:

```
// Simplified implementation (inside React)

function useCallback(fn, dependencies) {

  return useMemo(() => fn, dependencies);

}
```

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useCallback } from 'react';
import ShippingForm from './ShippingForm.js';

export default function ProductPage({ productId, referrer, theme }) {
  const handleSubmit = useCallback((orderDetails) => {
    post('/product/' + productId + '/buy', {
      referrer,
      orderDetails,
    });
  }, [productId, referrer]);

  return (
    <div className={theme}>
      <ShippingForm onSubmit={handleSubmit} />
    </div>
  );
}

function post(url, data) {
  // Imagine this sends a request...
  console.log('POST /' + url);
  console.log(data);
}
```

***

### Updating state from a memoized callback[](#updating-state-from-a-memoized-callback "Link for Updating state from a memoized callback ")

Sometimes, you might need to update state based on previous state from a memoized callback.

This `handleAddTodo` function specifies `todos` as a dependency because it computes the next todos from it:

```
function TodoList() {

  const [todos, setTodos] = useState([]);



  const handleAddTodo = useCallback((text) => {

    const newTodo = { id: nextId++, text };

    setTodos([...todos, newTodo]);

  }, [todos]);

  // ...
```

You’ll usually want memoized functions to have as few dependencies as possible. When you read some state only to calculate the next state, you can remove that dependency by passing an [updater function](/reference/react/useState#updating-state-based-on-the-previous-state) instead:

```
function TodoList() {

  const [todos, setTodos] = useState([]);



  const handleAddTodo = useCallback((text) => {

    const newTodo = { id: nextId++, text };

    setTodos(todos => [...todos, newTodo]);

  }, []); // ✅ No need for the todos dependency

  // ...
```

Here, instead of making `todos` a dependency and reading it inside, you pass an instruction about *how* to update the state (`todos => [...todos, newTodo]`) to React. [Read more about updater functions.](/reference/react/useState#updating-state-based-on-the-previous-state)

***

### Preventing an Effect from firing too often[](#preventing-an-effect-from-firing-too-often "Link for Preventing an Effect from firing too often ")

Sometimes, you might want to call a function from inside an [Effect:](/learn/synchronizing-with-effects)

```
function ChatRoom({ roomId }) {

  const [message, setMessage] = useState('');



  function createOptions() {

    return {

      serverUrl: 'https://localhost:1234',

      roomId: roomId

    };

  }



  useEffect(() => {

    const options = createOptions();

    const connection = createConnection(options);

    connection.connect();

    // ...
```

This creates a problem. [Every reactive value must be declared as a dependency of your Effect.](/learn/lifecycle-of-reactive-effects#react-verifies-that-you-specified-every-reactive-value-as-a-dependency) However, if you declare `createOptions` as a dependency, it will cause your Effect to constantly reconnect to the chat room:

```
  useEffect(() => {

    const options = createOptions();

    const connection = createConnection(options);

    connection.connect();

    return () => connection.disconnect();

  }, [createOptions]); // 🔴 Problem: This dependency changes on every render

  // ...
```

To solve this, you can wrap the function you need to call from an Effect into `useCallback`:

```
function ChatRoom({ roomId }) {

  const [message, setMessage] = useState('');



  const createOptions = useCallback(() => {

    return {

      serverUrl: 'https://localhost:1234',

      roomId: roomId

    };

  }, [roomId]); // ✅ Only changes when roomId changes



  useEffect(() => {

    const options = createOptions();

    const connection = createConnection(options);

    connection.connect();

    return () => connection.disconnect();

  }, [createOptions]); // ✅ Only changes when createOptions changes

  // ...
```

This ensures that the `createOptions` function is the same between re-renders if the `roomId` is the same. **However, it’s even better to remove the need for a function dependency.** Move your function *inside* the Effect:

```
function ChatRoom({ roomId }) {

  const [message, setMessage] = useState('');



  useEffect(() => {

    function createOptions() { // ✅ No need for useCallback or function dependencies!

      return {

        serverUrl: 'https://localhost:1234',

        roomId: roomId

      };

    }



    const options = createOptions();

    const connection = createConnection(options);

    connection.connect();

    return () => connection.disconnect();

  }, [roomId]); // ✅ Only changes when roomId changes

  // ...
```

Now your code is simpler and doesn’t need `useCallback`. [Learn more about removing Effect dependencies.](/learn/removing-effect-dependencies#move-dynamic-objects-and-functions-inside-your-effect)

***

### Optimizing a custom Hook[](#optimizing-a-custom-hook "Link for Optimizing a custom Hook ")

If you’re writing a [custom Hook,](/learn/reusing-logic-with-custom-hooks) it’s recommended to wrap any functions that it returns into `useCallback`:

```
function useRouter() {

  const { dispatch } = useContext(RouterStateContext);



  const navigate = useCallback((url) => {

    dispatch({ type: 'navigate', url });

  }, [dispatch]);



  const goBack = useCallback(() => {

    dispatch({ type: 'back' });

  }, [dispatch]);



  return {

    navigate,

    goBack,

  };

}
```

This ensures that the consumers of your Hook can optimize their own code when needed.

***

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### Every time my component renders, `useCallback` returns a different function[](#every-time-my-component-renders-usecallback-returns-a-different-function "Link for this heading")

Make sure you’ve specified the dependency array as a second argument!

If you forget the dependency array, `useCallback` will return a new function every time:

```
function ProductPage({ productId, referrer }) {

  const handleSubmit = useCallback((orderDetails) => {

    post('/product/' + productId + '/buy', {

      referrer,

      orderDetails,

    });

  }); // 🔴 Returns a new function every time: no dependency array

  // ...
```

This is the corrected version passing the dependency array as a second argument:

```
function ProductPage({ productId, referrer }) {

  const handleSubmit = useCallback((orderDetails) => {

    post('/product/' + productId + '/buy', {

      referrer,

      orderDetails,

    });

  }, [productId, referrer]); // ✅ Does not return a new function unnecessarily

  // ...
```

If this doesn’t help, then the problem is that at least one of your dependencies is different from the previous render. You can debug this problem by manually logging your dependencies to the console:

```
  const handleSubmit = useCallback((orderDetails) => {

    // ..

  }, [productId, referrer]);



  console.log([productId, referrer]);
```

You can then right-click on the arrays from different re-renders in the console and select “Store as a global variable” for both of them. Assuming the first one got saved as `temp1` and the second one got saved as `temp2`, you can then use the browser console to check whether each dependency in both arrays is the same:

```
Object.is(temp1[0], temp2[0]); // Is the first dependency the same between the arrays?

Object.is(temp1[1], temp2[1]); // Is the second dependency the same between the arrays?

Object.is(temp1[2], temp2[2]); // ... and so on for every dependency ...
```

When you find which dependency is breaking memoization, either find a way to remove it, or [memoize it as well.](/reference/react/useMemo#memoizing-a-dependency-of-another-hook)

***

### I need to call `useCallback` for each list item in a loop, but it’s not allowed[](#i-need-to-call-usememo-for-each-list-item-in-a-loop-but-its-not-allowed "Link for this heading")

Suppose the `Chart` component is wrapped in [`memo`](/reference/react/memo). You want to skip re-rendering every `Chart` in the list when the `ReportList` component re-renders. However, you can’t call `useCallback` in a loop:

```
function ReportList({ items }) {

  return (

    <article>

      {items.map(item => {

        // 🔴 You can't call useCallback in a loop like this:

        const handleClick = useCallback(() => {

          sendReport(item)

        }, [item]);



        return (

          <figure key={item.id}>

            <Chart onClick={handleClick} />

          </figure>

        );

      })}

    </article>

  );

}
```

Instead, extract a component for an individual item, and put `useCallback` there:

```
function ReportList({ items }) {

  return (

    <article>

      {items.map(item =>

        <Report key={item.id} item={item} />

      )}

    </article>

  );

}



function Report({ item }) {

  // ✅ Call useCallback at the top level:

  const handleClick = useCallback(() => {

    sendReport(item)

  }, [item]);



  return (

    <figure>

      <Chart onClick={handleClick} />

    </figure>

  );

}
```

Alternatively, you could remove `useCallback` in the last snippet and instead wrap `Report` itself in [`memo`.](/reference/react/memo) If the `item` prop does not change, `Report` will skip re-rendering, so `Chart` will skip re-rendering too:

```
function ReportList({ items }) {

  // ...

}



const Report = memo(function Report({ item }) {

  function handleClick() {

    sendReport(item);

  }



  return (

    <figure>

      <Chart onClick={handleClick} />

    </figure>

  );

});
```

[PrevioususeActionState](/reference/react/useActionState)

[NextuseContext](/reference/react/useContext)

***

----
url: https://18.react.dev/reference/react-dom/render
----

[API Reference](/reference/react)

[APIs](/reference/react-dom)

# render[](#undefined "Link for this heading")

### Deprecated

This API will be removed in a future major version of React.

In React 18, `render` was replaced by [`createRoot`.](/reference/react-dom/client/createRoot) Using `render` in React 18 will warn that your app will behave as if it’s running React 17. Learn more [here.](/blog/2022/03/08/react-18-upgrade-guide#updates-to-client-rendering-apis)

`render` renders a piece of [JSX](/learn/writing-markup-with-jsx) (“React node”) into a browser DOM node.

```
render(reactNode, domNode, callback?)
```

* [Reference](#reference)
  * [`render(reactNode, domNode, callback?)`](#render)

* [Usage](#usage)

  * [Rendering the root component](#rendering-the-root-component)
  * [Rendering multiple roots](#rendering-multiple-roots)
  * [Updating the rendered tree](#updating-the-rendered-tree)

***

## Reference[](#reference "Link for Reference ")

### `render(reactNode, domNode, callback?)`[](#render "Link for this heading")

Call `render` to display a React component inside a browser DOM element.

```
import { render } from 'react-dom';



const domNode = document.getElementById('root');

render(<App />, domNode);
```

React will display `<App />` in the `domNode`, and take over managing the DOM inside it.

An app fully built with React will usually only have one `render` call with its root component. A page that uses “sprinkles” of React for parts of the page may have as many `render` calls as needed.

[See more examples below.](#usage)

#### Parameters[](#parameters "Link for Parameters ")

* `reactNode`: A *React node* that you want to display. This will usually be a piece of JSX like `<App />`, but you can also pass a React element constructed with [`createElement()`](/reference/react/createElement), a string, a number, `null`, or `undefined`.

* `domNode`: A [DOM element.](https://developer.mozilla.org/en-US/docs/Web/API/Element) React will display the `reactNode` you pass inside this DOM element. From this moment, React will manage the DOM inside the `domNode` and update it when your React tree changes.

* **optional** `callback`: A function. If passed, React will call it after your component is placed into the DOM.

#### Returns[](#returns "Link for Returns ")

`render` usually returns `null`. However, if the `reactNode` you pass is a *class component*, then it will return an instance of that component.

#### Caveats[](#caveats "Link for Caveats ")

* In React 18, `render` was replaced by [`createRoot`.](/reference/react-dom/client/createRoot) Please use `createRoot` for React 18 and beyond.

* The first time you call `render`, React will clear all the existing HTML content inside the `domNode` before rendering the React component into it. If your `domNode` contains HTML generated by React on the server or during the build, use [`hydrate()`](/reference/react-dom/hydrate) instead, which attaches the event handlers to the existing HTML.

* If you call `render` on the same `domNode` more than once, React will update the DOM as necessary to reflect the latest JSX you passed. React will decide which parts of the DOM can be reused and which need to be recreated by [“matching it up”](/learn/preserving-and-resetting-state) with the previously rendered tree. Calling `render` on the same `domNode` again is similar to calling the [`set` function](/reference/react/useState#setstate) on the root component: React avoids unnecessary DOM updates.

* If your app is fully built with React, you’ll likely have only one `render` call in your app. (If you use a framework, it might do this call for you.) When you want to render a piece of JSX in a different part of the DOM tree that isn’t a child of your component (for example, a modal or a tooltip), use [`createPortal`](/reference/react-dom/createPortal) instead of `render`.

***

## Usage[](#usage "Link for Usage ")

Call `render` to display a React component inside a browser DOM node.

```
import { render } from 'react-dom';

import App from './App.js';



render(<App />, document.getElementById('root'));
```

### Rendering the root component[](#rendering-the-root-component "Link for Rendering the root component ")

In apps fully built with React, **you will usually only do this once at startup**—to render the “root” component.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?parameters=N4IgZglgNgpgziAXKOAnAxgeggOwCYwAeAdAFYLIjoD2OALjPUiBALYAO1qdABAOTFMcOgE9YcYujhw-AbgA6ONp249gPVIwKoeAXx5hU1Vv00BDdHQC0eY3MXKuvAILt2BoyYGZX7MjIUcRU18GFQACgAeXx5MAD4AGh5bdABXVkY6YgBzGDoAUVgM-gAhEQBJPHC-I2o6PgBKBsCQBJY4EtwzVBEkMDMoOBhdNvYLAGszXP9aJFAaekzmYEUeHnkQHDMMjcR1kHNLYgIANw2E1f2TsLgIWl39gAZiZ8fzy43WM1wHjaEMbChEjkd44NYbODoVAQdh0OAPFZgtb7YTdOi_A4wCzWSHQ2FwHio7ig5H7ABGqWgeAxhxxUJhcJ4FKpJORGwYwhpWMsVlxDIJHN4VisjBOAF5yLZWKzwSAYKQYJYudjefT8Tx5Yr0SBLiMPiACOwtIx0BB4AjLrLaRiAHoARgAHC8XjL9rSbMZbY7nW9Wpa3dy6Xi4baAKw-ja6i5IjanAAiMCNoRwpvNSDUukUula7U6Wx6fQGQxGIHYqTJUAgWFwBBIAAs6KwoHMqLQGExECBIgBCOMAeQAwgAVACaAAV8jwG024opItOoDwoGYcNkxRtGBtZzh51i8Nu1pEMnQzDx0HXukM6OuQABVIcAMSsDq3lyPeVPWwyN5OZoA7io2pnm2mQ3n-EB4HQdZiqcVYwFY4GQXWSS4BAdAQAMqoDDAYp2i6IAHjwkToXQsBxHG1BpMUdCRJgJFkXOmB1nu26RGS1B4CIhGRHgEAnDwEE3rU2pxLRvEnKxmDsZxkkLnEOYQB0XQFog_SDMMbRoFgvj-C2CztnQzBEIByQwP0qRQLwYCpCm6G0DwvjhA0aiXJodCpKgYLznacQABIwFAUDUEkf5cFAeDdrRdY-YEmY4ApSn5r0qlFhpIBaUIojiJI0h6SBHYgAAVC5SLsYQvIQAAXrg2R7OxqDaFYZWxYoijSSIJVrGAbZWP0rDQCIexwCucC8mEEBgIEaxfKg2S4HsABMjzsIQU08GMeC8aueyPC1QQ4NFnU8DNc04FYdDUOwO1rd19AVZVMCLQtK17YodYLUdJ24Odl3XZct04lVj08EtL1Zq1B0AMyfd0p0_VdPC7f9PW3A9eyOmDOBxW9AAsMOzd9F0I0jSIA_dwN2gAbJj2MHaG-Nw0Tf2kyjQPozjNMQ3WlMM4Tv2IzdrNozwdrPat4P7TQBBHWTqMU8QC0wKwr04BZR0bVt2RWLglY4PBRJ0Ity3i1jEMJXm3TJWpxYlgwHDLgwzBQliDBWO6ZhuCAuhAA\&query=file%3D%252Fsrc%252Findex.js%26utm_medium%3Dsandpack\&environment=create-react-app "Open in CodeSandbox")

```
import './styles.css';
import { render } from 'react-dom';
import App from './App.js';

render(<App />, document.getElementById('root'));
```

Usually you shouldn’t need to call `render` again or to call it in more places. From this point on, React will be managing the DOM of your application. To update the UI, your components will [use state.](/reference/react/useState)

***

### Rendering multiple roots[](#rendering-multiple-roots "Link for Rendering multiple roots ")

If your page [isn’t fully built with React](/learn/add-react-to-an-existing-project#using-react-for-a-part-of-your-existing-page), call `render` for each top-level piece of UI managed by React.

```
import './styles.css';
import { render } from 'react-dom';
import { Comments, Navigation } from './Components.js';

render(
  <Navigation />,
  document.getElementById('navigation')
);

render(
  <Comments />,
  document.getElementById('comments')
);
```

You can destroy the rendered trees with [`unmountComponentAtNode()`.](/reference/react-dom/unmountComponentAtNode)

***

### Updating the rendered tree[](#updating-the-rendered-tree "Link for Updating the rendered tree ")

You can call `render` more than once on the same DOM node. As long as the component tree structure matches up with what was previously rendered, React will [preserve the state.](/learn/preserving-and-resetting-state) Notice how you can type in the input, which means that the updates from repeated `render` calls every second are not destructive:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?parameters=N4IgZglgNgpgziAXKOAnAxgeggOwCYwAeAdAFYLIjoD2OALjPUiBALYAO1qdABMD6kYFUPAL48wqaqx4ByQQEN0dALR5psgNwAdHG07c5xTHDoBPWHGLo4cLbv1deAQXbsJUmbOOv2ZOzo4urC8EDwAvDwADIFwMHQAkvQwqABuClAAFJkAlBEAfHy6PAJCKZnFJTwAPL48NACuyajhwBDimPkANJUl6ugNrIx0xADm8QCisEP0AEJmCXiZ8tTUdLI5lTmBJRAA1HuBol08AIxRF9u6IF0scLO4CqhmSGAZcccg7EoA1grj_loSFANGSTEQIGAlW0IBwCiGMMQPBhimUxAIqRhPRwJRhqRScAgtERyJAUWI5KiWOhIFYClwJJhJgw2HwRH81JxpLg6FQEHYdDgJKhXNxIFMTzojJAqNUPL5ArgPAl3E5VVJACMGtA8NLZSp5fzBTwtTq1VUYQxTHqYEo5byjUqrbwVCpGKlwuR1KxzWKYKQYMobXaDQ7FTx_YGpSBKscaQR2GUcOgIPBhb1SbLpQA9U4ADgpFN9mdtyjU0hz-cLVJuGZRpftCsFOYArNWYbHsWKMQARGCJtnJ1NCpB8US6UQ3O4POHPV7vGCfdgNDVQCBYXAEEgACzorCgwKotAY4JA1QAhD2APIAYQAKgBNAAKEx4u_3-V01XfUB4UAUOCjOEMKMDCn44N-tp4OBJTVEMdAKPU25PHEdDASAACqd4AGIqHmYGVHB8SIXCQzoakqYAO4GNG9THsM6GURAeB0Nu4QYuuMAqExLHbicuAQHQEAZKGGQwOEpxFiAME1EJdCwPkPbUAMMx0NUmByQpX6YNuUHgdUGrUHgZgydUeAQKkPDMehUhrGB6nmak-mYIZxnOT--RThA9yPHOiBvFAHy3GgWC-P4h6giedDMEQNE8AQbwNFAvBgE0yhEjiviZMAjTNKIeQiiUgh0A0qA4hUoo1DJ6rfqc-QABIwFAUDUCclFcFAeDnnwuUMKgojqdudUZrBuDLrw7D_ugMDbtQnUpOhd5mImyrSPE264KMb4pDAMI8J0GbqTJVw4OOOBeT5s4vP5C6fCFJjmJY1i2BF9GngAVEUXKGYQBoQAAXptSKGagwgqD9Ry6LorlmF9JRgMeKhvKw0BmEicAAXABopBAYA7DwdKoKMuBIgATFE7CEPj3x4OZgFIjEE5QzgQ1wwTTzEzgKh0NQ7AM_jCP0H9_0wGTpOU5DQQs6TbOE5z3O8_zlSC3KAOizw5MS0zUvbgAzLLHO4ArfPRALiOEiLSL5lrp3M9uAAsBtE0bPMm4zXIq8L6unAAbDbZ26NuLZO_LrtKx75tq1b9v-3bPshy7ium8rkeW2c4tU9rug0AQbOexb3vEKTMCsJLuhJWzNN06MKi4GuOBcSqdBkxTme21LF0zk810BR8nwMBw_4MMwvK2gwKj6gobggKIQA\&query=file%3D%252Fsrc%252Findex.js%26utm_medium%3Dsandpack\&environment=create-react-app "Open in CodeSandbox")

```
import { render } from 'react-dom';
import './styles.css';
import App from './App.js';

let i = 0;
setInterval(() => {
  render(
    <App counter={i} />,
    document.getElementById('root')
  );
  i++;
}, 1000);
```

It is uncommon to call `render` multiple times. Usually, you’ll [update state](/reference/react/useState) inside your components instead.

[PreviouspreloadModule](/reference/react-dom/preloadModule)

[NextunmountComponentAtNode](/reference/react-dom/unmountComponentAtNode)

***

----
url: https://18.react.dev/learn/render-and-commit
----

[Fork](https://codesandbox.io/api/v1/sandboxes/define?parameters=N4IgZglgNgpgziAXKOAnAxgeggOwCYwAeAdAFYLIjoD2OALjPUiBALYAO1qdABAJKsAhgHMYPMKmqseAcmKYBImGTgyA3AB0cbTtx7Ae6VDEEMAStWq8AvuMnSZxwejoBaPFMzooERnXVaWjQ4cLySVjwAvIZO5pZ0ABQe6ACurH7EonQAorDp9ABCAJ58eAmO8TIAlFVa4XTExvgwqAkAPIqiPJgAfFWaOCAANCxwBbiCqEVIYIJQcDDWI-zOANZKKrRIoMEMTIggwFo8PBogOILpZ4inIE4uxAQAbmdDx7dPLXAQtNe3AAzEQH_V7vM5CXB_M6YNBYXAEEjkUE4E5nOBGCDsOhwP5HFEnW6hSZ0KF3EwuVzo1CY7E8IncZEE24AIxS0DwpPubipNLgPFZ7MZBLODFCnPJ3IxWL5ot4rlcjCekXIHlYQtRIBgpBgLnFzkl1OlPC1OpJIHeSzBIAI7EYBBw6F8OKQ-neGq5pIAegBGAAcQKB6tuXPcUi9foDIOGbuDEspUuxXoArJGzha3vizs8ACIwW3NB1O3HWLTWYajcYXKYzOYLJYgdgpZk-OHNEgACzorCg2yotD2dGYbQAhNmAPIAYQAKgBNAAK2R4ne7PS0bWXUB4UEEOGEkTOjDOq5w65MeGPJza6TogkM7cmCzo-5AAFUpwAxVy-o_vK8wG88Bc6TPk8vgAO66Gahj9n4z5gRAeB0O2kTPBA6AwK48GIe2Qw8LgEB0BAczxnMMCRN6gYgBePBtIRdCwD02bUKk-R0G0mB0Qxa6YO2Z7Hm0zLUHgRTUW0eAQE8eF4M-9RHux4lPPxmCCcJSkbj05YQGMEzVogszzIsIywgoQiiCova7H4zBEJBPAELMKRQLwYApA6hG0PwpkwAkVSuvixh0CkqAogkMZtGwwgxicsLPp2dDsHAiCYNgxARUFxA0KwmAAFrvgAbHA3oAJwAExkOwkXmviTJzE-ZwyO-UBcHMWk8AA4owACX1LoIIMj8kUPDZHgKSTB4PATqYcw7tQNy3sIEDCDuhHoDw15zC24hNWBLR0qkUBYkFYjwUhPDGGAsAuBJYi2je8xptV3TUf0pZaJp2lVtMem1oZIDGaERSwHAGVwBQOwwfsIAAFR-ScgmEJSEAAF64MINyCagBCoK48MDCWOBaCpg14icYD9q4sysNARQ3HAO5wJSLQQGAAwnEIqALTgNwlf87CEKzPArHg4m7jc_x44EODtt6sNrZMnOuHQ1DsGLAtk_QiNIzA3MlXzEsE1LJWy-zCtKyrPDi-86vcsj2s8DzeuvQb7YAMzG_LuCK8rqtW-T3xazcfqOzg-NaO2AAs7sc57Zs-_i1ua3b3p5cHodS0mUem97Ftq37tuB-HqeS-2eWZzH2eW_HecBzw3q6_zTtBEJYgk-I1dJ8QJUwKw-taI5stCyLwiuLgPg4Bh9J0NzvMNyHkvvZWkxffpdb1gwHDbgwzBGCYDCuCGgjsOwIDWEAA\&query=file%3D%252Fsrc%252Findex.js%26utm_medium%3Dsandpack\&environment=create-react-app "Open in CodeSandbox")

```
import Image from './Image.js';
import { createRoot } from 'react-dom/client';

const root = createRoot(document.getElementById('root'))
root.render(<Image />);
```

```
export default function Gallery() {
  return (
    <section>
      <h1>Inspiring Sculptures</h1>
      <Image />
      <Image />
      <Image />
    </section>
  );
}

function Image() {
  return (
    <img
      src="https://i.imgur.com/ZF6s192.jpg"
      alt="'Floralis Genérica' by Eduardo Catalano: a gigantic metallic flower sculpture with reflective petals"
    />
  );
}
```

```
export default function Clock({ time }) {
  return (
    <>
      <h1>{time}</h1>
      <input />
    </>
  );
}
```

***

----
url: https://legacy.reactjs.org/docs/addons.html
----

> Note:
>
> `React.addons` entry point is deprecated as of React v15.5. The add-ons have moved to separate modules, and some of them have been deprecated.

The React add-ons are a collection of useful utility modules for building React apps. **These should be considered experimental** and tend to change more often than the core.

* [`createFragment`](/docs/create-fragment.html), to create a set of externally-keyed children.

The add-ons below are in the development (unminified) version of React only:

* [`Perf`](/docs/perf.html), a performance profiling tool for finding optimization opportunities.
* [`ReactTestUtils`](/docs/test-utils.html), simple helpers for writing test cases.

### [](#legacy-add-ons)Legacy Add-ons

The add-ons below are considered legacy and their use is discouraged. They will keep working in observable future, but there is no further development.

* [`PureRenderMixin`](/docs/pure-render-mixin.html). Use [`React.PureComponent`](/docs/react-api.html#reactpurecomponent) instead.
* [`shallowCompare`](/docs/shallow-compare.html), a helper function that performs a shallow comparison for props and state in a component to decide if a component should update. We recommend using [`React.PureComponent`](/docs/react-api.html#reactpurecomponent) instead.
* [`update`](/docs/update.html). Use [`kolodny/immutability-helper`](https://github.com/kolodny/immutability-helper) instead.
* [`ReactDOMFactories`](https://www.npmjs.com/package/react-dom-factories), pre-configured DOM factories to make React easier to use without JSX.

### [](#deprecated-add-ons)Deprecated Add-ons

* [`LinkedStateMixin`](/docs/two-way-binding-helpers.html) has been deprecated.
* [`TransitionGroup` and `CSSTransitionGroup`](/docs/animation.html) have been deprecated in favor of [their drop-in replacements](https://github.com/reactjs/react-transition-group/tree/v1-stable).

## [](#using-react-with-add-ons)Using React with Add-ons

You can install the add-ons individually from npm (e.g. `npm install react-addons-create-fragment`) and import them:

```
import createFragment from 'react-addons-create-fragment'; // ES6
var createFragment = require('react-addons-create-fragment'); // ES5 with npm
```

When using React 15 or earlier from a CDN, you can use `react-with-addons.js` instead of `react.js`:

```
<script src="https://unpkg.com/react@15/dist/react-with-addons.js"></script>
```

The add-ons will be available via the `React.addons` global (e.g. `React.addons.TestUtils`).

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/addons.md)

----
url: https://react.dev/reference/react/startTransition
----

[API Reference](/reference/react)

[APIs](/reference/react/apis)

# startTransition[](#undefined "Link for this heading")

`startTransition` lets you render a part of the UI in the background.

```
startTransition(action)
```

* [Reference](#reference)
  * [`startTransition(action)`](#starttransition)
* [Usage](#usage)
  * [Marking a state update as a non-blocking Transition](#marking-a-state-update-as-a-non-blocking-transition)

***

## Reference[](#reference "Link for Reference ")

### `startTransition(action)`[](#starttransition "Link for this heading")

The `startTransition` function lets you mark a state update as a Transition.

```
import { startTransition } from 'react';



function TabContainer() {

  const [tab, setTab] = useState('about');



  function selectTab(nextTab) {

    startTransition(() => {

      setTab(nextTab);

    });

  }

  // ...

}
```

[See more examples below.](#usage)

#### Parameters[](#parameters "Link for Parameters ")

* `action`: A function that updates some state by calling one or more [`set` functions](/reference/react/useState#setstate). React calls `action` immediately with no parameters and marks all state updates scheduled synchronously during the `action` function call as Transitions. Any async calls awaited in the `action` will be included in the transition, but currently require wrapping any `set` functions after the `await` in an additional `startTransition` (see [Troubleshooting](/reference/react/useTransition#react-doesnt-treat-my-state-update-after-await-as-a-transition)). State updates marked as Transitions will be [non-blocking](#marking-a-state-update-as-a-non-blocking-transition) and [will not display unwanted loading indicators.](/reference/react/useTransition#preventing-unwanted-loading-indicators).

#### Returns[](#returns "Link for Returns ")

`startTransition` does not return anything.

#### Caveats[](#caveats "Link for Caveats ")

* `startTransition` does not provide a way to track whether a Transition is pending. To show a pending indicator while the Transition is ongoing, you need [`useTransition`](/reference/react/useTransition) instead.

* You can wrap an update into a Transition only if you have access to the `set` function of that state. If you want to start a Transition in response to some prop or a custom Hook return value, try [`useDeferredValue`](/reference/react/useDeferredValue) instead.

* The function you pass to `startTransition` is called immediately, marking all state updates that happen while it executes as Transitions. If you try to perform state updates in a `setTimeout`, for example, they won’t be marked as Transitions.

* You must wrap any state updates after any async requests in another `startTransition` to mark them as Transitions. This is a known limitation that we will fix in the future (see [Troubleshooting](/reference/react/useTransition#react-doesnt-treat-my-state-update-after-await-as-a-transition)).

* A state update marked as a Transition will be interrupted by other state updates. For example, if you update a chart component inside a Transition, but then start typing into an input while the chart is in the middle of a re-render, React will restart the rendering work on the chart component after handling the input state update.

* Transition updates can’t be used to control text inputs.

* If there are multiple ongoing Transitions, React currently batches them together. This is a limitation that may be removed in a future release.

***

## Usage[](#usage "Link for Usage ")

### Marking a state update as a non-blocking Transition[](#marking-a-state-update-as-a-non-blocking-transition "Link for Marking a state update as a non-blocking Transition ")

You can mark a state update as a *Transition* by wrapping it in a `startTransition` call:

```
import { startTransition } from 'react';



function TabContainer() {

  const [tab, setTab] = useState('about');



  function selectTab(nextTab) {

    startTransition(() => {

      setTab(nextTab);

    });

  }

  // ...

}
```

***

----
url: https://18.react.dev/reference/react-dom/components/script
----

[API Reference](/reference/react)

[Components](/reference/react-dom/components)

# \<script>[](#undefined "Link for this heading")

### Canary

React’s extensions to `<script>` are currently only available in React’s canary and experimental channels. In stable releases of React `<script>` works only as a [built-in browser HTML component](https://react.dev/reference/react-dom/components#all-html-components). Learn more about [React’s release channels here](/community/versioning-policy#all-release-channels).

The [built-in browser `<script>` component](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script) lets you add a script to your document.

```
<script> alert("hi!") </script>
```

* [Reference](#reference)
  * [`<script>`](#script)

* [Usage](#usage)

  * [Rendering an external script](#rendering-an-external-script)
  * [Rendering an inline script](#rendering-an-inline-script)

***

## Reference[](#reference "Link for Reference ")

### `<script>`[](#script "Link for this heading")

To add inline or external scripts to your document, render the [built-in browser `<script>` component](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script). You can render `<script>` from any component and React will [in certain cases](#special-rendering-behavior) place the corresponding DOM element in the document head and de-duplicate identical scripts.

```
<script> alert("hi!") </script>

<script src="script.js" />
```

[See more examples below.](#usage)

#### Props[](#props "Link for Props ")

`<script>` supports all [common element props.](/reference/react-dom/components/common#props)

***

## Usage[](#usage "Link for Usage ")

### Rendering an external script[](#rendering-an-external-script "Link for Rendering an external script ")

If a component depends on certain scripts in order to be displayed correctly, you can render a `<script>` within the component. However, the component might be committed before the script has finished loading. You can start depending on the script content once the `load` event is fired e.g. by using the `onLoad` prop.

React will de-duplicate scripts that have the same `src`, inserting only one of them into the DOM even if multiple components render it.

```
import ShowRenderedHTML from './ShowRenderedHTML.js';

function Map({lat, long}) {
  return (
    <>
      <script async src="map-api.js" onLoad={() => console.log('script loaded')} />
      <div id="map" data-lat={lat} data-long={long} />
    </>
  );
}

export default function Page() {
  return (
    <ShowRenderedHTML>
      <Map />
    </ShowRenderedHTML>
  );
}
```

### Note

When you want to use a script, it can be beneficial to call the [preinit](/reference/react-dom/preinit) function. Calling this function may allow the browser to start fetching the script earlier than if you just render a `<script>` component, for example by sending an [HTTP Early Hints response](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/103).

### Rendering an inline script[](#rendering-an-inline-script "Link for Rendering an inline script ")

To include an inline script, render the `<script>` component with the script source code as its children. Inline scripts are not de-duplicated or moved to the document `<head>`.

```
import ShowRenderedHTML from './ShowRenderedHTML.js';

function Tracking() {
  return (
    <script>
      ga('send', 'pageview');
    </script>
  );
}

export default function Page() {
  return (
    <ShowRenderedHTML>
      <h1>My Website</h1>
      <Tracking />
      <p>Welcome</p>
    </ShowRenderedHTML>
  );
}
```

[Previous\<meta>](/reference/react-dom/components/meta)

[Next\<style>](/reference/react-dom/components/style)

***

----
url: https://18.react.dev/reference/rsc/server-components
----

[API Reference](/reference/react)

# React Server Components[](#undefined "Link for this heading")

While React Server Components in React 19 are stable and will not break between major versions, the underlying APIs used to implement a React Server Components bundler or framework do not follow semver and may break between minors in React 19.x.

To support React Server Components as a bundler or framework, we recommend pinning to a specific React version, or using the Canary release. We will continue working with bundlers and frameworks to stabilize the APIs used to implement React Server Components in the future.

### Server Components without a Server[](#server-components-without-a-server "Link for Server Components without a Server ")

Server components can run at build time to read from the filesystem or fetch static content, so a web server is not required. For example, you may want to read static data from a content management system.

Without Server Components, it’s common to fetch static data on the client with an Effect:

```
// bundle.js

import marked from 'marked'; // 35.9K (11.2K gzipped)

import sanitizeHtml from 'sanitize-html'; // 206K (63.3K gzipped)



function Page({page}) {

  const [content, setContent] = useState('');

  // NOTE: loads *after* first page render.

  useEffect(() => {

    fetch(`/api/content/${page}`).then((data) => {

      setContent(data.content);

    });

  }, [page]);

  

  return <div>{sanitizeHtml(marked(content))}</div>;

}
```

```
// api.js

app.get(`/api/content/:page`, async (req, res) => {

  const page = req.params.page;

  const content = await file.readFile(`${page}.md`);

  res.send({content});

});
```

This pattern means users need to download and parse an additional 75K (gzipped) of libraries, and wait for a second request to fetch the data after the page loads, just to render static content that will not change for the lifetime of the page.

With Server Components, you can render these components once at build time:

```
import marked from 'marked'; // Not included in bundle

import sanitizeHtml from 'sanitize-html'; // Not included in bundle



async function Page({page}) {

  // NOTE: loads *during* render, when the app is built.

  const content = await file.readFile(`${page}.md`);

  

  return <div>{sanitizeHtml(marked(content))}</div>;

}
```

The rendered output can then be server-side rendered (SSR) to HTML and uploaded to a CDN. When the app loads, the client will not see the original `Page` component, or the expensive libraries for rendering the markdown. The client will only see the rendered output:

```
<div><!-- html for markdown --></div>
```

This means the content is visible during first page load, and the bundle does not include the expensive libraries needed to render the static content.

### Note

You may notice that the Server Component above is an async function:

```
async function Page({page}) {

  //...

}
```

Async Components are a new feature of Server Components that allow you to `await` in render.

See [Async components with Server Components](#async-components-with-server-components) below.

### Server Components with a Server[](#server-components-with-a-server "Link for Server Components with a Server ")

Server Components can also run on a web server during a request for a page, letting you access your data layer without having to build an API. They are rendered before your application is bundled, and can pass data and JSX as props to Client Components.

Without Server Components, it’s common to fetch dynamic data on the client in an Effect:

```
// bundle.js

function Note({id}) {

  const [note, setNote] = useState('');

  // NOTE: loads *after* first render.

  useEffect(() => {

    fetch(`/api/notes/${id}`).then(data => {

      setNote(data.note);

    });

  }, [id]);

  

  return (

    <div>

      <Author id={note.authorId} />

      <p>{note}</p>

    </div>

  );

}



function Author({id}) {

  const [author, setAuthor] = useState('');

  // NOTE: loads *after* Note renders.

  // Causing an expensive client-server waterfall.

  useEffect(() => {

    fetch(`/api/authors/${id}`).then(data => {

      setAuthor(data.author);

    });

  }, [id]);



  return <span>By: {author.name}</span>;

}
```

```
// api

import db from './database';



app.get(`/api/notes/:id`, async (req, res) => {

  const note = await db.notes.get(id);

  res.send({note});

});



app.get(`/api/authors/:id`, async (req, res) => {

  const author = await db.authors.get(id);

  res.send({author});

});
```

With Server Components, you can read the data and render it in the component:

```
import db from './database';



async function Note({id}) {

  // NOTE: loads *during* render.

  const note = await db.notes.get(id);

  return (

    <div>

      <Author id={note.authorId} />

      <p>{note}</p>

    </div>

  );

}



async function Author({id}) {

  // NOTE: loads *after* Note,

  // but is fast if data is co-located.

  const author = await db.authors.get(id);

  return <span>By: {author.name}</span>;

}
```

The bundler then combines the data, rendered Server Components and dynamic Client Components into a bundle. Optionally, that bundle can then be server-side rendered (SSR) to create the initial HTML for the page. When the page loads, the browser does not see the original `Note` and `Author` components; only the rendered output is sent to the client:

```
<div>

  <span>By: The React Team</span>

  <p>React 19 is...</p>

</div>
```

Server Components can be made dynamic by re-fetching them from a server, where they can access the data and render again. This new application architecture combines the simple “request/response” mental model of server-centric Multi-Page Apps with the seamless interactivity of client-centric Single-Page Apps, giving you the best of both worlds.

### Adding interactivity to Server Components[](#adding-interactivity-to-server-components "Link for Adding interactivity to Server Components ")

Server Components are not sent to the browser, so they cannot use interactive APIs like `useState`. To add interactivity to Server Components, you can compose them with Client Component using the `"use client"` directive.

### Note

#### There is no directive for Server Components.[](#there-is-no-directive-for-server-components "Link for There is no directive for Server Components. ")

A common misunderstanding is that Server Components are denoted by `"use server"`, but there is no directive for Server Components. The `"use server"` directive is used for Server Actions.

For more info, see the docs for [Directives](/reference/rsc/directives).

In the following example, the `Notes` Server Component imports an `Expandable` Client Component that uses state to toggle its `expanded` state:

```
// Server Component

import Expandable from './Expandable';



async function Notes() {

  const notes = await db.notes.getAll();

  return (

    <div>

      {notes.map(note => (

        <Expandable key={note.id}>

          <p note={note} />

        </Expandable>

      ))}

    </div>

  )

}
```

```
// Client Component

"use client"



export default function Expandable({children}) {

  const [expanded, setExpanded] = useState(false);

  return (

    <div>

      <button

        onClick={() => setExpanded(!expanded)}

      >

        Toggle

      </button>

      {expanded && children}

    </div>

  )

}
```

This works by first rendering `Notes` as a Server Component, and then instructing the bundler to create a bundle for the Client Component `Expandable`. In the browser, the Client Components will see output of the Server Components passed as props:

```
<head>

  <!-- the bundle for Client Components -->

  <script src="bundle.js" />

</head>

<body>

  <div>

    <Expandable key={1}>

      <p>this is the first note</p>

    </Expandable>

    <Expandable key={2}>

      <p>this is the second note</p>

    </Expandable>

    <!--...-->

  </div> 

</body>
```

### Async components with Server Components[](#async-components-with-server-components "Link for Async components with Server Components ")

Server Components introduce a new way to write Components using async/await. When you `await` in an async component, React will suspend and wait for the promise to resolve before resuming rendering. This works across server/client boundaries with streaming support for Suspense.

You can even create a promise on the server, and await it on the client:

```
// Server Component

import db from './database';



async function Page({id}) {

  // Will suspend the Server Component.

  const note = await db.notes.get(id);

  

  // NOTE: not awaited, will start here and await on the client. 

  const commentsPromise = db.comments.get(note.id);

  return (

    <div>

      {note}

      <Suspense fallback={<p>Loading Comments...</p>}>

        <Comments commentsPromise={commentsPromise} />

      </Suspense>

    </div>

  );

}
```

```
// Client Component

"use client";

import {use} from 'react';



function Comments({commentsPromise}) {

  // NOTE: this will resume the promise from the server.

  // It will suspend until the data is available.

  const comments = use(commentsPromise);

  return comments.map(commment => <p>{comment}</p>);

}
```

The `note` content is important data for the page to render, so we `await` it on the server. The comments are below the fold and lower-priority, so we start the promise on the server, and wait for it on the client with the `use` API. This will Suspend on the client, without blocking the `note` content from rendering.

Since async components are [not supported on the client](#why-cant-i-use-async-components-on-the-client), we await the promise with `use`.

[NextServer Actions](/reference/rsc/server-actions)

***

----
url: https://legacy.reactjs.org/blog/2017/11/28/react-v16.2.0-fragment-support.html
----

November 28, 2017 by [Clement Hoang](https://twitter.com/c8hoang)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

React 16.2 is now available! The biggest addition is improved support for returning multiple children from a component’s render method. We call this feature *fragments*:

Fragments look like empty JSX tags. They let you group a list of children without adding extra nodes to the DOM:

```
render() {
  return (
    <>
      <ChildA />
      <ChildB />
      <ChildC />
    </>
  );
}
```

This exciting new feature is made possible by additions to both React and JSX.

## [](#what-are-fragments)What Are Fragments?

A common pattern is for a component to return a list of children. Take this example HTML:

```
Some text.
<h2>A heading</h2>
More text.
<h2>Another heading</h2>
Even more text.
```

Prior to version 16, the only way to achieve this in React was by wrapping the children in an extra element, usually a `div` or `span`:

```
render() {
  return (
    // Extraneous div element :(
    <div>
      Some text.
      <h2>A heading</h2>
      More text.
      <h2>Another heading</h2>
      Even more text.
    </div>
  );
}
```

To address this limitation, React 16.0 added support for [returning an array of elements from a component’s `render` method](/blog/2017/09/26/react-v16.0.html#new-render-return-types-fragments-and-strings). Instead of wrapping the children in a DOM element, you can put them into an array:

```
render() {
 return [
  "Some text.",
  <h2 key="heading-1">A heading</h2>,
  "More text.",
  <h2 key="heading-2">Another heading</h2>,
  "Even more text."
 ];
}
```

However, this has some confusing differences from normal JSX:

* Children in an array must be separated by commas.
* Children in an array must have a key to prevent React’s [key warning](/docs/lists-and-keys.html#keys).
* Strings must be wrapped in quotes.

To provide a more consistent authoring experience for fragments, React now provides a first-class `Fragment` component that can be used in place of arrays.

```
render() {
  return (
    <Fragment>      Some text.
      <h2>A heading</h2>
      More text.
      <h2>Another heading</h2>
      Even more text.
    </Fragment>  );
}
```

You can use `<Fragment />` the same way you’d use any other element, without changing the way you write JSX. No commas, no keys, no quotes.

The Fragment component is available on the main React object:

```
const Fragment = React.Fragment;

<Fragment>
  <ChildA />
  <ChildB />
  <ChildC />
</Fragment>

// This also works
<React.Fragment>
  <ChildA />
  <ChildB />
  <ChildC />
</React.Fragment>
```

## [](#jsx-fragment-syntax)JSX Fragment Syntax

Fragments are a common pattern in our codebases at Facebook. We anticipate they’ll be widely adopted by other teams, too. To make the authoring experience as convenient as possible, we’re adding syntactical support for fragments to JSX:

```
render() {
  return (
    <>      Some text.
      <h2>A heading</h2>
      More text.
      <h2>Another heading</h2>
      Even more text.
    </>  );
}
```

In React, this desugars to a `<React.Fragment/>` element, as in the example from the previous section. (Non-React frameworks that use JSX may compile to something different.)

Fragment syntax in JSX was inspired by prior art such as the `XMLList() <></>` constructor in [E4X](https://web.archive.org/web/20201019115828/https://developer.mozilla.org/en-US/docs/Archive/Web/E4X/E4X_for_templating). Using a pair of empty tags is meant to represent the idea it won’t add an actual element to the DOM.

### [](#keyed-fragments)Keyed Fragments

Note that the `<></>` syntax does not accept attributes, including keys.

If you need a keyed fragment, you can use `<Fragment />` directly. A use case for this is mapping a collection to an array of fragments — for example, to create a description list:

```
function Glossary(props) {
  return (
    <dl>
      {props.items.map(item => (
        // Without the `key`, React will fire a key warning
        <Fragment key={item.id}>
          <dt>{item.term}</dt>
          <dd>{item.description}</dd>
        </Fragment>
      ))}
    </dl>
  );
}
```

`key` is the only attribute that can be passed to `Fragment`. In the future, we may add support for additional attributes, such as event handlers.

### [](#live-demo)Live Demo

You can experiment with JSX fragment syntax with this [CodePen](https://codepen.io/reactjs/pen/VrEbjE?editors=1000).

## [](#support-for-fragment-syntax)Support for Fragment Syntax

Support for fragment syntax in JSX will vary depending on the tools you use to build your app. Please be patient as the JSX community works to adopt the new syntax. We’ve been working closely with maintainers of the most popular projects:

### [](#create-react-app)Create React App

Experimental support for fragment syntax will be added to Create React App within the next few days. A stable release may take a bit longer as we await adoption by upstream projects.

### [](#babel)Babel

Support for JSX fragments is available in [Babel v7.0.0-beta.31](https://github.com/babel/babel/releases/tag/v7.0.0-beta.31) and above! If you are already on Babel 7, simply update to the latest Babel and plugin transform:

```
# for yarn users
yarn upgrade @babel/core @babel/plugin-transform-react-jsx
# for npm users
npm update @babel/core @babel/plugin-transform-react-jsx
```

Or if you are using the [react preset](https://www.npmjs.com/package/@babel/preset-react):

```
# for yarn users
yarn upgrade @babel/core @babel/preset-react
# for npm users
npm update @babel/core @babel/preset-react
```

Note that Babel 7 is technically still in beta, but a [stable release is coming soon](https://babeljs.io/blog/2017/09/12/planning-for-7.0).

Unfortunately, support for Babel 6.x is not available, and there are currently no plans to backport.

#### [](#babel-with-webpack-babel-loader)Babel with Webpack (babel-loader)

If you are using Babel with [Webpack](https://webpack.js.org/), no additional steps are needed because [babel-loader](https://github.com/babel/babel-loader) will use your peer-installed version of Babel.

#### [](#babel-with-other-frameworks)Babel with Other Frameworks

If you use JSX with a non-React framework like Inferno or Preact, there is a [pragma option available in babel-plugin-transform-react-jsx](https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-react-jsx#pragmafrag) that configures the Babel compiler to de-sugar the `<></>` syntax to a custom identifier.

### [](#typescript)TypeScript

TypeScript has full support for fragment syntax! Please upgrade to [version 2.6.2](https://github.com/Microsoft/TypeScript/releases/tag/v2.6.2). (Note that this is important even if you are already on version 2.6.1, since support was added as patch release in 2.6.2.)

Upgrade to the latest TypeScript with the command:

```
# for yarn users
yarn upgrade typescript
# for npm users
npm update typescript
```

### [](#flow)Flow

[Flow](https://flow.org/) support for JSX fragments is available starting in [version 0.59](https://github.com/facebook/flow/releases/tag/v0.59.0)! Simply run

```
# for yarn users
yarn upgrade flow-bin
# for npm users
npm update flow-bin
```

to update Flow to the latest version.

### [](#prettier)Prettier

[Prettier](https://github.com/prettier/prettier) added support for fragments in their [1.9 release](https://prettier.io/blog/2017/12/05/1.9.0.html#jsx-fragment-syntax-3237-https-githubcom-prettier-prettier-pull-3237-by-duailibe-https-githubcom-duailibe).

### [](#eslint)ESLint

JSX Fragments are supported by [ESLint](https://eslint.org/) 3.x when it is used together with [babel-eslint](https://github.com/babel/babel-eslint):

```
# for yarn users
yarn add eslint@3.x babel-eslint@7
# for npm users
npm install eslint@3.x babel-eslint@7
```

or if you already have it, then upgrade:

```
# for yarn users
yarn upgrade eslint@3.x babel-eslint@7
# for npm users
npm update eslint@3.x babel-eslint@7
```

Ensure you have the following line inside your `.eslintrc`:

```
"parser": "babel-eslint"
```

That’s it!

Note that `babel-eslint` is not officially supported by ESLint. We’ll be looking into adding support for fragments to ESLint 4.x itself in the coming weeks (see [issue #9662](https://github.com/eslint/eslint/issues/9662)).

### [](#editor-support)Editor Support

It may take a while for fragment syntax to be supported in your text editor. Please be patient as the community works to adopt the latest changes. In the meantime, you may see errors or inconsistent highlighting if your editor does not yet support fragment syntax. Generally, these errors can be safely ignored.

#### [](#typescript-editor-support)TypeScript Editor Support

If you’re a TypeScript user — great news! Editor support for JSX fragments is already available in [Visual Studio 2015](https://www.microsoft.com/en-us/download/details.aspx?id=48593), [Visual Studio 2017](https://www.microsoft.com/en-us/download/details.aspx?id=55258), [Visual Studio Code](https://code.visualstudio.com/updates/v1_19#_jsx-fragment-syntax) and [Sublime Text via Package Control](https://packagecontrol.io/packages/TypeScript).

### [](#other-tools)Other Tools

For other tools, please check with the corresponding documentation to check if there is support available. However, if you’re blocked by your tooling, you can always start with using the `<Fragment>` component and perform a codemod later to replace it with the shorthand syntax when the appropriate support is available.

## [](#installation)Installation

React v16.2.0 is available on the npm registry.

To install React 16 with Yarn, run:

```
yarn add react@^16.2.0 react-dom@^16.2.0
```

To install React 16 with npm, run:

```
npm install --save react@^16.2.0 react-dom@^16.2.0
```

We also provide UMD builds of React via a CDN:

```
<script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
```

Refer to the documentation for [detailed installation instructions](/docs/installation.html).

## [](#changelog)Changelog

### [](#react)React

* Add `Fragment` as named export to React. ([@clemmy](https://github.com/clemmy) in [#10783](https://github.com/facebook/react/pull/10783))
* Support experimental Call/Return types in `React.Children` utilities. ([@MatteoVH](https://github.com/MatteoVH) in [#11422](https://github.com/facebook/react/pull/11422))

### [](#react-dom)React DOM

* Fix radio buttons not getting checked when using multiple lists of radios. ([@landvibe](https://github.com/landvibe) in [#11227](https://github.com/facebook/react/pull/11227))
* Fix radio buttons not receiving the `onChange` event in some cases. ([@jquense](https://github.com/jquense) in [#11028](https://github.com/facebook/react/pull/11028))

### [](#react-test-renderer)React Test Renderer

* Fix `setState()` callback firing too early when called from `componentWillMount`. ([@accordeiro](https://github.com/accordeiro) in [#11507](https://github.com/facebook/react/pull/11507))

### [](#react-reconciler)React Reconciler

* Expose `react-reconciler/reflection` with utilities useful to custom renderers. ([@rivenhk](https://github.com/rivenhk) in [#11683](https://github.com/facebook/react/pull/11683))

### [](#internal-changes)Internal Changes

* Many tests were rewritten against the public API. Big thanks to [everyone who contributed](https://github.com/facebook/react/issues/11299)!

## [](#acknowledgments)Acknowledgments

This release was made possible by our open source contributors. A big thanks to everyone who filed issues, contributed to syntax discussions, reviewed pull requests, added support for JSX fragments in third party libraries, and more!

Special thanks to the [TypeScript](https://www.typescriptlang.org/) and [Flow](https://flow.org/) teams, as well as the [Babel](https://babeljs.io/) maintainers, who helped make tooling support for the new syntax go seamlessly.

Thanks to [Gajus Kuizinas](https://github.com/gajus/) and other contributors who prototyped the `Fragment` component in open source.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2017-11-28-react-v16.2.0-fragment-support.md)

----
url: https://legacy.reactjs.org/blog/2014/03/19/react-v0.10-rc1.html
----

March 19, 2014 by [Paul O’Shannessy](https://twitter.com/zpao)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

[v0.9 has only been out for a month](/blog/2014/02/20/react-v0.9.html), but we’re getting ready to push out v0.10 already. Unlike v0.9 which took a long time, we don’t have a long list of changes to talk about.

The release candidate is available for download from the CDN:

* **React**\
  Dev build with warnings: <https://fb.me/react-0.10.0-rc1.js>\
  Minified build for production: <https://fb.me/react-0.10.0-rc1.min.js>
* **React with Add-Ons**\
  Dev build with warnings: <https://fb.me/react-with-addons-0.10.0-rc1.js>\
  Minified build for production: <https://fb.me/react-with-addons-0.10.0-rc1.min.js>
* **In-Browser JSX transformer**\
  <https://fb.me/JSXTransformer-0.10.0-rc1.js>

We’ve also published version `0.10.0-rc1` of the `react` and `react-tools` packages on npm and the `react` package on bower.

Please try these builds out and [file an issue on GitHub](https://github.com/facebook/react/issues/new) if you see anything awry.

## [](#clone-on-mount)Clone On Mount

The main purpose of this release is to provide a smooth upgrade path as we evolve some of the implementation of core. In v0.9 we started warning in cases where you called methods on unmounted components. This is part of an effort to enforce the idea that the return value of a component (`React.DOM.div()`, `MyComponent()`) is in fact not a reference to the component instance React uses in the virtual DOM. The return value is instead a light-weight object that React knows how to use. Since the return value currently is a reference to the same object React uses internally, we need to make this transition in stages as many people have come to depend on this implementation detail.

In 0.10, we’re adding more warnings to catch a similar set of patterns. When a component is mounted we clone it and use that object for our internal representation. This allows us to capture calls you think you’re making to a mounted component. We’ll forward them on to the right object, but also warn you that this is breaking. See “Access to the Mounted Instance” on [this page](https://fb.me/react-warning-descriptors). Most of the time you can solve your pattern by using refs.

Storing a reference to your top level component is a pattern touched upon on that page, but another examples that demonstrates what we see a lot of:

```
// This is a common pattern. However instance here really refers to a
// "descriptor", not necessarily the mounted instance.
var instance = <MyComponent/>;
React.renderComponent(instance);
// ...
instance.setProps(...);

// The change here is very simple. The return value of renderComponent will be
// the mounted instance.
var instance = React.renderComponent(<MyComponent/>)
// ...
instance.setProps(...);
```

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2014-03-19-react-v0.10-rc1.md)

----
url: https://react.dev/reference/react-dom/components/style
----

[API Reference](/reference/react)

[Components](/reference/react-dom/components)

# \<style>[](#undefined "Link for this heading")

The [built-in browser `<style>` component](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/style) lets you add inline CSS stylesheets to your document.

```
<style>{` p { color: red; } `}</style>
```

* [Reference](#reference)
  * [`<style>`](#style)
* [Usage](#usage)
  * [Rendering an inline CSS stylesheet](#rendering-an-inline-css-stylesheet)

***

## Reference[](#reference "Link for Reference ")

### `<style>`[](#style "Link for this heading")

To add inline styles to your document, render the [built-in browser `<style>` component](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/style). You can render `<style>` from any component and React will [in certain cases](#special-rendering-behavior) place the corresponding DOM element in the document head and de-duplicate identical styles.

```
<style>{` p { color: red; } `}</style>
```

[See more examples below.](#usage)

#### Props[](#props "Link for Props ")

`<style>` supports all [common element props.](/reference/react-dom/components/common#common-props)

This special treatment comes with three caveats:

* React will ignore changes to props after the style has been rendered. (React will issue a warning in development if this happens.)
* React will drop all extraneous props when using the `precedence` prop (beyond `href` and `precedence`).
* React may leave the style in the DOM even after the component that rendered it has been unmounted.

***

## Usage[](#usage "Link for Usage ")

### Rendering an inline CSS stylesheet[](#rendering-an-inline-css-stylesheet "Link for Rendering an inline CSS stylesheet ")

If a component depends on certain CSS styles in order to be displayed correctly, you can render an inline stylesheet within the component.

The `href` prop should uniquely identify the stylesheet, because React will de-duplicate stylesheets that have the same `href`. If you supply a `precedence` prop, React will reorder inline stylesheets based on the order these values appear in the component tree.

Inline stylesheets will not trigger Suspense boundaries while they’re loading. Even if they load async resources like fonts or images.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import ShowRenderedHTML from './ShowRenderedHTML.js';
import { useId } from 'react';

function PieChart({data, colors}) {
  const id = useId();
  const stylesheet = colors.map((color, index) =>
    `#${id} .color-${index}: \{ color: "${color}"; \}`
  ).join();
  return (
    <>
      <style href={"PieChart-" + JSON.stringify(colors)} precedence="medium">
        {stylesheet}
      </style>
      <svg id={id}>
        …
      </svg>
    </>
  );
}

export default function App() {
  return (
    <ShowRenderedHTML>
      <PieChart data="..." colors={['red', 'green', 'blue']} />
    </ShowRenderedHTML>
  );
}
```

[Previous\<script>](/reference/react-dom/components/script)

[Next\<title>](/reference/react-dom/components/title)

***

----
url: https://18.react.dev/reference/react-dom/flushSync
----

[API Reference](/reference/react)

[APIs](/reference/react-dom)

# flushSync[](#undefined "Link for this heading")

### Pitfall

Using `flushSync` is uncommon and can hurt the performance of your app.

`flushSync` lets you force React to flush any updates inside the provided callback synchronously. This ensures that the DOM is updated immediately.

```
flushSync(callback)
```

* [Reference](#reference)
  * [`flushSync(callback)`](#flushsync)
* [Usage](#usage)
  * [Flushing updates for third-party integrations](#flushing-updates-for-third-party-integrations)

***

## Reference[](#reference "Link for Reference ")

### `flushSync(callback)`[](#flushsync "Link for this heading")

Call `flushSync` to force React to flush any pending work and update the DOM synchronously.

```
import { flushSync } from 'react-dom';



flushSync(() => {

  setSomething(123);

});
```

***

## Usage[](#usage "Link for Usage ")

### Flushing updates for third-party integrations[](#flushing-updates-for-third-party-integrations "Link for Flushing updates for third-party integrations ")

When integrating with third-party code such as browser APIs or UI libraries, it may be necessary to force React to flush updates. Use `flushSync` to force React to flush any state updates inside the callback synchronously:

```
flushSync(() => {

  setSomething(123);

});

// By this line, the DOM is updated.
```

This ensures that, by the time the next line of code runs, React has already updated the DOM.

**Using `flushSync` is uncommon, and using it often can significantly hurt the performance of your app.** If your app only uses React APIs, and does not integrate with third-party libraries, `flushSync` should be unnecessary.

However, it can be helpful for integrating with third-party code like browser APIs.

Some browser APIs expect results inside of callbacks to be written to the DOM synchronously, by the end of the callback, so the browser can do something with the rendered DOM. In most cases, React handles this for you automatically. But in some cases it may be necessary to force a synchronous update.

For example, the browser `onbeforeprint` API allows you to change the page immediately before the print dialog opens. This is useful for applying custom print styles that allow the document to display better for printing. In the example below, you use `flushSync` inside of the `onbeforeprint` callback to immediately “flush” the React state to the DOM. Then, by the time the print dialog opens, `isPrinting` displays “yes”:

```
import { useState, useEffect } from 'react';
import { flushSync } from 'react-dom';

export default function PrintApp() {
  const [isPrinting, setIsPrinting] = useState(false);

  useEffect(() => {
    function handleBeforePrint() {
      flushSync(() => {
        setIsPrinting(true);
      })
    }

    function handleAfterPrint() {
      setIsPrinting(false);
    }

    window.addEventListener('beforeprint', handleBeforePrint);
    window.addEventListener('afterprint', handleAfterPrint);
    return () => {
      window.removeEventListener('beforeprint', handleBeforePrint);
      window.removeEventListener('afterprint', handleAfterPrint);
    }
  }, []);

  return (
    <>
      <h1>isPrinting: {isPrinting ? 'yes' : 'no'}</h1>
      <button onClick={() => window.print()}>
        Print
      </button>
    </>
  );
}
```

Without `flushSync`, the print dialog will display `isPrinting` as “no”. This is because React batches the updates asynchronously and the print dialog is displayed before the state is updated.

### Pitfall

`flushSync` can significantly hurt performance, and may unexpectedly force pending Suspense boundaries to show their fallback state.

Most of the time, `flushSync` can be avoided, so use `flushSync` as a last resort.

[PreviouscreatePortal](/reference/react-dom/createPortal)

[NextfindDOMNode](/reference/react-dom/findDOMNode)

***

----
url: https://18.react.dev/community/videos
----

[Community](/community)

# React Videos[](#undefined "Link for this heading")

Videos dedicated to the discussion of React and the React ecosystem.

***

----
url: https://react.dev/learn/reacting-to-input-with-state
----

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
async function handleFormSubmit(e) {
  e.preventDefault();
  disable(textarea);
  disable(button);
  show(loadingMessage);
  hide(errorMessage);
  try {
    await submitForm(textarea.value);
    show(successMessage);
    hide(form);
  } catch (err) {
    show(errorMessage);
    errorMessage.textContent = err.message;
  } finally {
    hide(loadingMessage);
    enable(textarea);
    enable(button);
  }
}

function handleTextareaChange() {
  if (textarea.value.length === 0) {
    disable(button);
  } else {
    enable(button);
  }
}

function hide(el) {
  el.style.display = 'none';
}

function show(el) {
  el.style.display = '';
}

function enable(el) {
  el.disabled = false;
}

function disable(el) {
  el.disabled = true;
}

function submitForm(answer) {
  // Pretend it's hitting the network.
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (answer.toLowerCase() === 'istanbul') {
        resolve();
      } else {
        reject(new Error('Good guess but a wrong answer. Try again!'));
      }
    }, 1500);
  });
}

let form = document.getElementById('form');
let textarea = document.getElementById('textarea');
let button = document.getElementById('button');
let loadingMessage = document.getElementById('loading');
let errorMessage = document.getElementById('error');
let successMessage = document.getElementById('success');
form.onsubmit = handleFormSubmit;
textarea.oninput = handleTextareaChange;
```

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
export default function Form({
  status = 'empty'
}) {
  if (status === 'success') {
    return <h1>That's right!</h1>
  }
  return (
    <>
      <h2>City quiz</h2>
      <p>
        In which city is there a billboard that turns air into drinkable water?
      </p>
      <form>
        <textarea />
        <br />
        <button>
          Submit
        </button>
      </form>
    </>
  )
}
```

You could call that prop anything you like, the naming is not important. Try editing `status = 'empty'` to `status = 'success'` to see the success message appear. Mocking lets you quickly iterate on the UI before you wire up any logic. Here is a more fleshed out prototype of the same component, still “controlled” by the `status` prop:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
export default function Form({
  // Try 'submitting', 'error', 'success':
  status = 'empty'
}) {
  if (status === 'success') {
    return <h1>That's right!</h1>
  }
  return (
    <>
      <h2>City quiz</h2>
      <p>
        In which city is there a billboard that turns air into drinkable water?
      </p>
      <form>
        <textarea disabled={
          status === 'submitting'
        } />
        <br />
        <button disabled={
          status === 'empty' ||
          status === 'submitting'
        }>
          Submit
        </button>
        {status === 'error' &&
          <p className="Error">
            Good guess but a wrong answer. Try again!
          </p>
        }
      </form>
      </>
  );
}
```

##### Deep Dive#### Displaying many visual states at once[](#displaying-many-visual-states-at-once "Link for Displaying many visual states at once ")

If a component has a lot of visual states, it can be convenient to show them all on one page:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import Form from './Form.js';

let statuses = [
  'empty',
  'typing',
  'submitting',
  'success',
  'error',
];

export default function App() {
  return (
    <>
      {statuses.map(status => (
        <section key={status}>
          <h4>Form ({status}):</h4>
          <Form status={status} />
        </section>
      ))}
    </>
  );
}
```

```
const [answer, setAnswer] = useState('');

const [error, setError] = useState(null);
```

Then, you’ll need a state variable representing which one of the visual states that you want to display. There’s usually more than a single way to represent that in memory, so you’ll need to experiment with it.

If you struggle to think of the best way immediately, start by adding enough state that you’re *definitely* sure that all the possible visual states are covered:

```
const [isEmpty, setIsEmpty] = useState(true);

const [isTyping, setIsTyping] = useState(false);

const [isSubmitting, setIsSubmitting] = useState(false);

const [isSuccess, setIsSuccess] = useState(false);

const [isError, setIsError] = useState(false);
```

```
const [answer, setAnswer] = useState('');

const [error, setError] = useState(null);

const [status, setStatus] = useState('typing'); // 'typing', 'submitting', or 'success'
```

You know they are essential, because you can’t remove any of them without breaking the functionality.

##### Deep Dive#### Eliminating “impossible” states with a reducer[](#eliminating-impossible-states-with-a-reducer "Link for Eliminating “impossible” states with a reducer ")

These three variables are a good enough representation of this form’s state. However, there are still some intermediate states that don’t fully make sense. For example, a non-null `error` doesn’t make sense when `status` is `'success'`. To model the state more precisely, you can [extract it into a reducer.](/learn/extracting-state-logic-into-a-reducer) Reducers let you unify multiple state variables into a single object and consolidate all the related logic!

### Step 5: Connect the event handlers to set state[](#step-5-connect-the-event-handlers-to-set-state "Link for Step 5: Connect the event handlers to set state ")

Lastly, create event handlers that update the state. Below is the final form, with all event handlers wired up:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function Form() {
  const [answer, setAnswer] = useState('');
  const [error, setError] = useState(null);
  const [status, setStatus] = useState('typing');

  if (status === 'success') {
    return <h1>That's right!</h1>
  }

  async function handleSubmit(e) {
    e.preventDefault();
    setStatus('submitting');
    try {
      await submitForm(answer);
      setStatus('success');
    } catch (err) {
      setStatus('typing');
      setError(err);
    }
  }

  function handleTextareaChange(e) {
    setAnswer(e.target.value);
  }

  return (
    <>
      <h2>City quiz</h2>
      <p>
        In which city is there a billboard that turns air into drinkable water?
      </p>
      <form onSubmit={handleSubmit}>
        <textarea
          value={answer}
          onChange={handleTextareaChange}
          disabled={status === 'submitting'}
        />
        <br />
        <button disabled={
          answer.length === 0 ||
          status === 'submitting'
        }>
          Submit
        </button>
        {error !== null &&
          <p className="Error">
            {error.message}
          </p>
        }
      </form>
    </>
  );
}

function submitForm(answer) {
  // Pretend it's hitting the network.
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      let shouldError = answer.toLowerCase() !== 'lima'
      if (shouldError) {
        reject(new Error('Good guess but a wrong answer. Try again!'));
      } else {
        resolve();
      }
    }, 1500);
  });
}
```

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
export default function Picture() {
  return (
    <div className="background background--active">
      <img
        className="picture"
        alt="Rainbow houses in Kampung Pelangi, Indonesia"
        src="https://react.dev/images/docs/scientists/5qwVYb1.jpeg"
      />
    </div>
  );
}
```

[PreviousManaging State](/learn/managing-state)

[NextChoosing the State Structure](/learn/choosing-the-state-structure)

***

----
url: https://18.react.dev/reference/react/useDebugValue
----

[API Reference](/reference/react)

[Hooks](/reference/react/hooks)

# useDebugValue[](#undefined "Link for this heading")

`useDebugValue` is a React Hook that lets you add a label to a custom Hook in [React DevTools.](/learn/react-developer-tools)

```
useDebugValue(value, format?)
```

* [Reference](#reference)
  * [`useDebugValue(value, format?)`](#usedebugvalue)

* [Usage](#usage)

  * [Adding a label to a custom Hook](#adding-a-label-to-a-custom-hook)
  * [Deferring formatting of a debug value](#deferring-formatting-of-a-debug-value)

***

## Reference[](#reference "Link for Reference ")

### `useDebugValue(value, format?)`[](#usedebugvalue "Link for this heading")

Call `useDebugValue` at the top level of your [custom Hook](/learn/reusing-logic-with-custom-hooks) to display a readable debug value:

```
import { useDebugValue } from 'react';



function useOnlineStatus() {

  // ...

  useDebugValue(isOnline ? 'Online' : 'Offline');

  // ...

}
```

```
import { useDebugValue } from 'react';



function useOnlineStatus() {

  // ...

  useDebugValue(isOnline ? 'Online' : 'Offline');

  // ...

}
```

This gives components calling `useOnlineStatus` a label like `OnlineStatus: "Online"` when you inspect them:

Without the `useDebugValue` call, only the underlying data (in this example, `true`) would be displayed.

```
import { useSyncExternalStore, useDebugValue } from 'react';

export function useOnlineStatus() {
  const isOnline = useSyncExternalStore(subscribe, () => navigator.onLine, () => true);
  useDebugValue(isOnline ? 'Online' : 'Offline');
  return isOnline;
}

function subscribe(callback) {
  window.addEventListener('online', callback);
  window.addEventListener('offline', callback);
  return () => {
    window.removeEventListener('online', callback);
    window.removeEventListener('offline', callback);
  };
}
```

### Note

Don’t add debug values to every custom Hook. It’s most valuable for custom Hooks that are part of shared libraries and that have a complex internal data structure that’s difficult to inspect.

***

### Deferring formatting of a debug value[](#deferring-formatting-of-a-debug-value "Link for Deferring formatting of a debug value ")

You can also pass a formatting function as the second argument to `useDebugValue`:

```
useDebugValue(date, date => date.toDateString());
```

Your formatting function will receive the debug value as a parameter and should return a formatted display value. When your component is inspected, React DevTools will call this function and display its result.

This lets you avoid running potentially expensive formatting logic unless the component is actually inspected. For example, if `date` is a Date value, this avoids calling `toDateString()` on it for every render.

[PrevioususeContext](/reference/react/useContext)

[NextuseDeferredValue](/reference/react/useDeferredValue)

***

----
url: https://legacy.reactjs.org/docs/events.html
----

> These docs are old and won’t be updated. Go to [react.dev](https://react.dev/) for the new React docs.
>
> These new documentation pages teach modern React and include live examples:
>
> * [Common components (e.g. `<div>`)](https://react.dev/reference/react-dom/components/common)

This reference guide documents the `SyntheticEvent` wrapper that forms part of React’s Event System. See the [Handling Events](/docs/handling-events.html) guide to learn more.

## [](#overview)Overview

Your event handlers will be passed instances of `SyntheticEvent`, a cross-browser wrapper around the browser’s native event. It has the same interface as the browser’s native event, including `stopPropagation()` and `preventDefault()`, except the events work identically across all browsers.

If you find that you need the underlying browser event for some reason, simply use the `nativeEvent` attribute to get it. The synthetic events are different from, and do not map directly to, the browser’s native events. For example in `onMouseLeave` `event.nativeEvent` will point to a `mouseout` event. The specific mapping is not part of the public API and may change at any time. Every `SyntheticEvent` object has the following attributes:

```
boolean bubbles
boolean cancelable
DOMEventTarget currentTarget
boolean defaultPrevented
number eventPhase
boolean isTrusted
DOMEvent nativeEvent
void preventDefault()
boolean isDefaultPrevented()
void stopPropagation()
boolean isPropagationStopped()
void persist()
DOMEventTarget target
number timeStamp
string type
```

> Note:
>
> As of v17, `e.persist()` doesn’t do anything because the `SyntheticEvent` is no longer [pooled](/docs/legacy-event-pooling.html).

> Note:
>
> As of v0.14, returning `false` from an event handler will no longer stop event propagation. Instead, `e.stopPropagation()` or `e.preventDefault()` should be triggered manually, as appropriate.

## [](#supported-events)Supported Events

React normalizes events so that they have consistent properties across different browsers.

The event handlers below are triggered by an event in the bubbling phase. To register an event handler for the capture phase, append `Capture` to the event name; for example, instead of using `onClick`, you would use `onClickCapture` to handle the click event in the capture phase.

* [Clipboard Events](#clipboard-events)
* [Composition Events](#composition-events)
* [Keyboard Events](#keyboard-events)
* [Focus Events](#focus-events)
* [Form Events](#form-events)
* [Generic Events](#generic-events)
* [Mouse Events](#mouse-events)
* [Pointer Events](#pointer-events)
* [Selection Events](#selection-events)
* [Touch Events](#touch-events)
* [UI Events](#ui-events)
* [Wheel Events](#wheel-events)
* [Media Events](#media-events)
* [Image Events](#image-events)
* [Animation Events](#animation-events)
* [Transition Events](#transition-events)
* [Other Events](#other-events)

***

## [](#reference)Reference

### [](#clipboard-events)Clipboard Events

Event names:

```
onCopy onCut onPaste
```

Properties:

```
DOMDataTransfer clipboardData
```

***

### [](#composition-events)Composition Events

Event names:

```
onCompositionEnd onCompositionStart onCompositionUpdate
```

Properties:

```
string data
```

***

### [](#keyboard-events)Keyboard Events

Event names:

```
onKeyDown onKeyPress onKeyUp
```

Properties:

```
boolean altKey
number charCode
boolean ctrlKey
boolean getModifierState(key)
string key
number keyCode
string locale
number location
boolean metaKey
boolean repeat
boolean shiftKey
number which
```

The `key` property can take any of the values documented in the [DOM Level 3 Events spec](https://www.w3.org/TR/uievents-key/#named-key-attribute-values).

***

### [](#focus-events)Focus Events

Event names:

```
onFocus onBlur
```

These focus events work on all elements in the React DOM, not just form elements.

Properties:

```
DOMEventTarget relatedTarget
```

#### [](#onfocus)onFocus

The `onFocus` event is called when the element (or some element inside of it) receives focus. For example, it’s called when the user clicks on a text input.

```
function Example() {
  return (
    <input
      onFocus={(e) => {
        console.log('Focused on input');
      }}
      placeholder="onFocus is triggered when you click this input."
    />
  )
}
```

#### [](#onblur)onBlur

The `onBlur` event handler is called when focus has left the element (or left some element inside of it). For example, it’s called when the user clicks outside of a focused text input.

```
function Example() {
  return (
    <input
      onBlur={(e) => {
        console.log('Triggered because this input lost focus');
      }}
      placeholder="onBlur is triggered when you click this input and then you click outside of it."
    />
  )
}
```

#### [](#detecting-focus-entering-and-leaving)Detecting Focus Entering and Leaving

You can use the `currentTarget` and `relatedTarget` to differentiate if the focusing or blurring events originated from *outside* of the parent element. Here is a demo you can copy and paste that shows how to detect focusing a child, focusing the element itself, and focus entering or leaving the whole subtree.

```
function Example() {
  return (
    <div
      tabIndex={1}
      onFocus={(e) => {
        if (e.currentTarget === e.target) {
          console.log('focused self');
        } else {
          console.log('focused child', e.target);
        }
        if (!e.currentTarget.contains(e.relatedTarget)) {
          // Not triggered when swapping focus between children
          console.log('focus entered self');
        }
      }}
      onBlur={(e) => {
        if (e.currentTarget === e.target) {
          console.log('unfocused self');
        } else {
          console.log('unfocused child', e.target);
        }
        if (!e.currentTarget.contains(e.relatedTarget)) {
          // Not triggered when swapping focus between children
          console.log('focus left self');
        }
      }}
    >
      <input id="1" />
      <input id="2" />
    </div>
  );
}
```

***

### [](#form-events)Form Events

Event names:

```
onChange onInput onInvalid onReset onSubmit 
```

For more information about the onChange event, see [Forms](/docs/forms.html).

***

### [](#generic-events)Generic Events

Event names:

```
onError onLoad
```

***

### [](#mouse-events)Mouse Events

Event names:

```
onClick onContextMenu onDoubleClick onDrag onDragEnd onDragEnter onDragExit
onDragLeave onDragOver onDragStart onDrop onMouseDown onMouseEnter onMouseLeave
onMouseMove onMouseOut onMouseOver onMouseUp
```

The `onMouseEnter` and `onMouseLeave` events propagate from the element being left to the one being entered instead of ordinary bubbling and do not have a capture phase.

Properties:

```
boolean altKey
number button
number buttons
number clientX
number clientY
boolean ctrlKey
boolean getModifierState(key)
boolean metaKey
number pageX
number pageY
DOMEventTarget relatedTarget
number screenX
number screenY
boolean shiftKey
```

***

### [](#pointer-events)Pointer Events

Event names:

```
onPointerDown onPointerMove onPointerUp onPointerCancel onGotPointerCapture
onLostPointerCapture onPointerEnter onPointerLeave onPointerOver onPointerOut
```

The `onPointerEnter` and `onPointerLeave` events propagate from the element being left to the one being entered instead of ordinary bubbling and do not have a capture phase.

Properties:

As defined in the [W3 spec](https://www.w3.org/TR/pointerevents/), pointer events extend [Mouse Events](#mouse-events) with the following properties:

```
number pointerId
number width
number height
number pressure
number tangentialPressure
number tiltX
number tiltY
number twist
string pointerType
boolean isPrimary
```

A note on cross-browser support:

Pointer events are not yet supported in every browser (at the time of writing this article, supported browsers include: Chrome, Firefox, Edge, and Internet Explorer). React deliberately does not polyfill support for other browsers because a standard-conform polyfill would significantly increase the bundle size of `react-dom`.

If your application requires pointer events, we recommend adding a third party pointer event polyfill.

***

### [](#selection-events)Selection Events

Event names:

```
onSelect
```

***

### [](#touch-events)Touch Events

Event names:

```
onTouchCancel onTouchEnd onTouchMove onTouchStart
```

Properties:

```
boolean altKey
DOMTouchList changedTouches
boolean ctrlKey
boolean getModifierState(key)
boolean metaKey
boolean shiftKey
DOMTouchList targetTouches
DOMTouchList touches
```

***

### [](#ui-events)UI Events

Event names:

```
onScroll
```

> Note
>
> Starting with React 17, the `onScroll` event **does not bubble** in React. This matches the browser behavior and prevents the confusion when a nested scrollable element fires events on a distant parent.

Properties:

```
number detail
DOMAbstractView view
```

***

### [](#wheel-events)Wheel Events

Event names:

```
onWheel
```

Properties:

```
number deltaMode
number deltaX
number deltaY
number deltaZ
```

***

### [](#media-events)Media Events

Event names:

```
onAbort onCanPlay onCanPlayThrough onDurationChange onEmptied onEncrypted
onEnded onError onLoadedData onLoadedMetadata onLoadStart onPause onPlay
onPlaying onProgress onRateChange onSeeked onSeeking onStalled onSuspend
onTimeUpdate onVolumeChange onWaiting
```

***

### [](#image-events)Image Events

Event names:

```
onLoad onError
```

***

### [](#animation-events)Animation Events

Event names:

```
onAnimationStart onAnimationEnd onAnimationIteration
```

Properties:

```
string animationName
string pseudoElement
float elapsedTime
```

***

### [](#transition-events)Transition Events

Event names:

```
onTransitionEnd
```

Properties:

```
string propertyName
string pseudoElement
float elapsedTime
```

***

### [](#other-events)Other Events

Event names:

```
onToggle
```

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/reference-events.md)

----
url: https://legacy.reactjs.org/blog/2017/04/07/react-v15.5.0.html
----

April 07, 2017 by [Andrew Clark](https://twitter.com/acdlite)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

It’s been exactly one year since the last breaking change to React. Our next major release, React 16, will include some exciting improvements, including a [complete rewrite](https://www.youtube.com/watch?v=ZCuYPiUIONs) of React’s internals. [We take stability seriously](/docs/design-principles.html#stability), and are committed to bringing those improvements to all of our users with minimal effort.

To that end, today we’re releasing React 15.5.0.

### [](#new-deprecation-warnings)New Deprecation Warnings

The biggest change is that we’ve extracted `React.PropTypes` and `React.createClass` into their own packages. Both are still accessible via the main `React` object, but using either will log a one-time deprecation warning to the console when in development mode. This will enable future code size optimizations.

These warnings will not affect the behavior of your application. However, we realize they may cause some frustration, particularly if you use a testing framework that treats `console.error` as a failure.

**Adding new warnings is not something we do lightly.** Warnings in React are not mere suggestions — they are integral to our strategy of keeping as many people as possible on the latest version of React. We never add warnings without providing an incremental path forward.

So while the warnings may cause frustration in the short-term, we believe **prodding developers to migrate their codebases now prevents greater frustration in the future**. Proactively fixing warnings ensures you are prepared for the next major release. If your app produces zero warnings in 15.5, it should continue to work in 16 without any changes.

For each of these new deprecations, we’ve provided a codemod to automatically migrate your code. They are available as part of the [react-codemod](https://github.com/reactjs/react-codemod) project.

### [](#migrating-from-reactproptypes)Migrating from React.PropTypes

Prop types are a feature for runtime validation of props during development. We’ve extracted the built-in prop types to a separate package to reflect the fact that not everybody uses them.

In 15.5, instead of accessing `PropTypes` from the main `React` object, install the `prop-types` package and import them from there:

```
// Before (15.4 and below)
import React from 'react';

class Component extends React.Component {
  render() {
    return <div>{this.props.text}</div>;
  }
}

Component.propTypes = {
  text: React.PropTypes.string.isRequired,}

// After (15.5)
import React from 'react';
import PropTypes from 'prop-types';
class Component extends React.Component {
  render() {
    return <div>{this.props.text}</div>;
  }
}

Component.propTypes = {
  text: PropTypes.string.isRequired,};
```

The [codemod](https://github.com/reactjs/react-codemod#react-proptypes-to-prop-types) for this change performs this conversion automatically. Basic usage:

```
jscodeshift -t react-codemod/transforms/React-PropTypes-to-prop-types.js <path>
```

The `propTypes`, `contextTypes`, and `childContextTypes` APIs will work exactly as before. The only change is that the built-in validators now live in a separate package.

You may also consider using [Flow](https://flow.org/) to statically type check your JavaScript code, including [React components](https://flow.org/en/docs/react/components/).

### [](#migrating-from-reactcreateclass)Migrating from React.createClass

When React was initially released, there was no idiomatic way to create classes in JavaScript, so we provided our own: `React.createClass`.

Later, classes were added to the language as part of ES2015, so we added the ability to create React components using JavaScript classes. **Along with function components, JavaScript classes are now the [preferred way to create components in React](/docs/components-and-props.html#functional-and-class-components).**

For your existing `createClass` components, we recommend that you migrate them to JavaScript classes. However, if you have components that rely on mixins, converting to classes may not be immediately feasible. If so, `create-react-class` is available on npm as a drop-in replacement:

```
// Before (15.4 and below)
var React = require('react');

var Component = React.createClass({  mixins: [MixinA],
  render() {
    return <Child />;
  }
});

// After (15.5)
var React = require('react');
var createReactClass = require('create-react-class');
var Component = createReactClass({  mixins: [MixinA],
  render() {
    return <Child />;
  }
});
```

Your components will continue to work the same as they did before.

The [codemod](https://github.com/reactjs/react-codemod#explanation-of-the-new-es2015-class-transform-with-property-initializers) for this change attempts to convert a `createClass` component to a JavaScript class, with a fallback to `create-react-class` if necessary. It has converted thousands of components internally at Facebook.

Basic usage:

```
jscodeshift -t react-codemod/transforms/class.js path/to/components
```

### [](#discontinuing-support-for-react-addons)Discontinuing support for React Addons

We’re discontinuing active maintenance of React Addons packages. In truth, most of these packages haven’t been actively maintained in a long time. They will continue to work indefinitely, but we recommend migrating away as soon as you can to prevent future breakages.

* **react-addons-create-fragment** – React 16 will have first-class support for fragments, at which point this package won’t be necessary. We recommend using arrays of keyed elements instead.
* **react-addons-css-transition-group** - Use [react-transition-group/CSSTransitionGroup](https://github.com/reactjs/react-transition-group) instead. Version 1.1.1 provides a drop-in replacement.
* **react-addons-linked-state-mixin** - Explicitly set the `value` and `onChange` handler instead.
* **react-addons-pure-render-mixin** - Use [`React.PureComponent`](/docs/react-api.html#reactpurecomponent) instead.
* **react-addons-shallow-compare** - Use [`React.PureComponent`](/docs/react-api.html#reactpurecomponent) instead.
* **react-addons-transition-group** - Use [react-transition-group/TransitionGroup](https://github.com/reactjs/react-transition-group) instead. Version 1.1.1 provides a drop-in replacement.
* **react-addons-update** - Use [immutability-helper](https://github.com/kolodny/immutability-helper) instead, a drop-in replacement.
* **react-linked-input** - Explicitly set the `value` and `onChange` handler instead.

We’re also discontinuing support for the `react-with-addons` UMD build. It will be removed in React 16.

### [](#react-test-utils)React Test Utils

Currently, the React Test Utils live inside `react-addons-test-utils`. As of 15.5, we’re deprecating that package and moving them to `react-dom/test-utils` instead:

```
// Before (15.4 and below)
import TestUtils from 'react-addons-test-utils';

// After (15.5)
import TestUtils from 'react-dom/test-utils';
```

This reflects the fact that what we call the Test Utils are really a set of APIs that wrap the DOM renderer.

The exception is shallow rendering, which is not DOM-specific. The shallow renderer has been moved to `react-test-renderer/shallow`.

```
// Before (15.4 and below)
import { createRenderer } from 'react-addons-test-utils';
// After (15.5)
import { createRenderer } from 'react-test-renderer/shallow';
```

***

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

## [](#acknowledgements)Acknowledgements

A special thank you to these folks for transferring ownership of npm package names:

* [Jason Miller](https://github.com/developit)
* [Aaron Ackerman](https://github.com/aackerman)
* [Vinicius Marson](https://github.com/viniciusmarson)

***

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

## [](#installation)Installation

We recommend using [Yarn](https://yarnpkg.com/) or [npm](https://www.npmjs.com/) for managing front-end dependencies. If you’re new to package managers, the [Yarn documentation](https://yarnpkg.com/en/docs/getting-started) is a good place to get started.

To install React with Yarn, run:

```
yarn add react@^15.5.0 react-dom@^15.5.0
```

To install React with npm, run:

```
npm install --save react@^15.5.0 react-dom@^15.5.0
```

We recommend using a bundler like [webpack](https://webpack.js.org/) or [Browserify](http://browserify.org/) so you can write modular code and bundle it together into small packages to optimize load time.

Remember that by default, React runs extra checks and provides helpful warnings in development mode. When deploying your app, make sure to [compile it in production mode](/docs/installation.html#development-and-production-versions).

In case you don’t use a bundler, we also provide pre-built bundles in the npm packages which you can [include as script tags](/docs/installation.html#using-a-cdn) on your page:

* **React**\
  Dev build with warnings: [react/dist/react.js](https://unpkg.com/react@15.5.0/dist/react.js)\
  Minified build for production: [react/dist/react.min.js](https://unpkg.com/react@15.5.0/dist/react.min.js)
* **React with Add-Ons**\
  Dev build with warnings: [react/dist/react-with-addons.js](https://unpkg.com/react@15.5.0/dist/react-with-addons.js)\
  Minified build for production: [react/dist/react-with-addons.min.js](https://unpkg.com/react@15.5.0/dist/react-with-addons.min.js)
* **React DOM** (include React in the page before React DOM)\
  Dev build with warnings: [react-dom/dist/react-dom.js](https://unpkg.com/react-dom@15.5.0/dist/react-dom.js)\
  Minified build for production: [react-dom/dist/react-dom.min.js](https://unpkg.com/react-dom@15.5.0/dist/react-dom.min.js)
* **React DOM Server** (include React in the page before React DOM Server)\
  Dev build with warnings: [react-dom/dist/react-dom-server.js](https://unpkg.com/react-dom@15.5.0/dist/react-dom-server.js)\
  Minified build for production: [react-dom/dist/react-dom-server.min.js](https://unpkg.com/react-dom@15.5.0/dist/react-dom-server.min.js)

We’ve also published version `15.5.0` of the `react`, `react-dom`, and addons packages on npm and the `react` package on bower.

***

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

## [](#changelog)Changelog

## [](#1550-april-7-2017)15.5.0 (April 7, 2017)

### [](#react)React

* Added a deprecation warning for `React.createClass`. Points users to create-react-class instead. ([@acdlite](https://github.com/acdlite) in [d9a4fa4](https://github.com/facebook/react/commit/d9a4fa4f51c6da895e1655f32255cf72c0fe620e))
* Added a deprecation warning for `React.PropTypes`. Points users to prop-types instead. ([@acdlite](https://github.com/acdlite) in [043845c](https://github.com/facebook/react/commit/043845ce75ea0812286bbbd9d34994bb7e01eb28))
* Fixed an issue when using `ReactDOM` together with `ReactDOMServer`. ([@wacii](https://github.com/wacii) in [#9005](https://github.com/facebook/react/pull/9005))
* Fixed issue with Closure Compiler. ([@anmonteiro](https://github.com/anmonteiro) in [#8895](https://github.com/facebook/react/pull/8895))
* Another fix for Closure Compiler. ([@Shastel](https://github.com/Shastel) in [#8882](https://github.com/facebook/react/pull/8882))
* Added component stack info to invalid element type warning. ([@n3tr](https://github.com/n3tr) in [#8495](https://github.com/facebook/react/pull/8495))

### [](#react-dom)React DOM

* Fixed Chrome bug when backspacing in number inputs. ([@nhunzaker](https://github.com/nhunzaker) in [#7359](https://github.com/facebook/react/pull/7359))
* Added `react-dom/test-utils`, which exports the React Test Utils. ([@bvaughn](https://github.com/bvaughn))

### [](#react-test-renderer)React Test Renderer

* Fixed bug where `componentWillUnmount` was not called for children. ([@gre](https://github.com/gre) in [#8512](https://github.com/facebook/react/pull/8512))
* Added `react-test-renderer/shallow`, which exports the shallow renderer. ([@bvaughn](https://github.com/bvaughn))

### [](#react-addons)React Addons

* Last release for addons; they will no longer be actively maintained.
* Removed `peerDependencies` so that addons continue to work indefinitely. ([@acdlite](https://github.com/acdlite) and [@bvaughn](https://github.com/bvaughn) in [8a06cd7](https://github.com/facebook/react/commit/8a06cd7a786822fce229197cac8125a551e8abfa) and [67a8db3](https://github.com/facebook/react/commit/67a8db3650d724a51e70be130e9008806402678a))
* Updated to remove references to `React.createClass` and `React.PropTypes` ([@acdlite](https://github.com/acdlite) in [12a96b9](https://github.com/facebook/react/commit/12a96b94823d6b6de6b1ac13bd576864abd50175))
* `react-addons-test-utils` is deprecated. Use `react-dom/test-utils` and `react-test-renderer/shallow` instead. ([@bvaughn](https://github.com/bvaughn))

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2017-04-07-react-v15.5.0.md)

----
url: https://legacy.reactjs.org/docs/hooks-custom.html
----

> These docs are old and won’t be updated. Go to [react.dev](https://react.dev/) for the new React docs.
>
> These new documentation pages teach modern React and include live examples:
>
> * [Reusing Logic with Custom Hooks](https://react.dev/learn/reusing-logic-with-custom-hooks)

*Hooks* are a new addition in React 16.8. They let you use state and other React features without writing a class.

Building your own Hooks lets you extract component logic into reusable functions.

When we were learning about [using the Effect Hook](/docs/hooks-effect.html#example-using-hooks-1), we saw this component from a chat application that displays a message indicating whether a friend is online or offline:

```
import React, { useState, useEffect } from 'react';

function FriendStatus(props) {
  const [isOnline, setIsOnline] = useState(null);  useEffect(() => {    function handleStatusChange(status) {      setIsOnline(status.isOnline);    }    ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);    return () => {      ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);    };  });
  if (isOnline === null) {
    return 'Loading...';
  }
  return isOnline ? 'Online' : 'Offline';
}
```

Now let’s say that our chat application also has a contact list, and we want to render names of online users with a green color. We could copy and paste similar logic above into our `FriendListItem` component but it wouldn’t be ideal:

```
import React, { useState, useEffect } from 'react';

function FriendListItem(props) {
  const [isOnline, setIsOnline] = useState(null);  useEffect(() => {    function handleStatusChange(status) {      setIsOnline(status.isOnline);    }    ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);    return () => {      ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);    };  });
  return (
    <li style={{ color: isOnline ? 'green' : 'black' }}>
      {props.friend.name}
    </li>
  );
}
```

Instead, we’d like to share this logic between `FriendStatus` and `FriendListItem`.

Traditionally in React, we’ve had two popular ways to share stateful logic between components: [render props](/docs/render-props.html) and [higher-order components](/docs/higher-order-components.html). We will now look at how Hooks solve many of the same problems without forcing you to add more components to the tree.

## [](#extracting-a-custom-hook)Extracting a Custom Hook

When we want to share logic between two JavaScript functions, we extract it to a third function. Both components and Hooks are functions, so this works for them too!

**A custom Hook is a JavaScript function whose name starts with ”`use`” and that may call other Hooks.** For example, `useFriendStatus` below is our first custom Hook:

```
import { useState, useEffect } from 'react';

function useFriendStatus(friendID) {  const [isOnline, setIsOnline] = useState(null);

  useEffect(() => {
    function handleStatusChange(status) {
      setIsOnline(status.isOnline);
    }

    ChatAPI.subscribeToFriendStatus(friendID, handleStatusChange);
    return () => {
      ChatAPI.unsubscribeFromFriendStatus(friendID, handleStatusChange);
    };
  });

  return isOnline;
}
```

There’s nothing new inside of it — the logic is copied from the components above. Just like in a component, make sure to only call other Hooks unconditionally at the top level of your custom Hook.

Unlike a React component, a custom Hook doesn’t need to have a specific signature. We can decide what it takes as arguments, and what, if anything, it should return. In other words, it’s just like a normal function. Its name should always start with `use` so that you can tell at a glance that the [rules of Hooks](/docs/hooks-rules.html) apply to it.

The purpose of our `useFriendStatus` Hook is to subscribe us to a friend’s status. This is why it takes `friendID` as an argument, and returns whether this friend is online:

```
function useFriendStatus(friendID) {
  const [isOnline, setIsOnline] = useState(null);

  // ...

  return isOnline;
}
```

Now let’s see how we can use our custom Hook.

## [](#using-a-custom-hook)Using a Custom Hook

In the beginning, our stated goal was to remove the duplicated logic from the `FriendStatus` and `FriendListItem` components. Both of them want to know whether a friend is online.

Now that we’ve extracted this logic to a `useFriendStatus` hook, we can *just use it:*

```
function FriendStatus(props) {
  const isOnline = useFriendStatus(props.friend.id);
  if (isOnline === null) {
    return 'Loading...';
  }
  return isOnline ? 'Online' : 'Offline';
}
```

```
function FriendListItem(props) {
  const isOnline = useFriendStatus(props.friend.id);
  return (
    <li style={{ color: isOnline ? 'green' : 'black' }}>
      {props.friend.name}
    </li>
  );
}
```

**Is this code equivalent to the original examples?** Yes, it works in exactly the same way. If you look closely, you’ll notice we didn’t make any changes to the behavior. All we did was to extract some common code between two functions into a separate function. **Custom Hooks are a convention that naturally follows from the design of Hooks, rather than a React feature.**

**Do I have to name my custom Hooks starting with “`use`”?** Please do. This convention is very important. Without it, we wouldn’t be able to automatically check for violations of [rules of Hooks](/docs/hooks-rules.html) because we couldn’t tell if a certain function contains calls to Hooks inside of it.

**Do two components using the same Hook share state?** No. Custom Hooks are a mechanism to reuse *stateful logic* (such as setting up a subscription and remembering the current value), but every time you use a custom Hook, all state and effects inside of it are fully isolated.

**How does a custom Hook get isolated state?** Each *call* to a Hook gets isolated state. Because we call `useFriendStatus` directly, from React’s point of view our component just calls `useState` and `useEffect`. And as we [learned](/docs/hooks-state.html#tip-using-multiple-state-variables) [earlier](/docs/hooks-effect.html#tip-use-multiple-effects-to-separate-concerns), we can call `useState` and `useEffect` many times in one component, and they will be completely independent.

### [](#tip-pass-information-between-hooks)Tip: Pass Information Between Hooks

Since Hooks are functions, we can pass information between them.

To illustrate this, we’ll use another component from our hypothetical chat example. This is a chat message recipient picker that displays whether the currently selected friend is online:

```
const friendList = [
  { id: 1, name: 'Phoebe' },
  { id: 2, name: 'Rachel' },
  { id: 3, name: 'Ross' },
];

function ChatRecipientPicker() {
  const [recipientID, setRecipientID] = useState(1);  const isRecipientOnline = useFriendStatus(recipientID);
  return (
    <>
      <Circle color={isRecipientOnline ? 'green' : 'red'} />      <select
        value={recipientID}
        onChange={e => setRecipientID(Number(e.target.value))}
      >
        {friendList.map(friend => (
          <option key={friend.id} value={friend.id}>
            {friend.name}
          </option>
        ))}
      </select>
    </>
  );
}
```

We keep the currently chosen friend ID in the `recipientID` state variable, and update it if the user chooses a different friend in the `<select>` picker.

Because the `useState` Hook call gives us the latest value of the `recipientID` state variable, we can pass it to our custom `useFriendStatus` Hook as an argument:

```
  const [recipientID, setRecipientID] = useState(1);
  const isRecipientOnline = useFriendStatus(recipientID);
```

This lets us know whether the *currently selected* friend is online. If we pick a different friend and update the `recipientID` state variable, our `useFriendStatus` Hook will unsubscribe from the previously selected friend, and subscribe to the status of the newly selected one.

## [](#useyourimagination)`useYourImagination()`

Custom Hooks offer the flexibility of sharing logic that wasn’t possible in React components before. You can write custom Hooks that cover a wide range of use cases like form handling, animation, declarative subscriptions, timers, and probably many more we haven’t considered. What’s more, you can build Hooks that are just as easy to use as React’s built-in features.

Try to resist adding abstraction too early. Now that function components can do more, it’s likely that the average function component in your codebase will become longer. This is normal — don’t feel like you *have to* immediately split it into Hooks. But we also encourage you to start spotting cases where a custom Hook could hide complex logic behind a simple interface, or help untangle a messy component.

For example, maybe you have a complex component that contains a lot of local state that is managed in an ad-hoc way. `useState` doesn’t make centralizing the update logic any easier so you might prefer to write it as a [Redux](https://redux.js.org/) reducer:

```
function todosReducer(state, action) {
  switch (action.type) {
    case 'add':
      return [...state, {
        text: action.text,
        completed: false
      }];
    // ... other actions ...
    default:
      return state;
  }
}
```

Reducers are very convenient to test in isolation, and scale to express complex update logic. You can further break them apart into smaller reducers if necessary. However, you might also enjoy the benefits of using React local state, or might not want to install another library.

So what if we could write a `useReducer` Hook that lets us manage the *local* state of our component with a reducer? A simplified version of it might look like this:

```
function useReducer(reducer, initialState) {
  const [state, setState] = useState(initialState);

  function dispatch(action) {
    const nextState = reducer(state, action);
    setState(nextState);
  }

  return [state, dispatch];
}
```

Now we could use it in our component, and let the reducer drive its state management:

```
function Todos() {
  const [todos, dispatch] = useReducer(todosReducer, []);
  function handleAddClick(text) {
    dispatch({ type: 'add', text });
  }

  // ...
}
```

The need to manage local state with a reducer in a complex component is common enough that we’ve built the `useReducer` Hook right into React. You’ll find it together with other built-in Hooks in the [Hooks API reference](/docs/hooks-reference.html).

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/hooks-custom.md)

* Previous article

  [Rules of Hooks](/docs/hooks-rules.html)

* Next article

  [Hooks API Reference](/docs/hooks-reference.html)

----
url: https://legacy.reactjs.org/blog/2015/03/04/community-roundup-25.html
----

March 04, 2015 by [Matthew Johnston](https://github.com/matthewathome)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

## [](#react-101)React 101

Interest in React has been exploding recently, so it’s a good time to explore some great recent tutorials and videos that cover getting started.

[Ryan Clark](https://github.com/rynclark) provides a [great overview of the basics of React](http://ryanclark.me/getting-started-with-react/) with the goal of building a really simple dropdown nav.

[Formidable Labs](https://github.com/FormidableLabs) and [Seattle JS](http://www.meetup.com/seattlejs/) recently hosted a series of React, Flux, and Flow workshops, and the first part is available to watch online:

[AEFlash](https://github.com/aearly) writes up [some best practices and tips](http://aeflash.com/2015-02/react-tips-and-best-practices.html) to help you avoid potential pitfalls when developing with React.

Black Mutt Media [takes us through their usage of React](http://blackmuttmedia.com/blog/react-tmdb-api/) and Ruby to build an autocomplete field, and some of the pitfalls they encountered along the way.

Our own [Sebastian Markbåge](https://github.com/sebmarkbage) was on the [Web Platform Podcast](http://thewebplatform.libsyn.com/31-building-with-reactjs) to have a chat about all aspects of React.

## [](#community-additions)Community Additions

[Formidable Labs](https://github.com/FormidableLabs) have been busy, as they’ve also[ just launched Radium](http://projects.formidablelabs.com/radium/), a React component that provides you with the ability to use inline styles instead of CSS. They’re also [looking for some help](http://projects.formidablelabs.com/radium-bootstrap/) contributing to a Radium Bootstrap implementation.

[Reactiflux.com](http://reactiflux.com/) is a new Slack community based around (you guessed it!) React, and Flux.

[React Week](http://reactweek.com/) is a week-long learning workshop, happening next week, for React, Flux, and other related technologies, run by [Ryan Florence](https://github.com/ryanflorence).

[Babel-sublime](https://github.com/babel/babel-sublime) is a new package which provides Sublime with language definitions for ES6 JavaScript with React JSX syntax extensions.

[react-meteor](https://github.com/reactjs/react-meteor), a package that replaces the default templating system of the Meteor platform with React, recently received a big update.

## [](#rebuilding-with-react)Rebuilding with React

[Rich Manalang](https://github.com/rmanalan) from Atlassian [explains why](https://developer.atlassian.com/blog/2015/02/rebuilding-hipchat-with-react/) they rebuilt their HipChat web client from scratch using React, and how they’re already using it to rebuild their native desktop clients.

[Andrew Hillel](https://twitter.com/andyhillel) of the BBC gives [an excellent and thorough breakdown](http://www.bbc.co.uk/blogs/internet/entries/47a96d23-ae04-444e-808f-678e6809765d) of the stack they used to rebuild their homepage, with React as an integral part of the front-end.

A team from New Zealand called [Atomic](https://atomic.io/) is [building web and mobile prototyping and design tools](http://thenextweb.com/creativity/2015/02/19/meet-atomic-missing-tool-interface-design-thats-entirely-browser/) entirely in-browser, and as co-founder [Darryl Gray](https://twitter.com/darrylgray) says, “React.js “totally changed” the fact that browser performance often wasn’t good enough for complex tools like this.”.

[Polarr](https://github.com/Polarrco) have rebuilt [their browser-based photo editor](http://polarrist.tumblr.com/post/111290422225/polarr-photo-editor-2-0-alpha-is-here) with React.

[](http://polarrist.tumblr.com/post/111290422225/polarr-photo-editor-2-0-alpha-is-here)

## [](#its-f8)It’s F8!

F8 2015 is just around the corner, and you can [sign up for the video streams](https://www.fbf8.com/stream.html) in advance because we’re sure to be covering all things React.

## [](#meetups)Meetups

|                                                                                                                                                                                                                                                                                                                                 |                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| > Our [@reactjs](https://twitter.com/reactjs) meetup is in full effect [#ReactJS](https://twitter.com/hashtag/ReactJS?src=hash) btw bathroom code is 6012 lol [pic.twitter.com/7iUpvmm3zz](http://t.co/7iUpvmm3zz)
>
> — littleBits (@littleBits) [February 25, 2015](https://twitter.com/littleBits/status/570373833028472832) | > [@yrezgui](https://twitter.com/yrezgui) captivating us with [@reactjs](https://twitter.com/reactjs) at [@DevRocketUK](https://twitter.com/DevRocketUK). Thanks to the amazing sponsors [@makersacademy](https://twitter.com/makersacademy) and [@couchbase](https://twitter.com/couchbase). [pic.twitter.com/xwA773omky](http://t.co/xwA773omky)
>
> — James Nocentini (@jamiltz) [February 24, 2015](https://twitter.com/jamiltz/status/570306188577001473) |
| > Listening to a bunch of very clever geekoids at the [@reactjs](https://twitter.com/reactjs) seminar. Nice! [pic.twitter.com/0TeTOJOerO](http://t.co/0TeTOJOerO)
>
> — Nick Middleweek (@nmiddleweek) [February 18, 2015](https://twitter.com/nmiddleweek/status/568183658395394049)                                           | > Watching the [@FrontendMasters](https://twitter.com/FrontendMasters) ReactJS workshop! [pic.twitter.com/YraYIK97Lu](http://t.co/YraYIK97Lu)
>
> — ReactJS News (@ReactJSNews) [February 13, 2015](https://twitter.com/ReactJSNews/status/566269552112041985)                                                                                                                                                                                                 |

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2015-03-04-community-roundup-25.md)

----
url: https://react.dev/blog/2025/10/07/introducing-the-react-foundation
----

[Blog](/blog)

# Introducing the React Foundation[](#undefined "Link for this heading")

October 7, 2025 by [Seth Webster](https://x.com/sethwebster), [Matt Carroll](https://x.com/mattcarrollcode), [Joe Savona](https://x.com/en_JS), [Sophie Alpert](https://x.com/sophiebits)

***

Today, we’re announcing our plans to create the React Foundation and a new technical governance structure.

***

We open sourced React over a decade ago to help developers build great user experiences. From its earliest days, React has received substantial contributions from contributors outside of Meta. Over time, the number of contributors and the scope of their contributions has grown significantly. What started out as a tool developed for Meta has expanded into a project that spans multiple companies with regular contributions from across the ecosystem. React has outgrown the confines of any one company.

To better serve the React community, we are announcing our plans to move React and React Native from Meta to a new React Foundation. As a part of this change, we will also be implementing a new independent technical governance structure. We believe these changes will enable us to give React ecosystem projects more resources.

## The React Foundation[](#the-react-foundation "Link for The React Foundation ")

We will make the React Foundation the new home for React, React Native, and some supporting projects like JSX. The React Foundation’s mission will be to support the React community and ecosystem. Once implemented, the React Foundation will

* Maintain React’s infrastructure like GitHub, CI, and trademarks
* Organize React Conf
* Create initiatives to support the React ecosystem like financial support of ecosystem projects, issuing grants, and creating programs

The React Foundation will be governed by a board of directors, with Seth Webster serving as the executive director. This board will direct funds and resources to support React’s development, community, and ecosystem. We believe that this is the best structure to ensure that the React Foundation is vendor-neutral and reflects the best interests of the community.

The founding corporate members of the React Foundation will be Amazon, Callstack, Expo, Meta, Microsoft, Software Mansion, and Vercel. These companies have had a major impact on the React and React Native ecosystems and we are grateful for their support. We are excited to welcome even more members in the future.

## React’s technical governance[](#reacts-technical-governance "Link for React’s technical governance ")

We believe that React’s technical direction should be set by the people who contribute to and maintain React. As React moves to a foundation, it is important that no single company or organization is overrepresented. To achieve this, we plan to define a new technical governance structure for React that is independent from the React Foundation.

As a part of creating React’s new technical governance structure we will reach out to the community for feedback. Once finalized, we will share details in a future post.

## Thank you[](#thank-you "Link for Thank you ")

React’s incredible growth is thanks to the thousands of people, companies, and projects that have shaped React. The creation of the React Foundation is a testament to the strength and vibrancy of the React community. Together, the React Foundation and React’s new technical governance will ensure that React’s future is secure for years to come.

[PreviousReact Compiler v1.0](/blog/2025/10/07/react-compiler-1)

[NextReact 19.2](/blog/2025/10/01/react-19-2)

***

----
url: https://react.dev/learn/passing-props-to-a-component
----

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
function Avatar() {
  return (
    <img
      className="avatar"
      src="https://react.dev/images/docs/scientists/1bX5QH6.jpg"
      alt="Lin Lanying"
      width={100}
      height={100}
    />
  );
}

export default function Profile() {
  return (
    <Avatar />
  );
}
```

The props you can pass to an `<img>` tag are predefined (ReactDOM conforms to [the HTML standard](https://www.w3.org/TR/html52/semantics-embedded-content.html#the-img-element)). But you can pass any props to *your own* components, such as `<Avatar>`, to customize them. Here’s how!

## Passing props to a component[](#passing-props-to-a-component "Link for Passing props to a component ")

In this code, the `Profile` component isn’t passing any props to its child component, `Avatar`:

```
export default function Profile() {

  return (

    <Avatar />

  );

}
```

You can give `Avatar` some props in two steps.

### Step 1: Pass props to the child component[](#step-1-pass-props-to-the-child-component "Link for Step 1: Pass props to the child component ")

First, pass some props to `Avatar`. For example, let’s pass two props: `person` (an object), and `size` (a number):

```
export default function Profile() {

  return (

    <Avatar

      person={{ name: 'Lin Lanying', imageId: '1bX5QH6' }}

      size={100}

    />

  );

}
```

### Note

If double curly braces after `person=` confuse you, recall [they’re merely an object](/learn/javascript-in-jsx-with-curly-braces#using-double-curlies-css-and-other-objects-in-jsx) inside the JSX curlies.

Now you can read these props inside the `Avatar` component.

### Step 2: Read props inside the child component[](#step-2-read-props-inside-the-child-component "Link for Step 2: Read props inside the child component ")

You can read these props by listing their names `person, size` separated by the commas inside `({` and `})` directly after `function Avatar`. This lets you use them inside the `Avatar` code, like you would with a variable.

```
function Avatar({ person, size }) {

  // person and size are available here

}
```

Add some logic to `Avatar` that uses the `person` and `size` props for rendering, and you’re done.

Now you can configure `Avatar` to render in many different ways with different props. Try tweaking the values!

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { getImageUrl } from './utils.js';

function Avatar({ person, size }) {
  return (
    <img
      className="avatar"
      src={getImageUrl(person)}
      alt={person.name}
      width={size}
      height={size}
    />
  );
}

export default function Profile() {
  return (
    <div>
      <Avatar
        size={100}
        person={{
          name: 'Katsuko Saruhashi',
          imageId: 'YfeOqp2'
        }}
      />
      <Avatar
        size={80}
        person={{
          name: 'Aklilu Lemma',
          imageId: 'OKS67lh'
        }}
      />
      <Avatar
        size={50}
        person={{
          name: 'Lin Lanying',
          imageId: '1bX5QH6'
        }}
      />
    </div>
  );
}
```

Props let you think about parent and child components independently. For example, you can change the `person` or the `size` props inside `Profile` without having to think about how `Avatar` uses them. Similarly, you can change how the `Avatar` uses these props, without looking at the `Profile`.

You can think of props like “knobs” that you can adjust. They serve the same role as arguments serve for functions—in fact, props *are* the only argument to your component! React component functions accept a single argument, a `props` object:

```
function Avatar(props) {

  let person = props.person;

  let size = props.size;

  // ...

}
```

Usually you don’t need the whole `props` object itself, so you destructure it into individual props.

### Pitfall

**Don’t miss the pair of `{` and `}` curlies** inside of `(` and `)` when declaring props:

```
function Avatar({ person, size }) {

  // ...

}
```

This syntax is called [“destructuring”](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Unpacking_fields_from_objects_passed_as_a_function_parameter) and is equivalent to reading properties from a function parameter:

```
function Avatar(props) {

  let person = props.person;

  let size = props.size;

  // ...

}
```

## Specifying a default value for a prop[](#specifying-a-default-value-for-a-prop "Link for Specifying a default value for a prop ")

If you want to give a prop a default value to fall back on when no value is specified, you can do it with the destructuring by putting `=` and the default value right after the parameter:

```
function Avatar({ person, size = 100 }) {

  // ...

}
```

Now, if `<Avatar person={...} />` is rendered with no `size` prop, the `size` will be set to `100`.

The default value is only used if the `size` prop is missing or if you pass `size={undefined}`. But if you pass `size={null}` or `size={0}`, the default value will **not** be used.

## Forwarding props with the JSX spread syntax[](#forwarding-props-with-the-jsx-spread-syntax "Link for Forwarding props with the JSX spread syntax ")

Sometimes, passing props gets very repetitive:

```
function Profile({ person, size, isSepia, thickBorder }) {

  return (

    <div className="card">

      <Avatar

        person={person}

        size={size}

        isSepia={isSepia}

        thickBorder={thickBorder}

      />

    </div>

  );

}
```

There’s nothing wrong with repetitive code—it can be more legible. But at times you may value conciseness. Some components forward all of their props to their children, like how this `Profile` does with `Avatar`. Because they don’t use any of their props directly, it can make sense to use a more concise “spread” syntax:

```
function Profile(props) {

  return (

    <div className="card">

      <Avatar {...props} />

    </div>

  );

}
```

This forwards all of `Profile`’s props to the `Avatar` without listing each of their names.

**Use spread syntax with restraint.** If you’re using it in every other component, something is wrong. Often, it indicates that you should split your components and pass children as JSX. More on that next!

## Passing JSX as children[](#passing-jsx-as-children "Link for Passing JSX as children ")

It is common to nest built-in browser tags:

```
<div>

  <img />

</div>
```

Sometimes you’ll want to nest your own components the same way:

```
<Card>

  <Avatar />

</Card>
```

When you nest content inside a JSX tag, the parent component will receive that content in a prop called `children`. For example, the `Card` component below will receive a `children` prop set to `<Avatar />` and render it in a wrapper div:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import Avatar from './Avatar.js';

function Card({ children }) {
  return (
    <div className="card">
      {children}
    </div>
  );
}

export default function Profile() {
  return (
    <Card>
      <Avatar
        size={100}
        person={{
          name: 'Katsuko Saruhashi',
          imageId: 'YfeOqp2'
        }}
      />
    </Card>
  );
}
```

Try replacing the `<Avatar>` inside `<Card>` with some text to see how the `Card` component can wrap any nested content. It doesn’t need to “know” what’s being rendered inside of it. You will see this flexible pattern in many places.

You can think of a component with a `children` prop as having a “hole” that can be “filled in” by its parent components with arbitrary JSX. You will often use the `children` prop for visual wrappers: panels, grids, etc.

Illustrated by [Rachel Lee Nabors](https://nearestnabors.com/)

## How props change over time[](#how-props-change-over-time "Link for How props change over time ")

The `Clock` component below receives two props from its parent component: `color` and `time`. (The parent component’s code is omitted because it uses [state](/learn/state-a-components-memory), which we won’t dive into just yet.)

Try changing the color in the select box below:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
export default function Clock({ color, time }) {
  return (
    <h1 style={{ color: color }}>
      {time}
    </h1>
  );
}
```

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { getImageUrl } from './utils.js';

export default function Gallery() {
  return (
    <div>
      <h1>Notable Scientists</h1>
      <section className="profile">
        <h2>Maria Skłodowska-Curie</h2>
        <img
          className="avatar"
          src={getImageUrl('szV5sdG')}
          alt="Maria Skłodowska-Curie"
          width={70}
          height={70}
        />
        <ul>
          <li>
            <b>Profession: </b>
            physicist and chemist
          </li>
          <li>
            <b>Awards: 4 </b>
            (Nobel Prize in Physics, Nobel Prize in Chemistry, Davy Medal, Matteucci Medal)
          </li>
          <li>
            <b>Discovered: </b>
            polonium (chemical element)
          </li>
        </ul>
      </section>
      <section className="profile">
        <h2>Katsuko Saruhashi</h2>
        <img
          className="avatar"
          src={getImageUrl('YfeOqp2')}
          alt="Katsuko Saruhashi"
          width={70}
          height={70}
        />
        <ul>
          <li>
            <b>Profession: </b>
            geochemist
          </li>
          <li>
            <b>Awards: 2 </b>
            (Miyake Prize for geochemistry, Tanaka Prize)
          </li>
          <li>
            <b>Discovered: </b>
            a method for measuring carbon dioxide in seawater
          </li>
        </ul>
      </section>
    </div>
  );
}
```

[PreviousJavaScript in JSX with Curly Braces](/learn/javascript-in-jsx-with-curly-braces)

[NextConditional Rendering](/learn/conditional-rendering)

***

----
url: https://react.dev/blog/2025/10/01/react-19-2
----

[Blog](/blog)

# React 19.2[](#undefined "Link for this heading")

October 1, 2025 by [The React Team](/community/team)

***

React 19.2 is now available on npm!

This is our third release in the last year, following React 19 in December and React 19.1 in June. In this post, we’ll give an overview of the new features in React 19.2, and highlight some notable changes.

* [New React Features](#new-react-features)

  * [`<Activity />`](#activity)
  * [`useEffectEvent`](#use-effect-event)
  * [`cacheSignal`](#cache-signal)
  * [Performance Tracks](#performance-tracks)

* [New React DOM Features](#new-react-dom-features)
  * [Partial Pre-rendering](#partial-pre-rendering)

* [Notable Changes](#notable-changes)

  * [Batching Suspense Boundaries for SSR](#batching-suspense-boundaries-for-ssr)
  * [SSR: Web Streams support for Node](#ssr-web-streams-support-for-node)
  * [`eslint-plugin-react-hooks` v6](#eslint-plugin-react-hooks)
  * [Update the default `useId` prefix](#update-the-default-useid-prefix)

* [Changelog](#changelog)

***

## New React Features[](#new-react-features "Link for New React Features ")

### `<Activity />`[](#activity "Link for this heading")

`<Activity>` lets you break your app into “activities” that can be controlled and prioritized.

You can use Activity as an alternative to conditionally rendering parts of your app:

```
// Before

{isVisible && <Page />}



// After

<Activity mode={isVisible ? 'visible' : 'hidden'}>

  <Page />

</Activity>
```

In React 19.2, Activity supports two modes: `visible` and `hidden`.

* `hidden`: hides the children, unmounts effects, and defers all updates until React has nothing left to work on.
* `visible`: shows the children, mounts effects, and allows updates to be processed normally.

This means you can pre-render and keep rendering hidden parts of the app without impacting the performance of anything visible on screen.

You can use Activity to render hidden parts of the app that a user is likely to navigate to next, or to save the state of parts the user navigates away from. This helps make navigations quicker by loading data, css, and images in the background, and allows back navigations to maintain state such as input fields.

In the future, we plan to add more modes to Activity for different use cases.

For examples on how to use Activity, check out the [Activity docs](/reference/react/Activity).

***

### `useEffectEvent`[](#use-effect-event "Link for this heading")

One common pattern with `useEffect` is to notify the app code about some kind of “events” from an external system. For example, when a chat room gets connected, you might want to display a notification:

```
function ChatRoom({ roomId, theme }) {

  useEffect(() => {

    const connection = createConnection(serverUrl, roomId);

    connection.on('connected', () => {

      showNotification('Connected!', theme);

    });

    connection.connect();

    return () => {

      connection.disconnect()

    };

  }, [roomId, theme]);

  // ...
```

The problem with the code above is that a change to any values used inside such an “event” will cause the surrounding Effect to re-run. For example, changing the `theme` will cause the chat room to reconnect. This makes sense for values related to the Effect logic itself, like `roomId`, but it doesn’t make sense for `theme`.

To solve this, most users just disable the lint rule and exclude the dependency. But that can lead to bugs since the linter can no longer help you keep the dependencies up to date if you need to update the Effect later.

With `useEffectEvent`, you can split the “event” part of this logic out of the Effect that emits it:

```
function ChatRoom({ roomId, theme }) {

  const onConnected = useEffectEvent(() => {

    showNotification('Connected!', theme);

  });



  useEffect(() => {

    const connection = createConnection(serverUrl, roomId);

    connection.on('connected', () => {

      onConnected();

    });

    connection.connect();

    return () => connection.disconnect();

  }, [roomId]); // ✅ All dependencies declared (Effect Events aren't dependencies)

  // ...
```

Similar to DOM events, Effect Events always “see” the latest props and state.

**Effect Events should *not* be declared in the dependency array**. You’ll need to upgrade to `eslint-plugin-react-hooks@latest` so that the linter doesn’t try to insert them as dependencies. Note that Effect Events can only be declared in the same component or Hook as “their” Effect. These restrictions are verified by the linter.

### Note

#### When to use `useEffectEvent`[](#when-to-use-useeffectevent "Link for this heading")

You should use `useEffectEvent` for functions that are conceptually “events” that happen to be fired from an Effect instead of a user event (that’s what makes it an “Effect Event”). You don’t need to wrap everything in `useEffectEvent`, or to use it just to silence the lint error, as this can lead to bugs.

For a deep dive on how to think about Event Effects, see: [Separating Events from Effects](/learn/separating-events-from-effects#extracting-non-reactive-logic-out-of-effects).

***

### `cacheSignal`[](#cache-signal "Link for this heading")

### React Server Components

`cacheSignal` is only for use with [React Server Components](/reference/rsc/server-components).

`cacheSignal` allows you to know when the [`cache()`](/reference/react/cache) lifetime is over:

```
import {cache, cacheSignal} from 'react';

const dedupedFetch = cache(fetch);



async function Component() {

  await dedupedFetch(url, { signal: cacheSignal() });

}
```

This allows you to clean up or abort work when the result will no longer be used in the cache, such as:

* React has successfully completed rendering
* The render was aborted
* The render has failed

For more info, see the [`cacheSignal` docs](/reference/react/cacheSignal).

***

### Performance Tracks[](#performance-tracks "Link for Performance Tracks ")

React 19.2 adds a new set of [custom tracks](https://developer.chrome.com/docs/devtools/performance/extension) to Chrome DevTools performance profiles to provide more information about the performance of your React app:

The [React Performance Tracks docs](/reference/dev-tools/react-performance-tracks) explain everything included in the tracks, but here is a high-level overview.

#### Scheduler ⚛[](#scheduler- "Link for Scheduler ⚛ ")

The Scheduler track shows what React is working on for different priorities such as “blocking” for user interactions, or “transition” for updates inside startTransition. Inside each track, you will see the type of work being performed such as the event that scheduled an update, and when the render for that update happened.

We also show information such as when an update is blocked waiting for a different priority, or when React is waiting for paint before continuing. The Scheduler track helps you understand how React splits your code into different priorities, and the order it completed the work.

See the [Scheduler track](/reference/dev-tools/react-performance-tracks#scheduler) docs to see everything included.

#### Components ⚛[](#components- "Link for Components ⚛ ")

The Components track shows the tree of components that React is working on either to render or run effects. Inside you’ll see labels such as “Mount” for when children mount or effects are mounted, or “Blocked” for when rendering is blocked due to yielding to work outside React.

The Components track helps you understand when components are rendered or run effects, and the time it takes to complete that work to help identify performance problems.

See the [Components track docs](/reference/dev-tools/react-performance-tracks#components) for see everything included.

***

## New React DOM Features[](#new-react-dom-features "Link for New React DOM Features ")

### Partial Pre-rendering[](#partial-pre-rendering "Link for Partial Pre-rendering ")

In 19.2 we’re adding a new capability to pre-render part of the app ahead of time, and resume rendering it later.

This feature is called “Partial Pre-rendering”, and allows you to pre-render the static parts of your app and serve it from a CDN, and then resume rendering the shell to fill it in with dynamic content later.

To pre-render an app to resume later, first call `prerender` with an `AbortController`:

```
const {prelude, postponed} = await prerender(<App />, {

  signal: controller.signal,

});



// Save the postponed state for later

await savePostponedState(postponed);



// Send prelude to client or CDN.
```

Then, you can return the `prelude` shell to the client, and later call `resume` to “resume” to a SSR stream:

```
const postponed = await getPostponedState(request);

const resumeStream = await resume(<App />, postponed);



// Send stream to client.
```

Or you can call `resumeAndPrerender` to resume to get static HTML for SSG:

```
const postponedState = await getPostponedState(request);

const { prelude } = await resumeAndPrerender(<App />, postponedState);



// Send complete HTML prelude to CDN.
```

For more info, see the docs for the new APIs:

* `react-dom/server`

  * [`resume`](/reference/react-dom/server/resume): for Web Streams.
  * [`resumeToPipeableStream`](/reference/react-dom/server/resumeToPipeableStream) for Node Streams.

* `react-dom/static`

  * [`resumeAndPrerender`](/reference/react-dom/static/resumeAndPrerender) for Web Streams.
  * [`resumeAndPrerenderToNodeStream`](/reference/react-dom/static/resumeAndPrerenderToNodeStream) for Node Streams.

Additionally, the prerender apis now return a `postpone` state to pass to the `resume` apis.

***

## Notable Changes[](#notable-changes "Link for Notable Changes ")

### Batching Suspense Boundaries for SSR[](#batching-suspense-boundaries-for-ssr "Link for Batching Suspense Boundaries for SSR ")

We fixed a behavioral bug where Suspense boundaries would reveal differently depending on if they were rendered on the client or when streaming from server-side rendering.

Starting in 19.2, React will batch reveals of server-rendered Suspense boundaries for a short time, to allow more content to be revealed together and align with the client-rendered behavior.

Previously, during streaming server-side rendering, suspense content would immediately replace fallbacks.

In React 19.2, suspense boundaries are batched for a small amount of time, to allow revealing more content together.

This fix also prepares apps for supporting `<ViewTransition>` for Suspense during SSR. By revealing more content together, animations can run in larger batches of content, and avoid chaining animations of content that stream in close together.

### Note

React uses heuristics to ensure throttling does not impact core web vitals and search ranking.

For example, if the total page load time is approaching 2.5s (which is the time considered “good” for [LCP](https://web.dev/articles/lcp)), React will stop batching and reveal content immediately so that the throttling is not the reason to miss the metric.

***

### SSR: Web Streams support for Node[](#ssr-web-streams-support-for-node "Link for SSR: Web Streams support for Node ")

React 19.2 adds support for Web Streams for streaming SSR in Node.js:

* [`renderToReadableStream`](/reference/react-dom/server/renderToReadableStream) is now available for Node.js
* [`prerender`](/reference/react-dom/static/prerender) is now available for Node.js

As well as the new `resume` APIs:

* [`resume`](/reference/react-dom/server/resume) is available for Node.js.
* [`resumeAndPrerender`](/reference/react-dom/static/resumeAndPrerender) is available for Node.js.

### Pitfall

#### Prefer Node Streams for server-side rendering in Node.js[](#prefer-node-streams-for-server-side-rendering-in-nodejs "Link for Prefer Node Streams for server-side rendering in Node.js ")

In Node.js environments, we still highly recommend using the Node Streams APIs:

* [`renderToPipeableStream`](/reference/react-dom/server/renderToPipeableStream)
* [`resumeToPipeableStream`](/reference/react-dom/server/resumeToPipeableStream)
* [`prerenderToNodeStream`](/reference/react-dom/static/prerenderToNodeStream)
* [`resumeAndPrerenderToNodeStream`](/reference/react-dom/static/resumeAndPrerenderToNodeStream)

This is because Node Streams are much faster than Web Streams in Node, and Web Streams do not support compression by default, leading to users accidentally missing the benefits of streaming.

***

### `eslint-plugin-react-hooks` v6[](#eslint-plugin-react-hooks "Link for this heading")

We also published `eslint-plugin-react-hooks@latest` with flat config by default in the `recommended` preset, and opt-in for new React Compiler powered rules.

To continue using the legacy config, you can change to `recommended-legacy`:

```
- extends: ['plugin:react-hooks/recommended']

+ extends: ['plugin:react-hooks/recommended-legacy']
```

For a full list of compiler enabled rules, [check out the linter docs](/reference/eslint-plugin-react-hooks#recommended).

Check out the `eslint-plugin-react-hooks` [changelog for a full list of changes](https://github.com/facebook/react/blob/main/packages/eslint-plugin-react-hooks/CHANGELOG.md#610).

***

### Update the default `useId` prefix[](#update-the-default-useid-prefix "Link for this heading")

In 19.2, we’re updating the default `useId` prefix from `:r:` (19.0.0) or `«r»` (19.1.0) to `_r_`.

The original intent of using a special character that was not valid for CSS selectors was that it would be unlikely to collide with IDs written by users. However, to support View Transitions, we need to ensure that IDs generated by `useId` are valid for `view-transition-name` and XML 1.0 names.

***

## Changelog[](#changelog "Link for Changelog ")

Other notable changes

* `react-dom`: Allow nonce to be used on hoistable styles [#32461](https://github.com/facebook/react/pull/32461)
* `react-dom`: Warn for using a React owned node as a Container if it also has text content [#32774](https://github.com/facebook/react/pull/32774)

Notable bug fixes

* `react`: Stringify context as “SomeContext” instead of “SomeContext.Provider” [#33507](https://github.com/facebook/react/pull/33507)
* `react`: Fix infinite useDeferredValue loop in popstate event [#32821](https://github.com/facebook/react/pull/32821)
* `react`: Fix a bug when an initial value was passed to useDeferredValue [#34376](https://github.com/facebook/react/pull/34376)
* `react`: Fix a crash when submitting forms with Client Actions [#33055](https://github.com/facebook/react/pull/33055)
* `react`: Hide/unhide the content of dehydrated suspense boundaries if they resuspend [#32900](https://github.com/facebook/react/pull/32900)
* `react`: Avoid stack overflow on wide trees during Hot Reload [#34145](https://github.com/facebook/react/pull/34145)
* `react`: Improve component stacks in various places [#33629](https://github.com/facebook/react/pull/33629), [#33724](https://github.com/facebook/react/pull/33724), [#32735](https://github.com/facebook/react/pull/32735), [#33723](https://github.com/facebook/react/pull/33723)
* `react`: Fix a bug with React.use inside React.lazy-ed Component [#33941](https://github.com/facebook/react/pull/33941)
* `react-dom`: Stop warning when ARIA 1.3 attributes are used [#34264](https://github.com/facebook/react/pull/34264)
* `react-dom`: Fix a bug with deeply nested Suspense inside Suspense fallbacks [#33467](https://github.com/facebook/react/pull/33467)
* `react-dom`: Avoid hanging when suspending after aborting while rendering [#34192](https://github.com/facebook/react/pull/34192)

For a full list of changes, please see the [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md).

***

*Thanks to [Ricky Hanlon](https://bsky.app/profile/ricky.fm) for [writing this post](https://www.youtube.com/shorts/T9X3YkgZRG0), [Dan Abramov](https://bsky.app/profile/danabra.mov), [Matt Carroll](https://twitter.com/mattcarrollcode), [Jack Pope](https://jackpope.me), and [Joe Savona](https://x.com/en_JS) for reviewing this post.*

[PreviousIntroducing the React Foundation](/blog/2025/10/07/introducing-the-react-foundation)

[NextReact Labs: View Transitions, Activity, and more](/blog/2025/04/23/react-labs-view-transitions-activity-and-more)

***

----
url: https://legacy.reactjs.org/blog/2013/07/26/react-v0-4-1.html
----

July 26, 2013 by [Paul O’Shannessy](https://twitter.com/zpao)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

React v0.4.1 is a small update, mostly containing correctness fixes. Some code has been restructured internally but those changes do not impact any of our public APIs.

## [](#react)React

* `setState` callbacks are now executed in the scope of your component.
* `click` events now work on Mobile Safari.
* Prevent a potential error in event handling if `Object.prototype` is extended.
* Don’t set DOM attributes to the string `"undefined"` on update when previously defined.
* Improved support for `<iframe>` attributes.
* Added checksums to detect and correct cases where server-side rendering markup mismatches what React expects client-side.

## [](#jsxtransformer)JSXTransformer

* Improved environment detection so it can be run in a non-browser environment.

[Download it now!](/downloads.html)

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2013-07-26-react-v0-4-1.md)

----
url: https://legacy.reactjs.org/blog/2013/07/03/community-roundup-4.html
----

July 03, 2013 by [Vjeux](https://twitter.com/vjeux)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

React reconciliation process appears to be very well suited to implement a text editor with a live preview as people at Khan Academy show us.

## [](#khan-academy)Khan Academy

[Ben Kamens](http://bjk5.com/) explains how [Sophie Alpert](http://sophiebits.com/) and [Joel Burget](http://joelburget.com/) are promoting React inside of [Khan Academy](https://www.khanacademy.org/). They now have three projects in the works using React.

> Recently two Khan Academy devs dropped into our team chat and said they were gonna use React to write a new feature. They even hinted that we may want to adopt it product-wide.
>
> “The library is only a week old. It’s a brand new way of thinking about things. We’re the first to use it outside of Facebook. Heck, even the React devs were surprised to hear we’re using this in production!!!”
>
> [Read the full post…](http://bjk5.com/post/53742233351/getting-your-team-to-adopt-new-technology)

The best part is the demo of how React reconciliation process makes live editing more user-friendly.

> Our renderer, post-React, is on the left. A typical math editor’s preview is on the right.

[](http://bjk5.com/post/53742233351/getting-your-team-to-adopt-new-technology)

## [](#react-snippets)React Snippets

Over the past several weeks, members of our team, [Pete Hunt](http://www.petehunt.net/) and [Paul O’Shannessy](http://zpao.com/), answered many questions that were asked in the [React group](https://groups.google.com/forum/#!forum/reactjs). They give a good overview of how to integrate React with other libraries and APIs through the use of [Mixins](/docs/reusable-components.html) and [Lifecycle Methods](/docs/working-with-the-browser.html).

> [Listening Scroll Event](https://groups.google.com/forum/#!topic/reactjs/l6PnP8qbofk)
>
> * [JSFiddle](http://jsfiddle.net/aabeL/1/): Basically I’ve given you two mixins. The first lets you react to global scroll events. The second is, IMO, much more useful: it gives you scroll start and scroll end events, which you can use with setState() to create components that react based on whether the user is scrolling or not.
>
> [Fade-in Transition](https://groups.google.com/forum/#!topic/reactjs/RVAY_eQmdpo)
>
> * [JSFiddle](http://jsfiddle.net/ufe8k/1/): Creating a new `<FadeInWhenAdded>` component and using jQuery `.fadeIn()` function on the DOM node.
> * [JSFiddle](http://jsfiddle.net/R8f5L/5/): Using CSS transition instead.
>
> [Socket.IO Integration](https://groups.google.com/forum/#!topic/reactjs/pyUZBRWcHB4)
>
> * [Gist](https://gist.github.com/zpao/5686416): The big thing to notice is that my component is pretty dumb (it doesn’t have to be but that’s how I chose to model it). All it does is render itself based on the props that are passed in. renderOrUpdate is where the “magic” happens.
> * [Gist](https://gist.github.com/petehunt/5687230): This example is doing everything — including the IO — inside of a single React component.
> * [Gist](https://gist.github.com/petehunt/5687276): One pattern that we use at Instagram a lot is to employ separation of concerns and consolidate I/O and state into components higher in the hierarchy to keep the rest of the components mostly stateless and purely display.
>
> [Sortable jQuery Plugin Integration](https://groups.google.com/forum/#!topic/reactjs/mHfBGI3Qwz4)
>
> * [JSFiddle](http://jsfiddle.net/LQxy7/): Your React component simply render empty divs, and then in componentDidMount() you call React.renderComponent() on each of those divs to set up a new root React tree. Be sure to explicitly unmountAndReleaseReactRootNode() for each component in componentWillUnmount().

## [](#introduction-to-react-screencast)Introduction to React Screencast

[Pete Hunt](http://www.petehunt.net/) recorded himself implementing a simple `<Blink>` tag in React.

## [](#snake-in-react)Snake in React

[Tom Occhino](http://tomocchino.com/) implemented Snake in 150 lines with React.

> [Check the source on GitHub](https://github.com/tomocchino/react-snake/blob/master/src/snake.js)
>
> [](https://tomocchino.github.io/react-snake/)

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2013-07-03-community-roundup-4.md)

----
url: https://react.dev/reference/react/useState
----

[API Reference](/reference/react)

[Hooks](/reference/react/hooks)

# useState[](#undefined "Link for this heading")

`useState` is a React Hook that lets you add a [state variable](/learn/state-a-components-memory) to your component.

```
const [state, setState] = useState(initialState)
```

***

## Reference[](#reference "Link for Reference ")

### `useState(initialState)`[](#usestate "Link for this heading")

Call `useState` at the top level of your component to declare a [state variable.](/learn/state-a-components-memory)

```
import { useState } from 'react';



function MyComponent() {

  const [age, setAge] = useState(28);

  const [name, setName] = useState('Taylor');

  const [todos, setTodos] = useState(() => createTodos());

  // ...
```

***

### `set` functions, like `setSomething(nextState)`[](#setstate "Link for this heading")

The `set` function returned by `useState` lets you update the state to a different value and trigger a re-render. You can pass the next state directly, or a function that calculates it from the previous state:

```
const [name, setName] = useState('Edward');



function handleClick() {

  setName('Taylor');

  setAge(a => a + 1);

  // ...
```

***

## Usage[](#usage "Link for Usage ")

### Adding state to a component[](#adding-state-to-a-component "Link for Adding state to a component ")

Call `useState` at the top level of your component to declare one or more [state variables.](/learn/state-a-components-memory)

```
import { useState } from 'react';



function MyComponent() {

  const [age, setAge] = useState(42);

  const [name, setName] = useState('Taylor');

  // ...
```

The convention is to name state variables like `[something, setSomething]` using [array destructuring.](https://javascript.info/destructuring-assignment)

`useState` returns an array with exactly two items:

1. The current state of this state variable, initially set to the initial state you provided.
2. The `set` function that lets you change it to any other value in response to interaction.

To update what’s on the screen, call the `set` function with some next state:

```
function handleClick() {

  setName('Robin');

}
```

React will store the next state, render your component again with the new values, and update the UI.

### Pitfall

Calling the `set` function [**does not** change the current state in the already executing code](#ive-updated-the-state-but-logging-gives-me-the-old-value):

```
function handleClick() {

  setName('Robin');

  console.log(name); // Still "Taylor"!

}
```

It only affects what `useState` will return starting from the *next* render.

#### Basic useState examples[](#examples-basic "Link for Basic useState examples")

#### Example 1 of 4:Counter (number)[](#counter-number "Link for this heading")

In this example, the `count` state variable holds a number. Clicking the button increments it.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function Counter() {
  const [count, setCount] = useState(0);

  function handleClick() {
    setCount(count + 1);
  }

  return (
    <button onClick={handleClick}>
      You pressed me {count} times
    </button>
  );
}
```

***

### Updating state based on the previous state[](#updating-state-based-on-the-previous-state "Link for Updating state based on the previous state ")

Suppose the `age` is `42`. This handler calls `setAge(age + 1)` three times:

```
function handleClick() {

  setAge(age + 1); // setAge(42 + 1)

  setAge(age + 1); // setAge(42 + 1)

  setAge(age + 1); // setAge(42 + 1)

}
```

However, after one click, `age` will only be `43` rather than `45`! This is because calling the `set` function [does not update](/learn/state-as-a-snapshot) the `age` state variable in the already running code. So each `setAge(age + 1)` call becomes `setAge(43)`.

To solve this problem, **you may pass an *updater function*** to `setAge` instead of the next state:

```
function handleClick() {

  setAge(a => a + 1); // setAge(42 => 43)

  setAge(a => a + 1); // setAge(43 => 44)

  setAge(a => a + 1); // setAge(44 => 45)

}
```

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function Counter() {
  const [age, setAge] = useState(42);

  function increment() {
    setAge(a => a + 1);
  }

  return (
    <>
      <h1>Your age: {age}</h1>
      <button onClick={() => {
        increment();
        increment();
        increment();
      }}>+3</button>
      <button onClick={() => {
        increment();
      }}>+1</button>
    </>
  );
}
```

***

### Updating objects and arrays in state[](#updating-objects-and-arrays-in-state "Link for Updating objects and arrays in state ")

You can put objects and arrays into state. In React, state is considered read-only, so **you should *replace* it rather than *mutate* your existing objects**. For example, if you have a `form` object in state, don’t mutate it:

```
// 🚩 Don't mutate an object in state like this:

form.firstName = 'Taylor';
```

Instead, replace the whole object by creating a new one:

```
// ✅ Replace state with a new object

setForm({

  ...form,

  firstName: 'Taylor'

});
```

Read [updating objects in state](/learn/updating-objects-in-state) and [updating arrays in state](/learn/updating-arrays-in-state) to learn more.

#### Examples of objects and arrays in state[](#examples-objects "Link for Examples of objects and arrays in state")

#### Example 1 of 4:Form (object)[](#form-object "Link for this heading")

In this example, the `form` state variable holds an object. Each input has a change handler that calls `setForm` with the next state of the entire form. The `{ ...form }` spread syntax ensures that the state object is replaced rather than mutated.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function Form() {
  const [form, setForm] = useState({
    firstName: 'Barbara',
    lastName: 'Hepworth',
    email: 'bhepworth@sculpture.com',
  });

  return (
    <>
      <label>
        First name:
        <input
          value={form.firstName}
          onChange={e => {
            setForm({
              ...form,
              firstName: e.target.value
            });
          }}
        />
      </label>
      <label>
        Last name:
        <input
          value={form.lastName}
          onChange={e => {
            setForm({
              ...form,
              lastName: e.target.value
            });
          }}
        />
      </label>
      <label>
        Email:
        <input
          value={form.email}
          onChange={e => {
            setForm({
              ...form,
              email: e.target.value
            });
          }}
        />
      </label>
      <p>
        {form.firstName}{' '}
        {form.lastName}{' '}
        ({form.email})
      </p>
    </>
  );
}
```

***

### Avoiding recreating the initial state[](#avoiding-recreating-the-initial-state "Link for Avoiding recreating the initial state ")

React saves the initial state once and ignores it on the next renders.

```
function TodoList() {

  const [todos, setTodos] = useState(createInitialTodos());

  // ...
```

Although the result of `createInitialTodos()` is only used for the initial render, you’re still calling this function on every render. This can be wasteful if it’s creating large arrays or performing expensive calculations.

To solve this, you may **pass it as an *initializer* function** to `useState` instead:

```
function TodoList() {

  const [todos, setTodos] = useState(createInitialTodos);

  // ...
```

Notice that you’re passing `createInitialTodos`, which is the *function itself*, and not `createInitialTodos()`, which is the result of calling it. If you pass a function to `useState`, React will only call it during initialization.

React may [call your initializers twice](#my-initializer-or-updater-function-runs-twice) in development to verify that they are [pure.](/learn/keeping-components-pure)

#### The difference between passing an initializer and passing the initial state directly[](#examples-initializer "Link for The difference between passing an initializer and passing the initial state directly")

#### Example 1 of 2:Passing the initializer function[](#passing-the-initializer-function "Link for this heading")

This example passes the initializer function, so the `createInitialTodos` function only runs during initialization. It does not run when component re-renders, such as when you type into the input.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

function createInitialTodos() {
  const initialTodos = [];
  for (let i = 0; i < 50; i++) {
    initialTodos.push({
      id: i,
      text: 'Item ' + (i + 1)
    });
  }
  return initialTodos;
}

export default function TodoList() {
  const [todos, setTodos] = useState(createInitialTodos);
  const [text, setText] = useState('');

  return (
    <>
      <input
        value={text}
        onChange={e => setText(e.target.value)}
      />
      <button onClick={() => {
        setText('');
        setTodos([{
          id: todos.length,
          text: text
        }, ...todos]);
      }}>Add</button>
      <ul>
        {todos.map(item => (
          <li key={item.id}>
            {item.text}
          </li>
        ))}
      </ul>
    </>
  );
}
```

***

### Resetting state with a key[](#resetting-state-with-a-key "Link for Resetting state with a key ")

You’ll often encounter the `key` attribute when [rendering lists.](/learn/rendering-lists) However, it also serves another purpose.

You can **reset a component’s state by passing a different `key` to a component.** In this example, the Reset button changes the `version` state variable, which we pass as a `key` to the `Form`. When the `key` changes, React re-creates the `Form` component (and all of its children) from scratch, so its state gets reset.

Read [preserving and resetting state](/learn/preserving-and-resetting-state) to learn more.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function App() {
  const [version, setVersion] = useState(0);

  function handleReset() {
    setVersion(version + 1);
  }

  return (
    <>
      <button onClick={handleReset}>Reset</button>
      <Form key={version} />
    </>
  );
}

function Form() {
  const [name, setName] = useState('Taylor');

  return (
    <>
      <input
        value={name}
        onChange={e => setName(e.target.value)}
      />
      <p>Hello, {name}.</p>
    </>
  );
}
```

***

```
export default function CountLabel({ count }) {

  return <h1>{count}</h1>

}
```

Say you want to show whether the counter has *increased or decreased* since the last change. The `count` prop doesn’t tell you this — you need to keep track of its previous value. Add the `prevCount` state variable to track it. Add another state variable called `trend` to hold whether the count has increased or decreased. Compare `prevCount` with `count`, and if they’re not equal, update both `prevCount` and `trend`. Now you can show both the current count prop and *how it has changed since the last render*.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function CountLabel({ count }) {
  const [prevCount, setPrevCount] = useState(count);
  const [trend, setTrend] = useState(null);
  if (prevCount !== count) {
    setPrevCount(count);
    setTrend(count > prevCount ? 'increasing' : 'decreasing');
  }
  return (
    <>
      <h1>{count}</h1>
      {trend && <p>The count is {trend}</p>}
    </>
  );
}
```

Note that if you call a `set` function while rendering, it must be inside a condition like `prevCount !== count`, and there must be a call like `setPrevCount(count)` inside of the condition. Otherwise, your component would re-render in a loop until it crashes. Also, you can only update the state of the *currently rendering* component like this. Calling the `set` function of *another* component during rendering is an error. Finally, your `set` call should still [update state without mutation](#updating-objects-and-arrays-in-state) — this doesn’t mean you can break other rules of [pure functions.](/learn/keeping-components-pure)

This pattern can be hard to understand and is usually best avoided. However, it’s better than updating state in an effect. When you call the `set` function during render, React will re-render that component immediately after your component exits with a `return` statement, and before rendering the children. This way, children don’t need to render twice. The rest of your component function will still execute (and the result will be thrown away). If your condition is below all the Hook calls, you may add an early `return;` to restart rendering earlier.

***

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### I’ve updated the state, but logging gives me the old value[](#ive-updated-the-state-but-logging-gives-me-the-old-value "Link for I’ve updated the state, but logging gives me the old value ")

Calling the `set` function **does not change state in the running code**:

```
function handleClick() {

  console.log(count);  // 0



  setCount(count + 1); // Request a re-render with 1

  console.log(count);  // Still 0!



  setTimeout(() => {

    console.log(count); // Also 0!

  }, 5000);

}
```

This is because [states behaves like a snapshot.](/learn/state-as-a-snapshot) Updating state requests another render with the new state value, but does not affect the `count` JavaScript variable in your already-running event handler.

If you need to use the next state, you can save it in a variable before passing it to the `set` function:

```
const nextCount = count + 1;

setCount(nextCount);



console.log(count);     // 0

console.log(nextCount); // 1
```

***

### I’ve updated the state, but the screen doesn’t update[](#ive-updated-the-state-but-the-screen-doesnt-update "Link for I’ve updated the state, but the screen doesn’t update ")

React will **ignore your update if the next state is equal to the previous state,** as determined by an [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) comparison. This usually happens when you change an object or an array in state directly:

```
obj.x = 10;  // 🚩 Wrong: mutating existing object

setObj(obj); // 🚩 Doesn't do anything
```

You mutated an existing `obj` object and passed it back to `setObj`, so React ignored the update. To fix this, you need to ensure that you’re always [*replacing* objects and arrays in state instead of *mutating* them](#updating-objects-and-arrays-in-state):

```
// ✅ Correct: creating a new object

setObj({

  ...obj,

  x: 10

});
```

***

### I’m getting an error: “Too many re-renders”[](#im-getting-an-error-too-many-re-renders "Link for I’m getting an error: “Too many re-renders” ")

You might get an error that says: `Too many re-renders. React limits the number of renders to prevent an infinite loop.` Typically, this means that you’re unconditionally setting state *during render*, so your component enters a loop: render, set state (which causes a render), render, set state (which causes a render), and so on. Very often, this is caused by a mistake in specifying an event handler:

```
// 🚩 Wrong: calls the handler during render

return <button onClick={handleClick()}>Click me</button>



// ✅ Correct: passes down the event handler

return <button onClick={handleClick}>Click me</button>



// ✅ Correct: passes down an inline function

return <button onClick={(e) => handleClick(e)}>Click me</button>
```

If you can’t find the cause of this error, click on the arrow next to the error in the console and look through the JavaScript stack to find the specific `set` function call responsible for the error.

***

### My initializer or updater function runs twice[](#my-initializer-or-updater-function-runs-twice "Link for My initializer or updater function runs twice ")

In [Strict Mode](/reference/react/StrictMode), React will call some of your functions twice instead of once:

```
function TodoList() {

  // This component function will run twice for every render.



  const [todos, setTodos] = useState(() => {

    // This initializer function will run twice during initialization.

    return createTodos();

  });



  function handleClick() {

    setTodos(prevTodos => {

      // This updater function will run twice for every click.

      return [...prevTodos, createTodo()];

    });

  }

  // ...
```

This is expected and shouldn’t break your code.

This **development-only** behavior helps you [keep components pure.](/learn/keeping-components-pure) React uses the result of one of the calls, and ignores the result of the other call. As long as your component, initializer, and updater functions are pure, this shouldn’t affect your logic. However, if they are accidentally impure, this helps you notice the mistakes.

For example, this impure updater function mutates an array in state:

```
setTodos(prevTodos => {

  // 🚩 Mistake: mutating state

  prevTodos.push(createTodo());

});
```

Because React calls your updater function twice, you’ll see the todo was added twice, so you’ll know that there is a mistake. In this example, you can fix the mistake by [replacing the array instead of mutating it](#updating-objects-and-arrays-in-state):

```
setTodos(prevTodos => {

  // ✅ Correct: replacing with new state

  return [...prevTodos, createTodo()];

});
```

Now that this updater function is pure, calling it an extra time doesn’t make a difference in behavior. This is why React calling it twice helps you find mistakes. **Only component, initializer, and updater functions need to be pure.** Event handlers don’t need to be pure, so React will never call your event handlers twice.

Read [keeping components pure](/learn/keeping-components-pure) to learn more.

***

### I’m trying to set state to a function, but it gets called instead[](#im-trying-to-set-state-to-a-function-but-it-gets-called-instead "Link for I’m trying to set state to a function, but it gets called instead ")

You can’t put a function into state like this:

```
const [fn, setFn] = useState(someFunction);



function handleClick() {

  setFn(someOtherFunction);

}
```

Because you’re passing a function, React assumes that `someFunction` is an [initializer function](#avoiding-recreating-the-initial-state), and that `someOtherFunction` is an [updater function](#updating-state-based-on-the-previous-state), so it tries to call them and store the result. To actually *store* a function, you have to put `() =>` before them in both cases. Then React will store the functions you pass.

```
const [fn, setFn] = useState(() => someFunction);



function handleClick() {

  setFn(() => someOtherFunction);

}
```

[PrevioususeRef](/reference/react/useRef)

[NextuseSyncExternalStore](/reference/react/useSyncExternalStore)

***

----
url: https://react.dev/reference/react/act
----

[API Reference](/reference/react)

[APIs](/reference/react/apis)

# act[](#undefined "Link for this heading")

`act` is a test helper to apply pending React updates before making assertions.

```
await act(async actFn)
```

  * [I’m getting an error: “The current testing environment is not configured to support act(…)”](#error-the-current-testing-environment-is-not-configured-to-support-act)

***

## Reference[](#reference "Link for Reference ")

### `await act(async actFn)`[](#await-act-async-actfn "Link for this heading")

When writing UI tests, tasks like rendering, user events, or data fetching can be considered as “units” of interaction with a user interface. React provides a helper called `act()` that makes sure all updates related to these “units” have been processed and applied to the DOM before you make any assertions.

The name `act` comes from the [Arrange-Act-Assert](https://wiki.c2.com/?ArrangeActAssert) pattern.

```
it ('renders with button disabled', async () => {

  await act(async () => {

    root.render(<TestComponent />)

  });

  expect(container.querySelector('button')).toBeDisabled();

});
```

```
function Counter() {

  const [count, setCount] = useState(0);

  const handleClick = () => {

    setCount(prev => prev + 1);

  }



  useEffect(() => {

    document.title = `You clicked ${count} times`;

  }, [count]);



  return (

    <div>

      <p>You clicked {count} times</p>

      <button onClick={handleClick}>

        Click me

      </button>

    </div>

  )

}
```

### Rendering components in tests[](#rendering-components-in-tests "Link for Rendering components in tests ")

To test the render output of a component, wrap the render inside `act()`:

```
import {act} from 'react';

import ReactDOMClient from 'react-dom/client';

import Counter from './Counter';



it('can render and update a counter', async () => {

  container = document.createElement('div');

  document.body.appendChild(container);



  // ✅ Render the component inside act().

  await act(() => {

    ReactDOMClient.createRoot(container).render(<Counter />);

  });



  const button = container.querySelector('button');

  const label = container.querySelector('p');

  expect(label.textContent).toBe('You clicked 0 times');

  expect(document.title).toBe('You clicked 0 times');

});
```

Here, we create a container, append it to the document, and render the `Counter` component inside `act()`. This ensures that the component is rendered and its effects are applied before making assertions.

Using `act` ensures that all updates have been applied before we make assertions.

### Dispatching events in tests[](#dispatching-events-in-tests "Link for Dispatching events in tests ")

To test events, wrap the event dispatch inside `act()`:

```
import {act} from 'react';

import ReactDOMClient from 'react-dom/client';

import Counter from './Counter';



it.only('can render and update a counter', async () => {

  const container = document.createElement('div');

  document.body.appendChild(container);



  await act( async () => {

    ReactDOMClient.createRoot(container).render(<Counter />);

  });



  // ✅ Dispatch the event inside act().

  await act(async () => {

    button.dispatchEvent(new MouseEvent('click', { bubbles: true }));

  });



  const button = container.querySelector('button');

  const label = container.querySelector('p');

  expect(label.textContent).toBe('You clicked 1 times');

  expect(document.title).toBe('You clicked 1 times');

});
```

Here, we render the component with `act`, and then dispatch the event inside another `act()`. This ensures that all updates from the event are applied before making assertions.

### Pitfall

Don’t forget that dispatching DOM events only works when the DOM container is added to the document. You can use a library like [React Testing Library](https://testing-library.com/docs/react-testing-library/intro) to reduce the boilerplate code.

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### I’m getting an error: “The current testing environment is not configured to support act(…)”[](#error-the-current-testing-environment-is-not-configured-to-support-act "Link for I’m getting an error: “The current testing environment is not configured to support act(…)” ")

Using `act` requires setting `global.IS_REACT_ACT_ENVIRONMENT=true` in your test environment. This is to ensure that `act` is only used in the correct environment.

If you don’t set the global, you will see an error like this:

Console

Warning: The current testing environment is not configured to support act(…)

To fix, add this to your global setup file for React tests:

```
global.IS_REACT_ACT_ENVIRONMENT=true
```

### Note

In testing frameworks like [React Testing Library](https://testing-library.com/docs/react-testing-library/intro), `IS_REACT_ACT_ENVIRONMENT` is already set for you.

[PreviousAPIs](/reference/react/apis)

[NextaddTransitionType](/reference/react/addTransitionType)

***

----
url: https://legacy.reactjs.org/blog/2015/04/17/react-native-v0.4.html
----

April 17, 2015 by [Vjeux](https://twitter.com/vjeux)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

It’s been three weeks since we open sourced React Native and there’s been some insane amount of activity already: over 12.5k stars, 1000 commits, 500 issues, 380 pull requests, and 100 contributors, plus [35 plugins](http://react.parts/native-ios) and [1 app in the app store](http://herman.asia/building-a-flashcard-app-with-react-native)! We were expecting some buzz around the project but this is way beyond anything we imagined. Thank you!

I’d especially like to thank community members Brent Vatne and James Ide who have both already contributed meaningfully to the project and have been extremely helpful on IRC and with issues and pull requests

## [](#changelog)Changelog

The main focus of the past few weeks has been to make React Native the best possible experience for people outside of Facebook. Here’s a high level summary of what’s happened since we open sourced:

* **Error messages and documentation**: We want React Native to be the absolute best developer experience for building mobile apps. We’ve added a lot of warnings, improved the documentation, and fixed many bugs. If you encounter anything, and I really mean anything, that is not expected or clear, please create an issue - we want to hear about it and fix it.
* **NPM modules compatibility**: There are a lot of libraries on NPM that do not depend on node/browser internals that would be really useful in React Native, such as superagent, underscore, parse, and many others. The packager is now a lot more faithful to node/browserify/webpack dependency resolution. If your favorite library doesn’t work out of the box, please open up an issue.
* **Infrastructure**: We are refactoring the internals of React Native to make it easier to plug in to existing iOS codebases, as well as improve performance by removing redundant views and shadow views, supporting multiple root views and manually registering classes to reduce startup time.
* **Components**: The API for a lot of UI components and APIs, especially the ones we’re not using heavily inside of Facebook, has dramatically improved thanks to many of your pull requests.
* **Tests**: We ported JavaScript tests, iOS Snapshot tests, and End to End tests to Travis CI. We have broken GitHub master a couple of times (whoops!) when syncing and we hope that with this growing suite of tests it’s going to become harder and harder to do so.
* **Patent Grant**: Many of you had concerns and questions around the PATENTS file. We pushed [a new version of the grant](https://code.facebook.com/posts/1639473982937255/updating-our-open-source-patent-grant/).
* **Per commit history**: In order to synchronize from Facebook to GitHub, we used to do one giant commit every few days. We improved our tooling and now have per commit history that maintains author information (both internal and external from pull requests), and we retroactively applied this to historical diffs to provide proper attribution.

## [](#where-are-we-going)Where are we going?

In addition to supporting pull requests, issues, and general improvements, we’re also working hard on our internal React Native integrations and on React Native for Android.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2015-04-17-react-native-v0.4.md)

----
url: https://legacy.reactjs.org/docs/concurrent-mode-suspense.html
----

> Caution:
>
> This page is **somewhat outdated** and only exists for historical purposes.
>
> React 18 was released with support for concurrency. However, **there is no “mode” anymore,** and the new behavior is fully opt-in and only enabled [when you use the new features](https://reactjs.org/blog/2022/03/29/react-v18.html#gradually-adopting-concurrent-features).
>
> **For up-to-date high-level information, refer to:**
>
> * [React 18 Announcement](https://reactjs.org/blog/2022/03/29/react-v18.html)
> * [Upgrading to React 18](https://reactjs.org/blog/2022/03/08/react-18-upgrade-guide.html)
> * [React Conf 2021 Videos](https://reactjs.org/blog/2021/12/17/react-conf-2021-recap.html)
>
> **For details about concurrent APIs in React 18, refer to:**
>
> * [`React.Suspense`](https://reactjs.org/docs/react-api.html#reactsuspense) reference
> * [`React.startTransition`](https://reactjs.org/docs/react-api.html#starttransition) reference
> * [`React.useTransition`](https://reactjs.org/docs/hooks-reference.html#usetransition) reference
> * [`React.useDeferredValue`](https://reactjs.org/docs/hooks-reference.html#usedeferredvalue) reference
>
> The rest of this page includes content that’s stale, broken, or incorrect.

React 16.6 added a `<Suspense>` component that lets you “wait” for some code to load and declaratively specify a loading state (like a spinner) while we’re waiting:

```
const ProfilePage = React.lazy(() => import('./ProfilePage')); // Lazy-loaded

// Show a spinner while the profile is loading
<Suspense fallback={<Spinner />}>
  <ProfilePage />
</Suspense>
```

Suspense for Data Fetching is a new feature that lets you also use `<Suspense>` to **declaratively “wait” for anything else, including data.** This page focuses on the data fetching use case, but it can also wait for images, scripts, or other asynchronous work.

* [What Is Suspense, Exactly?](#what-is-suspense-exactly)

  * [What Suspense Is Not](#what-suspense-is-not)
  * [What Suspense Lets You Do](#what-suspense-lets-you-do)

* [Using Suspense in Practice](#using-suspense-in-practice)

  * [What If I Don’t Use Relay?](#what-if-i-dont-use-relay)
  * [For Library Authors](#for-library-authors)

* [Traditional Approaches vs Suspense](#traditional-approaches-vs-suspense)

  * [Approach 1: Fetch-on-Render (not using Suspense)](#approach-1-fetch-on-render-not-using-suspense)
  * [Approach 2: Fetch-Then-Render (not using Suspense)](#approach-2-fetch-then-render-not-using-suspense)
  * [Approach 3: Render-as-You-Fetch (using Suspense)](#approach-3-render-as-you-fetch-using-suspense)

* [Start Fetching Early](#start-fetching-early)

  * [We’re Still Figuring This Out](#were-still-figuring-this-out)

* [Suspense and Race Conditions](#suspense-and-race-conditions)

  * [Race Conditions with useEffect](#race-conditions-with-useeffect)
  * [Race Conditions with componentDidUpdate](#race-conditions-with-componentdidupdate)
  * [The Problem](#the-problem)
  * [Solving Race Conditions with Suspense](#solving-race-conditions-with-suspense)

* [Handling Errors](#handling-errors)

* [Next Steps](#next-steps)

## [](#what-is-suspense-exactly)What Is Suspense, Exactly?

Suspense lets your components “wait” for something before they can render. In [this example](https://codesandbox.io/s/frosty-hermann-bztrp), two components wait for an asynchronous API call to fetch some data:

```
const resource = fetchProfileData();

function ProfilePage() {
  return (
    <Suspense fallback={<h1>Loading profile...</h1>}>
      <ProfileDetails />
      <Suspense fallback={<h1>Loading posts...</h1>}>
        <ProfileTimeline />
      </Suspense>
    </Suspense>
  );
}

function ProfileDetails() {
  // Try to read user info, although it might not have loaded yet
  const user = resource.user.read();
  return <h1>{user.name}</h1>;
}

function ProfileTimeline() {
  // Try to read posts, although they might not have loaded yet
  const posts = resource.posts.read();
  return (
    <ul>
      {posts.map(post => (
        <li key={post.id}>{post.text}</li>
      ))}
    </ul>
  );
}
```

**[Try it on CodeSandbox](https://codesandbox.io/s/frosty-hermann-bztrp)**

This demo is a teaser. Don’t worry if it doesn’t quite make sense yet. We’ll talk more about how it works below. Keep in mind that Suspense is more of a *mechanism*, and particular APIs like `fetchProfileData()` or `resource.posts.read()` in the above example are not very important. If you’re curious, you can find their definitions right in the [demo sandbox](https://codesandbox.io/s/frosty-hermann-bztrp).

Suspense is not a data fetching library. It’s a **mechanism for data fetching libraries** to communicate to React that *the data a component is reading is not ready yet*. React can then wait for it to be ready and update the UI. At Facebook, we use Relay and its [new Suspense integration](https://relay.dev/docs/getting-started/step-by-step-guide/). We expect that other libraries like Apollo can provide similar integrations.

In the long term, we intend Suspense to become the primary way to read asynchronous data from components — no matter where that data is coming from.

### [](#what-suspense-is-not)What Suspense Is Not

Suspense is significantly different from existing approaches to these problems, so reading about it for the first time often leads to misconceptions. Let’s clarify the most common ones:

* **It is not a data fetching implementation.** It does not assume that you use GraphQL, REST, or any other particular data format, library, transport, or protocol.
* **It is not a ready-to-use client.** You can’t “replace” `fetch` or Relay with Suspense. But you can use a library that’s integrated with Suspense (for example, [new Relay APIs](https://relay.dev/docs/api-reference/relay-environment-provider/)).
* **It does not couple data fetching to the view layer.** It helps orchestrate displaying the loading states in your UI, but it doesn’t tie your network logic to React components.

### [](#what-suspense-lets-you-do)What Suspense Lets You Do

So what’s the point of Suspense? There are a few ways we can answer this:

* **It lets data fetching libraries deeply integrate with React.** If a data fetching library implements Suspense support, using it from React components feels very natural.
* **It lets you orchestrate intentionally designed loading states.** It doesn’t say *how* the data is fetched, but it lets you closely control the visual loading sequence of your app.
* **It helps you avoid race conditions.** Even with `await`, asynchronous code is often error-prone. Suspense feels more like reading data *synchronously* — as if it were already loaded.

## [](#using-suspense-in-practice)Using Suspense in Practice

At Facebook, so far we have only used the Relay integration with Suspense in production. **If you’re looking for a practical guide to get started today, [check out the Relay Guide](https://relay.dev/docs/getting-started/step-by-step-guide/)!** It demonstrates patterns that have already worked well for us in production.

**The code demos on this page use a “fake” API implementation rather than Relay.** This makes them easier to understand if you’re not familiar with GraphQL, but they won’t tell you the “right way” to build an app with Suspense. This page is more conceptual and is intended to help you see *why* Suspense works in a certain way, and which problems it solves.

### [](#what-if-i-dont-use-relay)What If I Don’t Use Relay?

If you don’t use Relay today, you might have to wait before you can really try Suspense in your app. So far, it’s the only implementation that we tested in production and are confident in.

Over the next several months, many libraries will appear with different takes on Suspense APIs. **If you prefer to learn when things are more stable, you might prefer to ignore this work for now, and come back when the Suspense ecosystem is more mature.**

You can also write your own integration for a data fetching library, if you’d like.

### [](#for-library-authors)For Library Authors

We expect to see a lot of experimentation in the community with other libraries. There is one important thing to note for data fetching library authors.

Although it’s technically doable, Suspense is **not** currently intended as a way to start fetching data when a component renders. Rather, it lets components express that they’re “waiting” for data that is *already being fetched*. **[Building Great User Experiences with Concurrent Mode and Suspense](/blog/2019/11/06/building-great-user-experiences-with-concurrent-mode-and-suspense.html) describes why this matters and how to implement this pattern in practice.**

Unless you have a solution that helps prevent waterfalls, we suggest to prefer APIs that favor or enforce fetching before render. For a concrete example, you can look at how [Relay Suspense API](https://relay.dev/docs/api-reference/use-preloaded-query/) enforces preloading. Our messaging about this hasn’t been very consistent in the past. Suspense for Data Fetching is still experimental, so you can expect our recommendations to change over time as we learn more from production usage and understand the problem space better.

## [](#traditional-approaches-vs-suspense)Traditional Approaches vs Suspense

We could introduce Suspense without mentioning the popular data fetching approaches. However, this makes it more difficult to see which problems Suspense solves, why these problems are worth solving, and how Suspense is different from the existing solutions.

Instead, we’ll look at Suspense as a logical next step in a sequence of approaches:

* **Fetch-on-render (for example, `fetch` in `useEffect`):** Start rendering components. Each of these components may trigger data fetching in their effects and lifecycle methods. This approach often leads to “waterfalls”.
* **Fetch-then-render (for example, Relay without Suspense):** Start fetching all the data for the next screen as early as possible. When the data is ready, render the new screen. We can’t do anything until the data arrives.
* **Render-as-you-fetch (for example, Relay with Suspense):** Start fetching all the required data for the next screen as early as possible, and start rendering the new screen *immediately — before we get a network response*. As data streams in, React retries rendering components that still need data until they’re all ready.

> Note
>
> This is a bit simplified, and in practice solutions tend to use a mix of different approaches. Still, we will look at them in isolation to better contrast their tradeoffs.

To compare these approaches, we’ll implement a profile page with each of them.

### [](#approach-1-fetch-on-render-not-using-suspense)Approach 1: Fetch-on-Render (not using Suspense)

A common way to fetch data in React apps today is to use an effect:

```
// In a function component:
useEffect(() => {
  fetchSomething();
}, []);

// Or, in a class component:
componentDidMount() {
  fetchSomething();
}
```

We call this approach “fetch-on-render” because it doesn’t start fetching until *after* the component has rendered on the screen. This leads to a problem known as a “waterfall”.

Consider these `<ProfilePage>` and `<ProfileTimeline>` components:

```
function ProfilePage() {
  const [user, setUser] = useState(null);

  useEffect(() => {    fetchUser().then(u => setUser(u));  }, []);
  if (user === null) {
    return <p>Loading profile...</p>;
  }
  return (
    <>
      <h1>{user.name}</h1>
      <ProfileTimeline />
    </>
  );
}

function ProfileTimeline() {
  const [posts, setPosts] = useState(null);

  useEffect(() => {    fetchPosts().then(p => setPosts(p));  }, []);
  if (posts === null) {
    return <h2>Loading posts...</h2>;
  }
  return (
    <ul>
      {posts.map(post => (
        <li key={post.id}>{post.text}</li>
      ))}
    </ul>
  );
}
```

**[Try it on CodeSandbox](https://codesandbox.io/s/fast-glade-rqnhtt)**

If you run this code and watch the console logs, you’ll notice the sequence is:

1. We start fetching user details
2. We wait…
3. We finish fetching user details
4. We start fetching posts
5. We wait…
6. We finish fetching posts

If fetching user details takes three seconds, we’ll only *start* fetching the posts after three seconds! That’s a “waterfall”: an unintentional *sequence* that should have been parallelized.

Waterfalls are common in code that fetches data on render. They’re possible to solve, but as the product grows, many people prefer to use a solution that guards against this problem.

### [](#approach-2-fetch-then-render-not-using-suspense)Approach 2: Fetch-Then-Render (not using Suspense)

Libraries can prevent waterfalls by offering a more centralized way to do data fetching. For example, Relay solves this problem by moving the information about the data a component needs to statically analyzable *fragments*, which later get composed into a single query.

On this page, we don’t assume knowledge of Relay, so we won’t be using it for this example. Instead, we’ll write something similar manually by combining our data fetching methods:

```
function fetchProfileData() {
  return Promise.all([
    fetchUser(),
    fetchPosts()
  ]).then(([user, posts]) => {
    return {user, posts};
  })
}
```

In this example, `<ProfilePage>` waits for both requests but starts them in parallel:

```
// Kick off fetching as early as possibleconst promise = fetchProfileData();
function ProfilePage() {
  const [user, setUser] = useState(null);
  const [posts, setPosts] = useState(null);

  useEffect(() => {    promise.then(data => {      setUser(data.user);      setPosts(data.posts);    });  }, []);
  if (user === null) {
    return <p>Loading profile...</p>;
  }
  return (
    <>
      <h1>{user.name}</h1>
      <ProfileTimeline posts={posts} />
    </>
  );
}

// The child doesn't trigger fetching anymore
function ProfileTimeline({ posts }) {
  if (posts === null) {
    return <h2>Loading posts...</h2>;
  }
  return (
    <ul>
      {posts.map(post => (
        <li key={post.id}>{post.text}</li>
      ))}
    </ul>
  );
}
```

**[Try it on CodeSandbox](https://codesandbox.io/s/hopeful-lake-loddz9)**

The event sequence now becomes like this:

1. We start fetching user details
2. We start fetching posts
3. We wait…
4. We finish fetching user details
5. We finish fetching posts

We’ve solved the previous network “waterfall”, but accidentally introduced a different one. We wait for *all* data to come back with `Promise.all()` inside `fetchProfileData`, so now we can’t render profile details until the posts have been fetched too. We have to wait for both.

Of course, this is possible to fix in this particular example. We could remove the `Promise.all()` call, and wait for both Promises separately. However, this approach gets progressively more difficult as the complexity of our data and component tree grows. It’s hard to write reliable components when arbitrary parts of the data tree may be missing or stale. So fetching all data for the new screen and *then* rendering is often a more practical option.

### [](#approach-3-render-as-you-fetch-using-suspense)Approach 3: Render-as-You-Fetch (using Suspense)

In the previous approach, we fetched data before we called `setState`:

1. Start fetching
2. Finish fetching
3. Start rendering

With Suspense, we still start fetching first, but we flip the last two steps around:

1. Start fetching
2. **Start rendering**
3. **Finish fetching**

**With Suspense, we don’t wait for the response to come back before we start rendering.** In fact, we start rendering *pretty much immediately* after kicking off the network request:

```
// This is not a Promise. It's a special object from our Suspense integration.
const resource = fetchProfileData();
function ProfilePage() {
  return (
    <Suspense fallback={<h1>Loading profile...</h1>}>
      <ProfileDetails />
      <Suspense fallback={<h1>Loading posts...</h1>}>
        <ProfileTimeline />
      </Suspense>
    </Suspense>
  );
}

function ProfileDetails() {
  // Try to read user info, although it might not have loaded yet
  const user = resource.user.read();  return <h1>{user.name}</h1>;
}

function ProfileTimeline() {
  // Try to read posts, although they might not have loaded yet
  const posts = resource.posts.read();  return (
    <ul>
      {posts.map(post => (
        <li key={post.id}>{post.text}</li>
      ))}
    </ul>
  );
}
```

**[Try it on CodeSandbox](https://codesandbox.io/s/frosty-hermann-bztrp)**

Here’s what happens when we render `<ProfilePage>` on the screen:

1. We’ve already kicked off the requests in `fetchProfileData()`. It gave us a special “resource” instead of a Promise. In a realistic example, it would be provided by our data library’s Suspense integration, like Relay.
2. React tries to render `<ProfilePage>`. It returns `<ProfileDetails>` and `<ProfileTimeline>` as children.
3. React tries to render `<ProfileDetails>`. It calls `resource.user.read()`. None of the data is fetched yet, so this component “suspends”. React skips over it, and tries rendering other components in the tree.
4. React tries to render `<ProfileTimeline>`. It calls `resource.posts.read()`. Again, there’s no data yet, so this component also “suspends”. React skips over it too, and tries rendering other components in the tree.
5. There’s nothing left to try rendering. Because `<ProfileDetails>` suspended, React shows the closest `<Suspense>` fallback above it in the tree: `<h1>Loading profile...</h1>`. We’re done for now.

This `resource` object represents the data that isn’t there yet, but might eventually get loaded. When we call `read()`, we either get the data, or the component “suspends”.

**As more data streams in, React will retry rendering, and each time it might be able to progress “deeper”.** When `resource.user` is fetched, the `<ProfileDetails>` component will render successfully and we’ll no longer need the `<h1>Loading profile...</h1>` fallback. Eventually, we’ll get all the data, and there will be no fallbacks on the screen.

This has an interesting implication. Even if we use a GraphQL client that collects all data requirements in a single request, *streaming the response lets us show more content sooner*. Because we render-*as-we-fetch* (as opposed to *after* fetching), if `user` appears in the response earlier than `posts`, we’ll be able to “unlock” the outer `<Suspense>` boundary before the response even finishes. We might have missed this earlier, but even the fetch-then-render solution contained a waterfall: between fetching and rendering. Suspense doesn’t inherently suffer from this waterfall, and libraries like Relay take advantage of this.

Note how we eliminated the `if (...)` “is loading” checks from our components. This doesn’t only remove boilerplate code, but it also simplifies making quick design changes. For example, if we wanted profile details and posts to always “pop in” together, we could delete the `<Suspense>` boundary between them. Or we could make them independent from each other by giving each *its own* `<Suspense>` boundary. Suspense lets us change the granularity of our loading states and orchestrate their sequencing without invasive changes to our code.

## [](#start-fetching-early)Start Fetching Early

If you’re working on a data fetching library, there’s a crucial aspect of Render-as-You-Fetch you don’t want to miss. **We kick off fetching *before* rendering.** Look at this code example closer:

```
// Start fetching early!
const resource = fetchProfileData();

// ...

function ProfileDetails() {
  // Try to read user info
  const user = resource.user.read();
  return <h1>{user.name}</h1>;
}
```

**[Try it on CodeSandbox](https://codesandbox.io/s/frosty-hermann-bztrp)**

Note that the `read()` call in this example doesn’t *start* fetching. It only tries to read the data that is **already being fetched**. This difference is crucial to creating fast applications with Suspense. We don’t want to delay loading data until a component starts rendering. As a data fetching library author, you can enforce this by making it impossible to get a `resource` object without also starting a fetch. Every demo on this page using our “fake API” enforces this.

You might object that fetching “at the top level” like in this example is impractical. What are we going to do if we navigate to another profile’s page? We might want to fetch based on props. The answer to this is **we want to start fetching in the event handlers instead**. Here is a simplified example of navigating between user’s pages:

```
// First fetch: as soon as possibleconst initialResource = fetchProfileData(0);
function App() {
  const [resource, setResource] = useState(initialResource);
  return (
    <>
      <button onClick={() => {
        const nextUserId = getNextId(resource.userId);
        // Next fetch: when the user clicks        setResource(fetchProfileData(nextUserId));      }}>
        Next
      </button>
      <ProfilePage resource={resource} />
    </>
  );
}
```

**[Try it on CodeSandbox](https://codesandbox.io/s/sparkling-field-41z4r3)**

With this approach, we can **fetch code and data in parallel**. When we navigate between pages, we don’t need to wait for a page’s code to load to start loading its data. We can start fetching both code and data at the same time (during the link click), delivering a much better user experience.

This poses a question of how do we know *what* to fetch before rendering the next screen. There are several ways to solve this (for example, by integrating data fetching closer with your routing solution). If you work on a data fetching library, [Building Great User Experiences with Concurrent Mode and Suspense](/blog/2019/11/06/building-great-user-experiences-with-concurrent-mode-and-suspense.html) presents a deep dive on how to accomplish this and why it’s important.

### [](#were-still-figuring-this-out)We’re Still Figuring This Out

Suspense itself as a mechanism is flexible and doesn’t have many constraints. Product code needs to be more constrained to ensure no waterfalls, but there are different ways to provide these guarantees. Some questions that we’re currently exploring include:

* Fetching early can be cumbersome to express. How do we make it easier to avoid waterfalls?
* When we fetch data for a page, can the API encourage including data for instant transitions *from* it?
* What is the lifetime of a response? Should caching be global or local? Who manages the cache?
* Can Proxies help express lazy-loaded APIs without inserting `read()` calls everywhere?
* What would the equivalent of composing GraphQL queries look like for arbitrary Suspense data?

Relay has its own answers to some of these questions. There is certainly more than a single way to do it, and we’re excited to see what new ideas the React community comes up with.

## [](#suspense-and-race-conditions)Suspense and Race Conditions

Race conditions are bugs that happen due to incorrect assumptions about the order in which our code may run. Fetching data in the `useEffect` Hook or in class lifecycle methods like `componentDidUpdate` often leads to them. Suspense can help here, too — let’s see how.

To demonstrate the issue, we will add a top-level `<App>` component that renders our `<ProfilePage>` with a button that lets us **switch between different profiles**:

```
function getNextId(id) {
  // ...
}

function App() {
  const [id, setId] = useState(0);
  return (
    <>
      <button onClick={() => setId(getNextId(id))}>        Next      </button>      <ProfilePage id={id} />
    </>
  );
}
```

Let’s compare how different data fetching strategies deal with this requirement.

### [](#race-conditions-with-useeffect)Race Conditions with `useEffect`

First, we’ll try a version of our original “fetch in effect” example. We’ll modify it to pass an `id` parameter from the `<ProfilePage>` props to `fetchUser(id)` and `fetchPosts(id)`:

```
function ProfilePage({ id }) {  const [user, setUser] = useState(null);

  useEffect(() => {
    fetchUser(id).then(u => setUser(u));  }, [id]);
  if (user === null) {
    return <p>Loading profile...</p>;
  }
  return (
    <>
      <h1>{user.name}</h1>
      <ProfileTimeline id={id} />    </>
  );
}

function ProfileTimeline({ id }) {  const [posts, setPosts] = useState(null);

  useEffect(() => {
    fetchPosts(id).then(p => setPosts(p));  }, [id]);
  if (posts === null) {
    return <h2>Loading posts...</h2>;
  }
  return (
    <ul>
      {posts.map(post => (
        <li key={post.id}>{post.text}</li>
      ))}
    </ul>
  );
}
```

**[Try it on CodeSandbox](https://codesandbox.io/s/beautiful-mendeleev-qwyxzg)**

Note how we also changed the effect dependencies from `[]` to `[id]` — because we want the effect to re-run when the `id` changes. Otherwise, we wouldn’t refetch new data.

If we try this code, it might seem like it works at first. However, if we randomize the delay time in our “fake API” implementation and press the “Next” button fast enough, we’ll see from the console logs that something is going very wrong. **Requests from the previous profiles may sometimes “come back” after we’ve already switched the profile to another ID — and in that case they can overwrite the new state with a stale response for a different ID.**

This problem is possible to fix (you could use the effect cleanup function to either ignore or cancel stale requests), but it’s unintuitive and difficult to debug.

### [](#race-conditions-with-componentdidupdate)Race Conditions with `componentDidUpdate`

One might think that this is a problem specific to `useEffect` or Hooks. Maybe if we port this code to classes or use convenient syntax like `async` / `await`, it will solve the problem?

Let’s try that:

```
class ProfilePage extends React.Component {
  state = {
    user: null,
  };
  componentDidMount() {
    this.fetchData(this.props.id);
  }
  componentDidUpdate(prevProps) {
    if (prevProps.id !== this.props.id) {
      this.fetchData(this.props.id);
    }
  }
  async fetchData(id) {
    const user = await fetchUser(id);
    this.setState({ user });
  }
  render() {
    const { id } = this.props;
    const { user } = this.state;
    if (user === null) {
      return <p>Loading profile...</p>;
    }
    return (
      <>
        <h1>{user.name}</h1>
        <ProfileTimeline id={id} />
      </>
    );
  }
}

class ProfileTimeline extends React.Component {
  state = {
    posts: null,
  };
  componentDidMount() {
    this.fetchData(this.props.id);
  }
  componentDidUpdate(prevProps) {
    if (prevProps.id !== this.props.id) {
      this.fetchData(this.props.id);
    }
  }
  async fetchData(id) {
    const posts = await fetchPosts(id);
    this.setState({ posts });
  }
  render() {
    const { posts } = this.state;
    if (posts === null) {
      return <h2>Loading posts...</h2>;
    }
    return (
      <ul>
        {posts.map(post => (
          <li key={post.id}>{post.text}</li>
        ))}
      </ul>
    );
  }
}
```

**[Try it on CodeSandbox](https://codesandbox.io/s/async-wind-9o4ojn)**

This code is deceptively easy to read.

Unfortunately, neither using a class nor the `async` / `await` syntax helped us solve this problem. This version suffers from exactly the same race conditions, for the same reasons.

### [](#the-problem)The Problem

React components have their own “lifecycle”. They may receive props or update state at any point in time. However, each asynchronous request *also* has its own “lifecycle”. It starts when we kick it off, and finishes when we get a response. The difficulty we’re experiencing is “synchronizing” several processes in time that affect each other. This is hard to think about.

### [](#solving-race-conditions-with-suspense)Solving Race Conditions with Suspense

Let’s rewrite this example again, but using Suspense only:

```
const initialResource = fetchProfileData(0);

function App() {
  const [resource, setResource] = useState(initialResource);
  return (
    <>
      <button onClick={() => {
        const nextUserId = getNextId(resource.userId);
        setResource(fetchProfileData(nextUserId));
      }}>
        Next
      </button>
      <ProfilePage resource={resource} />
    </>
  );
}

function ProfilePage({ resource }) {
  return (
    <Suspense fallback={<h1>Loading profile...</h1>}>
      <ProfileDetails resource={resource} />
      <Suspense fallback={<h1>Loading posts...</h1>}>
        <ProfileTimeline resource={resource} />
      </Suspense>
    </Suspense>
  );
}

function ProfileDetails({ resource }) {
  const user = resource.user.read();
  return <h1>{user.name}</h1>;
}

function ProfileTimeline({ resource }) {
  const posts = resource.posts.read();
  return (
    <ul>
      {posts.map(post => (
        <li key={post.id}>{post.text}</li>
      ))}
    </ul>
  );
}
```

**[Try it on CodeSandbox](https://codesandbox.io/s/sparkling-field-41z4r3)**

In the previous Suspense example, we only had one `resource`, so we held it in a top-level variable. Now that we have multiple resources, we moved it to the `<App>`’s component state:

```
const initialResource = fetchProfileData(0);

function App() {
  const [resource, setResource] = useState(initialResource);
```

When we click “Next”, the `<App>` component kicks off a request for the next profile, and passes *that* object down to the `<ProfilePage>` component:

```
  <>
    <button onClick={() => {
      const nextUserId = getNextId(resource.userId);
      setResource(fetchProfileData(nextUserId));    }}>
      Next
    </button>
    <ProfilePage resource={resource} />  </>
```

Again, notice that **we’re not waiting for the response to set the state. It’s the other way around: we set the state (and start rendering) immediately after kicking off a request**. As soon as we have more data, React “fills in” the content inside `<Suspense>` components.

This code is very readable, but unlike the examples earlier, the Suspense version doesn’t suffer from race conditions. You might be wondering why. The answer is that in the Suspense version, we don’t have to think about *time* as much in our code. Our original code with race conditions needed to set the state *at the right moment later*, or otherwise it would be wrong. But with Suspense, we set the state *immediately* — so it’s harder to mess it up.

## [](#handling-errors)Handling Errors

When we write code with Promises, we might use `catch()` to handle errors. How does this work with Suspense, given that we don’t *wait* for Promises to start rendering?

With Suspense, handling fetching errors works the same way as handling rendering errors — you can render an [error boundary](/docs/error-boundaries.html) anywhere to “catch” errors in components below.

First, we’ll define an error boundary component to use across our project:

```
// Error boundaries currently have to be classes.
class ErrorBoundary extends React.Component {
  state = { hasError: false, error: null };
  static getDerivedStateFromError(error) {
    return {
      hasError: true,
      error
    };
  }
  render() {
    if (this.state.hasError) {
      return this.props.fallback;
    }
    return this.props.children;
  }
}
```

And then we can put it anywhere in the tree to catch errors:

```
function ProfilePage() {
  return (
    <Suspense fallback={<h1>Loading profile...</h1>}>
      <ProfileDetails />
      <ErrorBoundary fallback={<h2>Could not fetch posts.</h2>}>        <Suspense fallback={<h1>Loading posts...</h1>}>
          <ProfileTimeline />
        </Suspense>
      </ErrorBoundary>    </Suspense>
  );
}
```

**[Try it on CodeSandbox](https://codesandbox.io/s/sparkling-rgb-r5vfhs)**

It would catch both rendering errors *and* errors from Suspense data fetching. We can have as many error boundaries as we like but it’s best to [be intentional](https://aweary.dev/fault-tolerance-react/) about their placement.

## [](#next-steps)Next Steps

We’ve now covered the basics of Suspense for Data Fetching! Importantly, we now better understand *why* Suspense works this way, and how it fits into the data fetching space.

Suspense answers some questions, but it also poses new questions of its own:

* If some component “suspends”, does the app freeze? How to avoid this?
* What if we want to show a spinner in a different place than “above” the component in a tree?
* If we intentionally *want* to show an inconsistent UI for a small period of time, can we do that?
* Instead of showing a spinner, can we add a visual effect like “greying out” the current screen?

To answer these questions, we will refer to the next section on [Concurrent UI Patterns](/docs/concurrent-mode-patterns.html).

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/concurrent-mode-suspense.md)

----
url: https://legacy.reactjs.org/blog/2018/10/01/create-react-app-v2.html
----

October 01, 2018 by [Joe Haddad](https://twitter.com/timer150) and [Dan Abramov](https://twitter.com/dan_abramov)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

Create React App 2.0 has been released today, and it brings a year’s worth of improvements in a single dependency update.

While React itself [doesn’t require any build dependencies](/docs/create-a-new-react-app.html), it can be challenging to write a complex app without a fast test runner, a production minifier, and a modular codebase. Since the very first release, the goal of [Create React App](https://github.com/facebook/create-react-app) has been to help you focus on what matters the most — your application code — and to handle build and testing setup for you.

Many of the tools it relies on have since released new versions containing new features and performance improvements: [Babel 7](https://babeljs.io/blog/2018/08/27/7.0.0), [webpack 4](https://medium.com/webpack/webpack-4-released-today-6cdb994702d4), and [Jest 23](https://jestjs.io/blog/2018/05/29/jest-23-blazing-fast-delightful-testing.html). However, updating them manually and making them work well together takes a lot of effort. And this is exactly what [Create React App 2.0 contributors](https://github.com/facebook/create-react-app/graphs/contributors) have been busy with for the past few months: **migrating the configuration and dependencies so that you don’t need to do it yourself.**

Now that Create React App 2.0 is out of beta, let’s see what’s new and how you can try it!

> Note
>
> Don’t feel pressured to upgrade anything. If you’re satisfied with the current feature set, its performance, and reliability, you can keep using the version you’re currently at! It might also be a good idea to let the 2.0 release stabilize a little bit before switching to it in production.

## [](#whats-new)What’s New

Here’s a short summary of what’s new in this release:

* 🎉 More styling options: you can use [Sass](https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#adding-a-sass-stylesheet) and [CSS Modules](https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#adding-a-css-modules-stylesheet) out of the box.
* 🐠 We updated to [Babel 7](https://babeljs.io/blog/2018/08/27/7.0.0), including support for the [React fragment syntax](/docs/fragments.html#short-syntax) and many bugfixes.
* 📦 We updated to [webpack 4](https://medium.com/webpack/webpack-4-released-today-6cdb994702d4), which automatically splits JS bundles more intelligently.
* 🃏 We updated to [Jest 23](https://jestjs.io/blog/2018/05/29/jest-23-blazing-fast-delightful-testing.html), which includes an [interactive mode](https://jestjs.io/blog/2018/05/29/jest-23-blazing-fast-delightful-testing#interactive-snapshot-mode) for reviewing snapshots.
* 💄 We added [PostCSS](https://preset-env.cssdb.org/features#stage-3) so you can use new CSS features in old browsers.
* 💎 You can use [Apollo](https://github.com/leoasis/graphql-tag.macro#usage), [Relay Modern](https://github.com/facebook/relay/pull/2171#issuecomment-411459604), [MDX](https://github.com/facebook/create-react-app/issues/5149#issuecomment-425396995), and other third-party [Babel Macros](https://babeljs.io/blog/2017/09/11/zero-config-with-babel-macros) transforms.
* 🌠 You can now [import an SVG as a React component](https://facebook.github.io/create-react-app/docs/adding-images-fonts-and-files#adding-svgs), and use it in JSX.
* 🐈 You can try the experimental [Yarn Plug’n’Play mode](https://github.com/yarnpkg/rfcs/pull/101) that removes `node_modules`.
* 🕸 You can now [plug your own proxy implementation](https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#configuring-the-proxy-manually) in development to match your backend API.
* 🚀 You can now use [packages written for latest Node versions](https://github.com/sindresorhus/ama/issues/446#issuecomment-281014491) without breaking the build.
* ✂️ You can now optionally get a smaller CSS bundle if you only plan to target modern browsers.
* 👷‍♀️ Service workers are now opt-in and are built using Google’s [Workbox](https://developers.google.com/web/tools/workbox/).

**All of these features work out of the box** — to enable them, follow the below instructions.

## [](#starting-a-project-with-create-react-app-20)Starting a Project with Create React App 2.0

You don’t need to update anything special. Starting from today, when you run `create-react-app` it will use the 2.0 version of the template by default. Have fun!

If you want to **use the old 1.x template** for some reason, you can do that by passing `--scripts-version=react-scripts@1.x` as an argument to `create-react-app`.

## [](#updating-a-project-to-create-react-app-20)Updating a Project to Create React App 2.0

Upgrading a non-ejected project to Create React App 2.0 should usually be straightforward. Open `package.json` in the root of your project and find `react-scripts` there.

Then change its version to `2.0.3`:

```
  // ... other dependencies ...
  "react-scripts": "2.0.3"
```

Run `npm install` (or `yarn`, if you use it). **For many projects, this one-line change is sufficient to upgrade!**

> working here... thanks for all the new functionality 👍
>
> — Stephen Haney (@sdothaney) [October 1, 2018](https://twitter.com/sdothaney/status/1046822703116607490?ref_src=twsrc%5Etfw)

Here are a few more tips to get you started.

**When you run `npm start` for the first time after the upgrade,** you’ll get a prompt asking about which browsers you’d like to support. Press `y` to accept the default ones. They’ll be written to your `package.json` and you can edit them any time. Create React App will use this information to produce smaller or polyfilled CSS bundles depending on whether you target modern browsers or older browsers.

**If `npm start` still doesn’t quite work for you after the upgrade,** [check out the more detailed migration instructions in the release notes](https://github.com/facebook/create-react-app/releases/tag/v2.0.3). There *are* a few breaking changes in this release but the scope of them is limited, so they shouldn’t take more than a few hours to sort out. Note that **[support for older browsers](https://github.com/facebook/create-react-app/blob/master/packages/react-app-polyfill/README.md) is now opt-in** to reduce the polyfill size.

**If you previously ejected but now want to upgrade,** one common solution is to find the commits where you ejected (and any subsequent commits changing the configuration), revert them, upgrade, and later optionally eject again. It’s also possible that the feature you ejected for (maybe Sass or CSS Modules?) is now supported out of the box.

> Note
>
> Due to a possible bug in npm, you might see warnings about unsatisfied peer dependencies. You should be able to ignore them. As far as we’re aware, this issue isn’t present with Yarn.

## [](#breaking-changes)Breaking Changes

Here’s a short list of breaking changes in this release:

* Node 6 is no longer supported.
* Support for older browsers (such as IE 9 to IE 11) is now opt-in with a [separate package](https://github.com/facebook/create-react-app/tree/master/packages/react-app-polyfill).
* Code-splitting with `import()` now behaves closer to specification, while `require.ensure()` is disabled.
* The default Jest environment now includes jsdom.
* Support for specifying an object as `proxy` setting was replaced with support for a custom proxy module.
* Support for `.mjs` extension was removed until the ecosystem around it stabilizes.
* PropTypes definitions are automatically stripped out of the production builds.

If either of these points affects you, [2.0.3 release notes](https://github.com/facebook/create-react-app/releases/tag/v2.0.3) contain more detailed instructions.

## [](#learn-more)Learn More

You can find the full changelog in the [release notes](https://github.com/facebook/create-react-app/releases/tag/v2.0.3). This was a large release, and we may have missed something. Please report any problems to our [issue tracker](https://github.com/facebook/create-react-app/issues/new) and we’ll try to help.

> Note
>
> If you’ve been using 2.x alpha versions, we provide [separate migration instructions](https://gist.github.com/gaearon/8650d1c70e436e5eff01f396dffc4114) for them.

## [](#thanks)Thanks

This release wouldn’t be possible without our wonderful community of contributors. We’d like to thank [Andreas Cederström](https://github.com/andriijas), [Clement Hoang](https://github.com/clemmy), [Brian Ng](https://github.com/existentialism), [Kent C. Dodds](https://github.com/kentcdodds), [Ade Viankakrisna Fadlil](https://github.com/viankakrisna), [Andrey Sitnik](https://github.com/ai), [Ro Savage](https://github.com/ro-savage), [Fabiano Brito](https://github.com/Fabianopb), [Ian Sutherland](https://github.com/iansu), [Pete Nykänen](https://github.com/petetnt), [Jeffrey Posnick](https://github.com/jeffposnick), [Jack Zhao](https://github.com/bugzpodder), [Tobias Koppers](https://github.com/sokra), [Henry Zhu](https://github.com/hzoo), [Maël Nison](https://github.com/arcanis), [XiaoYan Li](https://github.com/lixiaoyan), [Marko Trebizan](https://github.com/themre), [Marek Suscak](https://github.com/mareksuscak), [Mikhail Osher](https://github.com/miraage), and many others who provided feedback and testing for this release.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2018-10-01-create-react-app-v2.md)

----
url: https://legacy.reactjs.org/docs/reconciliation.html
----

> These docs are old and won’t be updated. Go to [react.dev](https://react.dev/) for the new React docs.
>
> These new documentation pages teach modern React and include live examples:
>
> * [Preserving and Resetting State](https://react.dev/learn/preserving-and-resetting-state)

React provides a declarative API so that you don’t have to worry about exactly what changes on every update. This makes writing applications a lot easier, but it might not be obvious how this is implemented within React. This article explains the choices we made in React’s “diffing” algorithm so that component updates are predictable while being fast enough for high-performance apps.

## [](#motivation)Motivation

When you use React, at a single point in time you can think of the `render()` function as creating a tree of React elements. On the next state or props update, that `render()` function will return a different tree of React elements. React then needs to figure out how to efficiently update the UI to match the most recent tree.

There are some generic solutions to this algorithmic problem of generating the minimum number of operations to transform one tree into another. However, the [state of the art algorithms](https://grfia.dlsi.ua.es/ml/algorithms/references/editsurvey_bille.pdf) have a complexity in the order of O(n3) where n is the number of elements in the tree.

If we used this in React, displaying 1000 elements would require in the order of one billion comparisons. This is far too expensive. Instead, React implements a heuristic O(n) algorithm based on two assumptions:

1. Two elements of different types will produce different trees.
2. The developer can hint at which child elements may be stable across different renders with a `key` prop.

In practice, these assumptions are valid for almost all practical use cases.

## [](#the-diffing-algorithm)The Diffing Algorithm

When diffing two trees, React first compares the two root elements. The behavior is different depending on the types of the root elements.

### [](#elements-of-different-types)Elements Of Different Types

Whenever the root elements have different types, React will tear down the old tree and build the new tree from scratch. Going from `<a>` to `<img>`, or from `<Article>` to `<Comment>`, or from `<Button>` to `<div>` - any of those will lead to a full rebuild.

When tearing down a tree, old DOM nodes are destroyed. Component instances receive `componentWillUnmount()`. When building up a new tree, new DOM nodes are inserted into the DOM. Component instances receive `UNSAFE_componentWillMount()` and then `componentDidMount()`. Any state associated with the old tree is lost.

Any components below the root will also get unmounted and have their state destroyed. For example, when diffing:

```
<div>
  <Counter />
</div>

<span>
  <Counter />
</span>
```

This will destroy the old `Counter` and remount a new one.

> Note:
>
> This method is considered legacy and you should [avoid it](/blog/2018/03/27/update-on-async-rendering.html) in new code:
>
> * `UNSAFE_componentWillMount()`

### [](#dom-elements-of-the-same-type)DOM Elements Of The Same Type

When comparing two React DOM elements of the same type, React looks at the attributes of both, keeps the same underlying DOM node, and only updates the changed attributes. For example:

```
<div className="before" title="stuff" />

<div className="after" title="stuff" />
```

By comparing these two elements, React knows to only modify the `className` on the underlying DOM node.

When updating `style`, React also knows to update only the properties that changed. For example:

```
<div style={{color: 'red', fontWeight: 'bold'}} />

<div style={{color: 'green', fontWeight: 'bold'}} />
```

When converting between these two elements, React knows to only modify the `color` style, not the `fontWeight`.

After handling the DOM node, React then recurses on the children.

### [](#component-elements-of-the-same-type)Component Elements Of The Same Type

When a component updates, the instance stays the same, so that state is maintained across renders. React updates the props of the underlying component instance to match the new element, and calls `UNSAFE_componentWillReceiveProps()`, `UNSAFE_componentWillUpdate()` and `componentDidUpdate()` on the underlying instance.

Next, the `render()` method is called and the diff algorithm recurses on the previous result and the new result.

> Note:
>
> These methods are considered legacy and you should [avoid them](/blog/2018/03/27/update-on-async-rendering.html) in new code:
>
> * `UNSAFE_componentWillUpdate()`
> * `UNSAFE_componentWillReceiveProps()`

### [](#recursing-on-children)Recursing On Children

By default, when recursing on the children of a DOM node, React just iterates over both lists of children at the same time and generates a mutation whenever there’s a difference.

For example, when adding an element at the end of the children, converting between these two trees works well:

```
<ul>
  <li>first</li>
  <li>second</li>
</ul>

<ul>
  <li>first</li>
  <li>second</li>
  <li>third</li>
</ul>
```

React will match the two `<li>first</li>` trees, match the two `<li>second</li>` trees, and then insert the `<li>third</li>` tree.

If you implement it naively, inserting an element at the beginning has worse performance. For example, converting between these two trees works poorly:

```
<ul>
  <li>Duke</li>
  <li>Villanova</li>
</ul>

<ul>
  <li>Connecticut</li>
  <li>Duke</li>
  <li>Villanova</li>
</ul>
```

React will mutate every child instead of realizing it can keep the `<li>Duke</li>` and `<li>Villanova</li>` subtrees intact. This inefficiency can be a problem.

### [](#keys)Keys

In order to solve this issue, React supports a `key` attribute. When children have keys, React uses the key to match children in the original tree with children in the subsequent tree. For example, adding a `key` to our inefficient example above can make the tree conversion efficient:

```
<ul>
  <li key="2015">Duke</li>
  <li key="2016">Villanova</li>
</ul>

<ul>
  <li key="2014">Connecticut</li>
  <li key="2015">Duke</li>
  <li key="2016">Villanova</li>
</ul>
```

Now React knows that the element with key `'2014'` is the new one, and the elements with the keys `'2015'` and `'2016'` have just moved.

In practice, finding a key is usually not hard. The element you are going to display may already have a unique ID, so the key can just come from your data:

```
<li key={item.id}>{item.name}</li>
```

When that’s not the case, you can add a new ID property to your model or hash some parts of the content to generate a key. The key only has to be unique among its siblings, not globally unique.

As a last resort, you can pass an item’s index in the array as a key. This can work well if the items are never reordered, but reorders will be slow.

Reorders can also cause issues with component state when indexes are used as keys. Component instances are updated and reused based on their key. If the key is an index, moving an item changes it. As a result, component state for things like uncontrolled inputs can get mixed up and updated in unexpected ways.

Here is [an example of the issues that can be caused by using indexes as keys](/redirect-to-codepen/reconciliation/index-used-as-key) on CodePen, and here is [an updated version of the same example showing how not using indexes as keys will fix these reordering, sorting, and prepending issues](/redirect-to-codepen/reconciliation/no-index-used-as-key).

## [](#tradeoffs)Tradeoffs

It is important to remember that the reconciliation algorithm is an implementation detail. React could rerender the whole app on every action; the end result would be the same. Just to be clear, rerender in this context means calling `render` for all components, it doesn’t mean React will unmount and remount them. It will only apply the differences following the rules stated in the previous sections.

We are regularly refining the heuristics in order to make common use cases faster. In the current implementation, you can express the fact that a subtree has been moved amongst its siblings, but you cannot tell that it has moved somewhere else. The algorithm will rerender that full subtree.

Because React relies on heuristics, if the assumptions behind them are not met, performance will suffer.

1. The algorithm will not try to match subtrees of different component types. If you see yourself alternating between two component types with very similar output, you may want to make it the same type. In practice, we haven’t found this to be an issue.
2. Keys should be stable, predictable, and unique. Unstable keys (like those produced by `Math.random()`) will cause many component instances and DOM nodes to be unnecessarily recreated, which can cause performance degradation and lost state in child components.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/reconciliation.md)

----
url: https://legacy.reactjs.org/blog/2014/04/04/reactnet.html
----

April 04, 2014 by [Daniel Lo Nigro](https://d.sb/)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

Today we’re happy to announce the initial release of [ReactJS.NET](http://reactjs.net/), which makes it easier to use React and JSX in .NET applications, focusing specifically on ASP.NET MVC web applications. It has several purposes:

* On-the-fly JSX to JavaScript compilation. Simply reference JSX files and they will be compiled and cached server-side.

  ```
  <script src="@Url.Content("/Scripts/HelloWorld.jsx")"></script>
  ```

* JSX to JavaScript compilation via popular minification/combination libraries (Cassette and ASP.NET Bundling and Minification). This is suggested for production websites.

* Server-side component rendering to make your initial render super fast.

Even though we are focusing on ASP.NET MVC, ReactJS.NET can also be used in Web Forms applications as well as non-web applications (for example, in build scripts). ReactJS.NET currently only works on Microsoft .NET but we are working on support for Linux and Mac OS X via Mono as well.

## [](#installation)Installation

ReactJS.NET is packaged in NuGet. Simply run `Install-Package React.Mvc4` in the package manager console or search NuGet for “React” to install it. [See the documentation](http://reactjs.net/docs) for more information. The GitHub project contains [a sample website](https://github.com/reactjs/React.NET/tree/master/src/React.Sample.Mvc4) demonstrating all of the features.

Let us know what you think, and feel free to send through any feedback and report bugs [on GitHub](https://github.com/reactjs/React.NET).

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2014-04-04-reactnet.md)

----
url: https://react.dev/blog/2023/03/16/introducing-react-dev
----

[Blog](/blog)

# Introducing react.dev[](#undefined "Link for this heading")

March 16, 2023 by [Dan Abramov](https://bsky.app/profile/danabra.mov) and [Rachel Nabors](https://twitter.com/rachelnabors)

***

Today we are thrilled to launch [react.dev](https://react.dev), the new home for React and its documentation. In this post, we would like to give you a tour of the new site.

***

## tl;dr[](#tldr "Link for tl;dr ")

* The new React site ([react.dev](https://react.dev)) teaches modern React with function components and Hooks.
* We’ve included diagrams, illustrations, challenges, and over 600 new interactive examples.
* The previous React documentation site has now moved to [legacy.reactjs.org](https://legacy.reactjs.org).

## New site, new domain, new homepage[](#new-site-new-domain-new-homepage "Link for New site, new domain, new homepage ")

First, a little bit of housekeeping.

To celebrate the launch of the new docs and, more importantly, to clearly separate the old and the new content, we’ve moved to the shorter [react.dev](https://react.dev) domain. The old [reactjs.org](https://reactjs.org) domain will now redirect here.

The old React docs are now archived at [legacy.reactjs.org](https://legacy.reactjs.org). All existing links to the old content will automatically redirect there to avoid “breaking the web”, but the legacy site will not get many more updates.

Believe it or not, React will soon be ten years old. In JavaScript years, it’s like a whole century! We’ve [refreshed the React homepage](https://react.dev) to reflect why we think React is a great way to create user interfaces today, and updated the getting started guides to more prominently mention modern React-based frameworks.

If you haven’t seen the new homepage yet, check it out!

## Going all-in on modern React with Hooks[](#going-all-in-on-modern-react-with-hooks "Link for Going all-in on modern React with Hooks ")

When we released React Hooks in 2018, the Hooks docs assumed the reader is familiar with class components. This helped the community adopt Hooks very swiftly, but after a while the old docs failed to serve the new readers. New readers had to learn React twice: once with class components and then once again with Hooks.

**The new docs teach React with Hooks from the beginning.** The docs are divided in two main sections:

* **[Learn React](/learn)** is a self-paced course that teaches React from scratch.
* **[API Reference](/reference)** provides the details and usage examples for every React API.

Let’s have a closer look at what you can find in each section.

### Note

There are still a few rare class component use cases that do not yet have a Hook-based equivalent. Class components remain supported, and are documented in the [Legacy API](/reference/react/legacy) section of the new site.

## Quick start[](#quick-start "Link for Quick start ")

The Learn section begins with the [Quick Start](/learn) page. It is a short introductory tour of React. It introduces the syntax for concepts like components, props, and state, but doesn’t go into much detail on how to use them.

If you like to learn by doing, we recommend checking out the [Tic-Tac-Toe Tutorial](/learn/tutorial-tic-tac-toe) next. It walks you through building a little game with React, while teaching the skills you’ll use every day. Here’s what you’ll build:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

function Square({ value, onSquareClick }) {
  return (
    <button className="square" onClick={onSquareClick}>
      {value}
    </button>
  );
}

function Board({ xIsNext, squares, onPlay }) {
  function handleClick(i) {
    if (calculateWinner(squares) || squares[i]) {
      return;
    }
    const nextSquares = squares.slice();
    if (xIsNext) {
      nextSquares[i] = 'X';
    } else {
      nextSquares[i] = 'O';
    }
    onPlay(nextSquares);
  }

  const winner = calculateWinner(squares);
  let status;
  if (winner) {
    status = 'Winner: ' + winner;
  } else {
    status = 'Next player: ' + (xIsNext ? 'X' : 'O');
  }

  return (
    <>
      <div className="status">{status}</div>
      <div className="board-row">
        <Square value={squares[0]} onSquareClick={() => handleClick(0)} />
        <Square value={squares[1]} onSquareClick={() => handleClick(1)} />
        <Square value={squares[2]} onSquareClick={() => handleClick(2)} />
      </div>
      <div className="board-row">
        <Square value={squares[3]} onSquareClick={() => handleClick(3)} />
        <Square value={squares[4]} onSquareClick={() => handleClick(4)} />
        <Square value={squares[5]} onSquareClick={() => handleClick(5)} />
      </div>
      <div className="board-row">
        <Square value={squares[6]} onSquareClick={() => handleClick(6)} />
        <Square value={squares[7]} onSquareClick={() => handleClick(7)} />
        <Square value={squares[8]} onSquareClick={() => handleClick(8)} />
      </div>
    </>
  );
}

export default function Game() {
  const [history, setHistory] = useState([Array(9).fill(null)]);
  const [currentMove, setCurrentMove] = useState(0);
  const xIsNext = currentMove % 2 === 0;
  const currentSquares = history[currentMove];

  function handlePlay(nextSquares) {
    const nextHistory = [...history.slice(0, currentMove + 1), nextSquares];
    setHistory(nextHistory);
    setCurrentMove(nextHistory.length - 1);
  }

  function jumpTo(nextMove) {
    setCurrentMove(nextMove);
  }

  const moves = history.map((squares, move) => {
    let description;
    if (move > 0) {
      description = 'Go to move #' + move;
    } else {
      description = 'Go to game start';
    }
    return (
      <li key={move}>
        <button onClick={() => jumpTo(move)}>{description}</button>
      </li>
    );
  });

  return (
    <div className="game">
      <div className="game-board">
        <Board xIsNext={xIsNext} squares={currentSquares} onPlay={handlePlay} />
      </div>
      <div className="game-info">
        <ol>{moves}</ol>
      </div>
    </div>
  );
}

function calculateWinner(squares) {
  const lines = [
    [0, 1, 2],
    [3, 4, 5],
    [6, 7, 8],
    [0, 3, 6],
    [1, 4, 7],
    [2, 5, 8],
    [0, 4, 8],
    [2, 4, 6],
  ];
  for (let i = 0; i < lines.length; i++) {
    const [a, b, c] = lines[i];
    if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
      return squares[a];
    }
  }
  return null;
}
```

We’d also like to highlight [Thinking in React](/learn/thinking-in-react)—that’s the tutorial that made React “click” for many of us. **We’ve updated both of these classic tutorials to use function components and Hooks,** so they’re as good as new.

### Note

The example above is a *sandbox*. We’ve added a lot of sandboxes—over 600!—everywhere throughout the site. You can edit any sandbox, or press “Fork” in the upper right corner to open it in a separate tab. Sandboxes let you quickly play with the React APIs, explore your ideas, and check your understanding.

## Learn React step by step[](#learn-react-step-by-step "Link for Learn React step by step ")

We’d like everyone in the world to have an equal opportunity to learn React for free on their own.

This is why the Learn section is organized like a self-paced course split into chapters. The first two chapters describe the fundamentals of React. If you’re new to React, or want to refresh it in your memory, start here:

* **[Describing the UI](/learn/describing-the-ui)** teaches how to display information with components.
* **[Adding Interactivity](/learn/adding-interactivity)** teaches how to update the screen in response to user input.

The next two chapters are more advanced, and will give you a deeper insight into the trickier parts:

* **[Managing State](/learn/managing-state)** teaches how to organize your logic as your app grows in complexity.
* **[Escape Hatches](/learn/escape-hatches)** teaches how you can “step outside” React, and when it makes most sense to do so.

Every chapter consists of several related pages. Most of these pages teach a specific skill or a technique—for example, [Writing Markup with JSX](/learn/writing-markup-with-jsx), [Updating Objects in State](/learn/updating-objects-in-state), or [Sharing State Between Components](/learn/sharing-state-between-components). Some of the pages focus on explaining an idea—like [Render and Commit](/learn/render-and-commit), or [State as a Snapshot](/learn/state-as-a-snapshot). And there are a few, like [You Might Not Need an Effect](/learn/you-might-not-need-an-effect), that share our suggestions based on what we’ve learned over these years.

You don’t have to read these chapters as a sequence. Who has the time for this?! But you could. Pages in the Learn section only rely on concepts introduced by the earlier pages. If you want to read it like a book, go for it!

### Check your understanding with challenges[](#check-your-understanding-with-challenges "Link for Check your understanding with challenges ")

Most pages in the Learn section end with a few challenges to check your understanding. For example, here are a few challenges from the page about [Conditional Rendering](/learn/conditional-rendering#challenges).

You don’t have to solve them right now! Unless you *really* want to.

#### Challenge 1 of 2:Show an icon for incomplete items with `? :`[](#show-an-icon-for-incomplete-items-with-- "Link for this heading")

Use the conditional operator (`cond ? a : b`) to render a ❌ if `isPacked` isn’t `true`.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
function Item({ name, isPacked }) {
  return (
    <li className="item">
      {name} {isPacked && '✅'}
    </li>
  );
}

export default function PackingList() {
  return (
    <section>
      <h1>Sally Ride's Packing List</h1>
      <ul>
        <Item
          isPacked={true}
          name="Space suit"
        />
        <Item
          isPacked={true}
          name="Helmet with a golden leaf"
        />
        <Item
          isPacked={false}
          name="Photo of Tam"
        />
      </ul>
    </section>
  );
}
```

Notice the “Show solution” button in the left bottom corner. It’s handy if you want to check yourself!

### Build an intuition with diagrams and illustrations[](#build-an-intuition-with-diagrams-and-illustrations "Link for Build an intuition with diagrams and illustrations ")

When we couldn’t figure out how to explain something with code and words alone, we’ve added diagrams that help provide some intuition. For example, here is one of the diagrams from [Preserving and Resetting State](/learn/preserving-and-resetting-state):

When `section` changes to `div`, the `section` is deleted and the new `div` is added

You’ll also see some illustrations throughout the docs—here’s one of the [browser painting the screen](/learn/render-and-commit#epilogue-browser-paint):

Illustrated by [Rachel Lee Nabors](https://nearestnabors.com/)

We’ve confirmed with the browser vendors that this depiction is 100% scientifically accurate.

## A new, detailed API Reference[](#a-new-detailed-api-reference "Link for A new, detailed API Reference ")

In the [API Reference](/reference/react), every React API now has a dedicated page. This includes all kinds of APIs:

* Built-in Hooks like [`useState`](/reference/react/useState).
* Built-in components like [`<Suspense>`](/reference/react/Suspense).
* Built-in browser components like [`<input>`](/reference/react-dom/components/input).
* Framework-oriented APIs like [`renderToPipeableStream`](/reference/react-dom/server/renderToReadableStream).
* Other React APIs like [`memo`](/reference/react/memo).

You’ll notice that every API page is split into at least two segments: *Reference* and *Usage*.

[Reference](/reference/react/useState#reference) describes the formal API signature by listing its arguments and return values. It’s concise, but it can feel a bit abstract if you’re not familiar with that API. It describes what an API does, but not how to use it.

[Usage](/reference/react/useState#usage) shows why and how you would use this API in practice, like a colleague or a friend might explain. It shows the **canonical scenarios for how each API was meant to be used by the React team.** We’ve added color-coded snippets, examples of using different APIs together, and recipes that you can copy and paste from:

#### Basic useState examples[](#examples-basic "Link for Basic useState examples")

#### Example 1 of 4:Counter (number)[](#counter-number "Link for this heading")

In this example, the `count` state variable holds a number. Clicking the button increments it.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function Counter() {
  const [count, setCount] = useState(0);

  function handleClick() {
    setCount(count + 1);
  }

  return (
    <button onClick={handleClick}>
      You pressed me {count} times
    </button>
  );
}
```

Some API pages also include [Troubleshooting](/reference/react/useEffect#troubleshooting) (for common problems) and [Alternatives](/reference/react-dom/findDOMNode#alternatives) (for deprecated APIs).

We hope that this approach will make the API reference useful not only as a way to look up an argument, but as a way to see all the different things you can do with any given API—and how it connects to the other ones.

## What’s next?[](#whats-next "Link for What’s next? ")

That’s a wrap for our little tour! Have a look around the new website, see what you like or don’t like, and keep the feedback coming in our [issue tracker](https://github.com/reactjs/react.dev/issues).

We acknowledge this project has taken a long time to ship. We wanted to maintain a high quality bar that the React community deserves. While writing these docs and creating all of the examples, we found mistakes in some of our own explanations, bugs in React, and even gaps in the React design that we are now working to address. We hope that the new documentation will help us hold React itself to a higher bar in the future.

We’ve heard many of your requests to expand the content and functionality of the website, for example:

* Providing a TypeScript version for all examples;
* Creating the updated performance, testing, and accessibility guides;
* Documenting React Server Components independently from the frameworks that support them;
* Working with our international community to get the new docs translated;
* Adding missing features to the new website (for example, RSS for this blog).

Now that [react.dev](https://react.dev/) is out, we will be able to shift our focus from “catching up” with the third-party React educational resources to adding new information and further improving our new website.

We think there’s never been a better time to learn React.

## Who worked on this?[](#who-worked-on-this "Link for Who worked on this? ")

On the React team, [Rachel Nabors](https://twitter.com/rachelnabors/) led the project (and provided the illustrations), and [Dan Abramov](https://bsky.app/profile/danabra.mov) designed the curriculum. They co-authored most of the content together as well.

Of course, no project this large happens in isolation. We have a lot of people to thank!

[Sylwia Vargas](https://twitter.com/SylwiaVargas) overhauled our examples to go beyond “foo/bar/baz” and kittens, and feature scientists, artists and cities from around the world. [Maggie Appleton](https://twitter.com/Mappletons) turned our doodles into a clear diagram system.

Thanks to [David McCabe](https://twitter.com/mcc_abe), [Sophie Alpert](https://twitter.com/sophiebits), [Rick Hanlon](https://twitter.com/rickhanlonii), [Andrew Clark](https://twitter.com/acdlite), and [Matt Carroll](https://twitter.com/mattcarrollcode) for additional writing contributions. We’d also like to thank [Natalia Tepluhina](https://twitter.com/n_tepluhina) and [Sebastian Markbåge](https://twitter.com/sebmarkbage) for their ideas and feedback.

Thanks to [Dan Lebowitz](https://twitter.com/lebo) for the site design and [Razvan Gradinar](https://dribbble.com/GradinarRazvan) for the sandbox design.

On the development front, thanks to [Jared Palmer](https://twitter.com/jaredpalmer) for prototype development. Thanks to [Dane Grant](https://twitter.com/danecando) and [Dustin Goodman](https://twitter.com/dustinsgoodman) from [ThisDotLabs](https://www.thisdot.co/) for their support on UI development. Thanks to [Ives van Hoorne](https://twitter.com/CompuIves), [Alex Moldovan](https://twitter.com/alexnmoldovan), [Jasper De Moor](https://twitter.com/JasperDeMoor), and [Danilo Woznica](https://twitter.com/danilowoz) from [CodeSandbox](https://codesandbox.io/) for their work with sandbox integration. Thanks to [Rick Hanlon](https://twitter.com/rickhanlonii) for spot development and design work, finessing our colors and finer details. Thanks to [Harish Kumar](https://www.strek.in/) and [Luna Ruan](https://twitter.com/lunaruan) for adding new features to the site and helping maintain it.

Huge thanks to the folks who volunteered their time to participate in the alpha and beta testing program. Your enthusiasm and invaluable feedback helped us shape these docs. A special shout out to our beta tester, [Debbie O’Brien](https://twitter.com/debs_obrien), who gave a talk about her experience using the React docs at React Conf 2021.

Finally, thanks to the React community for being the inspiration behind this effort. You are the reason we do this, and we hope that the new docs will help you use React to build any user interface that you want.

[PreviousReact Labs: What We've Been Working On – March 2023](/blog/2023/03/22/react-labs-what-we-have-been-working-on-march-2023)

[NextReact Labs: What We've Been Working On – June 2022](/blog/2022/06/15/react-labs-what-we-have-been-working-on-june-2022)

***

----
url: https://18.react.dev/reference/react/Fragment
----

[API Reference](/reference/react)

[Components](/reference/react/components)

# \<Fragment> (<>...\</>)[](#undefined "Link for this heading")

`<Fragment>`, often used via `<>...</>` syntax, lets you group elements without a wrapper node.

```
<>

  <OneChild />

  <AnotherChild />

</>
```

* [Reference](#reference)
  * [`<Fragment>`](#fragment)

* [Usage](#usage)

  * [Returning multiple elements](#returning-multiple-elements)
  * [Assigning multiple elements to a variable](#assigning-multiple-elements-to-a-variable)
  * [Grouping elements with text](#grouping-elements-with-text)
  * [Rendering a list of Fragments](#rendering-a-list-of-fragments)

***

## Reference[](#reference "Link for Reference ")

### `<Fragment>`[](#fragment "Link for this heading")

Wrap elements in `<Fragment>` to group them together in situations where you need a single element. Grouping elements in `Fragment` has no effect on the resulting DOM; it is the same as if the elements were not grouped. The empty JSX tag `<></>` is shorthand for `<Fragment></Fragment>` in most cases.

#### Props[](#props "Link for Props ")

* **optional** `key`: Fragments declared with the explicit `<Fragment>` syntax may have [keys.](/learn/rendering-lists#keeping-list-items-in-order-with-key)

#### Caveats[](#caveats "Link for Caveats ")

* If you want to pass `key` to a Fragment, you can’t use the `<>...</>` syntax. You have to explicitly import `Fragment` from `'react'` and render `<Fragment key={yourKey}>...</Fragment>`.

* React does not [reset state](/learn/preserving-and-resetting-state) when you go from rendering `<><Child /></>` to `[<Child />]` or back, or when you go from rendering `<><Child /></>` to `<Child />` and back. This only works a single level deep: for example, going from `<><><Child /></></>` to `<Child />` resets the state. See the precise semantics [here.](https://gist.github.com/clemmy/b3ef00f9507909429d8aa0d3ee4f986b)

***

## Usage[](#usage "Link for Usage ")

### Returning multiple elements[](#returning-multiple-elements "Link for Returning multiple elements ")

Use `Fragment`, or the equivalent `<>...</>` syntax, to group multiple elements together. You can use it to put multiple elements in any place where a single element can go. For example, a component can only return one element, but by using a Fragment you can group multiple elements together and then return them as a group:

```
function Post() {

  return (

    <>

      <PostTitle />

      <PostBody />

    </>

  );

}
```

Fragments are useful because grouping elements with a Fragment has no effect on layout or styles, unlike if you wrapped the elements in another container like a DOM element. If you inspect this example with the browser tools, you’ll see that all `<h1>` and `<article>` DOM nodes appear as siblings without wrappers around them:

```
export default function Blog() {
  return (
    <>
      <Post title="An update" body="It's been a while since I posted..." />
      <Post title="My new blog" body="I am starting a new blog!" />
    </>
  )
}

function Post({ title, body }) {
  return (
    <>
      <PostTitle title={title} />
      <PostBody body={body} />
    </>
  );
}

function PostTitle({ title }) {
  return <h1>{title}</h1>
}

function PostBody({ body }) {
  return (
    <article>
      <p>{body}</p>
    </article>
  );
}
```

##### Deep Dive#### How to write a Fragment without the special syntax?[](#how-to-write-a-fragment-without-the-special-syntax "Link for How to write a Fragment without the special syntax? ")

The example above is equivalent to importing `Fragment` from React:

```
import { Fragment } from 'react';



function Post() {

  return (

    <Fragment>

      <PostTitle />

      <PostBody />

    </Fragment>

  );

}
```

Usually you won’t need this unless you need to [pass a `key` to your `Fragment`.](#rendering-a-list-of-fragments)

***

### Assigning multiple elements to a variable[](#assigning-multiple-elements-to-a-variable "Link for Assigning multiple elements to a variable ")

Like any other element, you can assign Fragment elements to variables, pass them as props, and so on:

```
function CloseDialog() {

  const buttons = (

    <>

      <OKButton />

      <CancelButton />

    </>

  );

  return (

    <AlertDialog buttons={buttons}>

      Are you sure you want to leave this page?

    </AlertDialog>

  );

}
```

***

### Grouping elements with text[](#grouping-elements-with-text "Link for Grouping elements with text ")

You can use `Fragment` to group text together with components:

```
function DateRangePicker({ start, end }) {

  return (

    <>

      From

      <DatePicker date={start} />

      to

      <DatePicker date={end} />

    </>

  );

}
```

***

### Rendering a list of Fragments[](#rendering-a-list-of-fragments "Link for Rendering a list of Fragments ")

Here’s a situation where you need to write `Fragment` explicitly instead of using the `<></>` syntax. When you [render multiple elements in a loop](/learn/rendering-lists), you need to assign a `key` to each element. If the elements within the loop are Fragments, you need to use the normal JSX element syntax in order to provide the `key` attribute:

```
function Blog() {

  return posts.map(post =>

    <Fragment key={post.id}>

      <PostTitle title={post.title} />

      <PostBody body={post.body} />

    </Fragment>

  );

}
```

You can inspect the DOM to verify that there are no wrapper elements around the Fragment children:

```
import { Fragment } from 'react';

const posts = [
  { id: 1, title: 'An update', body: "It's been a while since I posted..." },
  { id: 2, title: 'My new blog', body: 'I am starting a new blog!' }
];

export default function Blog() {
  return posts.map(post =>
    <Fragment key={post.id}>
      <PostTitle title={post.title} />
      <PostBody body={post.body} />
    </Fragment>
  );
}

function PostTitle({ title }) {
  return <h1>{title}</h1>
}

function PostBody({ body }) {
  return (
    <article>
      <p>{body}</p>
    </article>
  );
}
```

[PreviousComponents](/reference/react/components)

[Next\<Profiler>](/reference/react/Profiler)

***

----
url: https://18.react.dev/reference/react-dom/components/meta
----

[API Reference](/reference/react)

[Components](/reference/react-dom/components)

# \<meta>[](#undefined "Link for this heading")

### Canary

React’s extensions to `<meta>` are currently only available in React’s canary and experimental channels. In stable releases of React `<meta>` works only as a [built-in browser HTML component](https://react.dev/reference/react-dom/components#all-html-components). Learn more about [React’s release channels here](/community/versioning-policy#all-release-channels).

The [built-in browser `<meta>` component](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta) lets you add metadata to the document.

```
<meta name="keywords" content="React, JavaScript, semantic markup, html" />
```

* [Reference](#reference)
  * [`<meta>`](#meta)

* [Usage](#usage)

  * [Annotating the document with metadata](#annotating-the-document-with-metadata)
  * [Annotating specific items within the document with metadata](#annotating-specific-items-within-the-document-with-metadata)

***

## Reference[](#reference "Link for Reference ")

### `<meta>`[](#meta "Link for this heading")

To add document metadata, render the [built-in browser `<meta>` component](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta). You can render `<meta>` from any component and React will always place the corresponding DOM element in the document head.

```
<meta name="keywords" content="React, JavaScript, semantic markup, html" />
```

[See more examples below.](#usage)

#### Props[](#props "Link for Props ")

`<meta>` supports all [common element props.](/reference/react-dom/components/common#props)

***

## Usage[](#usage "Link for Usage ")

### Annotating the document with metadata[](#annotating-the-document-with-metadata "Link for Annotating the document with metadata ")

You can annotate the document with metadata such as keywords, a summary, or the author’s name. React will place this metadata within the document `<head>` regardless of where in the React tree it is rendered.

```
<meta name="author" content="John Smith" />

<meta name="keywords" content="React, JavaScript, semantic markup, html" />

<meta name="description" content="API reference for the <meta> component in React DOM" />
```

You can render the `<meta>` component from any component. React will put a `<meta>` DOM node in the document `<head>`.

```
import ShowRenderedHTML from './ShowRenderedHTML.js';

export default function SiteMapPage() {
  return (
    <ShowRenderedHTML>
      <meta name="keywords" content="React" />
      <meta name="description" content="A site map for the React website" />
      <h1>Site Map</h1>
      <p>...</p>
    </ShowRenderedHTML>
  );
}
```

### Annotating specific items within the document with metadata[](#annotating-specific-items-within-the-document-with-metadata "Link for Annotating specific items within the document with metadata ")

You can use the `<meta>` component with the `itemProp` prop to annotate specific items within the document with metadata. In this case, React will *not* place these annotations within the document `<head>` but will place them like any other React component.

```
<section itemScope>

  <h3>Annotating specific items</h3>

  <meta itemProp="description" content="API reference for using <meta> with itemProp" />

  <p>...</p>

</section>
```

[Previous\<link>](/reference/react-dom/components/link)

[Next\<script>](/reference/react-dom/components/script)

***

----
url: https://18.react.dev/reference/react/Component
----

[API Reference](/reference/react)

[Legacy React APIs](/reference/react/legacy)

# Component[](#undefined "Link for this heading")

### Pitfall

We recommend defining components as functions instead of classes. [See how to migrate.](#alternatives)

`Component` is the base class for the React components defined as [JavaScript classes.](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes) Class components are still supported by React, but we don’t recommend using them in new code.

```
class Greeting extends Component {

  render() {

    return <h1>Hello, {this.props.name}!</h1>;

  }

}
```

* [Reference](#reference)

  * [`Component`](#component)
  * [`context`](#context)
  * [`props`](#props)
  * [`refs`](#refs)
  * [`getChildContext()`](#getchildcontext)
  * [`static childContextTypes`](#static-childcontexttypes)
  * [`static contextTypes`](#static-contexttypes)
  * [`static contextType`](#static-contexttype)
  * [`static defaultProps`](#static-defaultprops)
  * [`static propTypes`](#static-proptypes)
  * [`static getDerivedStateFromError(error)`](#static-getderivedstatefromerror)
  * [`static getDerivedStateFromProps(props, state)`](#static-getderivedstatefromprops)

* [Usage](#usage)

  * [Defining a class component](#defining-a-class-component)
  * [Adding state to a class component](#adding-state-to-a-class-component)
  * [Adding lifecycle methods to a class component](#adding-lifecycle-methods-to-a-class-component)
  * [Catching rendering errors with an error boundary](#catching-rendering-errors-with-an-error-boundary)

* [Alternatives](#alternatives)

  * [Migrating a simple component from a class to a function](#migrating-a-simple-component-from-a-class-to-a-function)
  * [Migrating a component with state from a class to a function](#migrating-a-component-with-state-from-a-class-to-a-function)
  * [Migrating a component with lifecycle methods from a class to a function](#migrating-a-component-with-lifecycle-methods-from-a-class-to-a-function)
  * [Migrating a component with context from a class to a function](#migrating-a-component-with-context-from-a-class-to-a-function)

***

## Reference[](#reference "Link for Reference ")

### `Component`[](#component "Link for this heading")

To define a React component as a class, extend the built-in `Component` class and define a [`render` method:](#render)

```
import { Component } from 'react';



class Greeting extends Component {

  render() {

    return <h1>Hello, {this.props.name}!</h1>;

  }

}
```

Only the `render` method is required, other methods are optional.

[See more examples below.](#usage)

***

### `context`[](#context "Link for this heading")

The [context](/learn/passing-data-deeply-with-context) of a class component is available as `this.context`. It is only available if you specify *which* context you want to receive using [`static contextType`](#static-contexttype) (modern) or [`static contextTypes`](#static-contexttypes) (deprecated).

A class component can only read one context at a time.

```
class Button extends Component {

  static contextType = ThemeContext;



  render() {

    const theme = this.context;

    const className = 'button-' + theme;

    return (

      <button className={className}>

        {this.props.children}

      </button>

    );

  }

}
```

### Note

Reading `this.context` in class components is equivalent to [`useContext`](/reference/react/useContext) in function components.

[See how to migrate.](#migrating-a-component-with-context-from-a-class-to-a-function)

***

### `props`[](#props "Link for this heading")

The props passed to a class component are available as `this.props`.

```
class Greeting extends Component {

  render() {

    return <h1>Hello, {this.props.name}!</h1>;

  }

}



<Greeting name="Taylor" />
```

### Note

Reading `this.props` in class components is equivalent to [declaring props](/learn/passing-props-to-a-component#step-2-read-props-inside-the-child-component) in function components.

[See how to migrate.](#migrating-a-simple-component-from-a-class-to-a-function)

***

### `refs`[](#refs "Link for this heading")

### Deprecated

This API will be removed in a future major version of React. [Use `createRef` instead.](/reference/react/createRef)

Lets you access [legacy string refs](https://reactjs.org/docs/refs-and-the-dom.html#legacy-api-string-refs) for this component.

***

### `state`[](#state "Link for this heading")

The state of a class component is available as `this.state`. The `state` field must be an object. Do not mutate the state directly. If you wish to change the state, call `setState` with the new state.

```
class Counter extends Component {

  state = {

    age: 42,

  };



  handleAgeChange = () => {

    this.setState({

      age: this.state.age + 1 

    });

  };



  render() {

    return (

      <>

        <button onClick={this.handleAgeChange}>

        Increment age

        </button>

        <p>You are {this.state.age}.</p>

      </>

    );

  }

}
```

### Note

Defining `state` in class components is equivalent to calling [`useState`](/reference/react/useState) in function components.

[See how to migrate.](#migrating-a-component-with-state-from-a-class-to-a-function)

***

### `constructor(props)`[](#constructor "Link for this heading")

The [constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/constructor) runs before your class component *mounts* (gets added to the screen). Typically, a constructor is only used for two purposes in React. It lets you declare state and [bind](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Function/bind) your class methods to the class instance:

```
class Counter extends Component {

  constructor(props) {

    super(props);

    this.state = { counter: 0 };

    this.handleClick = this.handleClick.bind(this);

  }



  handleClick() {

    // ...

  }
```

If you use modern JavaScript syntax, constructors are rarely needed. Instead, you can rewrite this code above using the [public class field syntax](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Public_class_fields) which is supported both by modern browsers and tools like [Babel:](https://babeljs.io/)

```
class Counter extends Component {

  state = { counter: 0 };



  handleClick = () => {

    // ...

  }
```

***

### `componentDidCatch(error, info)`[](#componentdidcatch "Link for this heading")

If you define `componentDidCatch`, React will call it when some child component (including distant children) throws an error during rendering. This lets you log that error to an error reporting service in production.

Typically, it is used together with [`static getDerivedStateFromError`](#static-getderivedstatefromerror) which lets you update state in response to an error and display an error message to the user. A component with these methods is called an *error boundary.*

***

### `componentDidMount()`[](#componentdidmount "Link for this heading")

If you define the `componentDidMount` method, React will call it when your component is added *(mounted)* to the screen. This is a common place to start data fetching, set up subscriptions, or manipulate the DOM nodes.

If you implement `componentDidMount`, you usually need to implement other lifecycle methods to avoid bugs. For example, if `componentDidMount` reads some state or props, you also have to implement [`componentDidUpdate`](#componentdidupdate) to handle their changes, and [`componentWillUnmount`](#componentwillunmount) to clean up whatever `componentDidMount` was doing.

```
class ChatRoom extends Component {

  state = {

    serverUrl: 'https://localhost:1234'

  };



  componentDidMount() {

    this.setupConnection();

  }



  componentDidUpdate(prevProps, prevState) {

    if (

      this.props.roomId !== prevProps.roomId ||

      this.state.serverUrl !== prevState.serverUrl

    ) {

      this.destroyConnection();

      this.setupConnection();

    }

  }



  componentWillUnmount() {

    this.destroyConnection();

  }



  // ...

}
```

***

### `componentDidUpdate(prevProps, prevState, snapshot?)`[](#componentdidupdate "Link for this heading")

If you define the `componentDidUpdate` method, React will call it immediately after your component has been re-rendered with updated props or state. This method is not called for the initial render.

You can use it to manipulate the DOM after an update. This is also a common place to do network requests as long as you compare the current props to previous props (e.g. a network request may not be necessary if the props have not changed). Typically, you’d use it together with [`componentDidMount`](#componentdidmount) and [`componentWillUnmount`:](#componentwillunmount)

```
class ChatRoom extends Component {

  state = {

    serverUrl: 'https://localhost:1234'

  };



  componentDidMount() {

    this.setupConnection();

  }



  componentDidUpdate(prevProps, prevState) {

    if (

      this.props.roomId !== prevProps.roomId ||

      this.state.serverUrl !== prevState.serverUrl

    ) {

      this.destroyConnection();

      this.setupConnection();

    }

  }



  componentWillUnmount() {

    this.destroyConnection();

  }



  // ...

}
```

***

### `componentWillMount()`[](#componentwillmount "Link for this heading")

### Deprecated

This API has been renamed from `componentWillMount` to [`UNSAFE_componentWillMount`.](#unsafe_componentwillmount) The old name has been deprecated. In a future major version of React, only the new name will work.

Run the [`rename-unsafe-lifecycles` codemod](https://github.com/reactjs/react-codemod#rename-unsafe-lifecycles) to automatically update your components.

***

### `componentWillReceiveProps(nextProps)`[](#componentwillreceiveprops "Link for this heading")

### Deprecated

This API has been renamed from `componentWillReceiveProps` to [`UNSAFE_componentWillReceiveProps`.](#unsafe_componentwillreceiveprops) The old name has been deprecated. In a future major version of React, only the new name will work.

Run the [`rename-unsafe-lifecycles` codemod](https://github.com/reactjs/react-codemod#rename-unsafe-lifecycles) to automatically update your components.

***

### `componentWillUpdate(nextProps, nextState)`[](#componentwillupdate "Link for this heading")

### Deprecated

This API has been renamed from `componentWillUpdate` to [`UNSAFE_componentWillUpdate`.](#unsafe_componentwillupdate) The old name has been deprecated. In a future major version of React, only the new name will work.

Run the [`rename-unsafe-lifecycles` codemod](https://github.com/reactjs/react-codemod#rename-unsafe-lifecycles) to automatically update your components.

***

### `componentWillUnmount()`[](#componentwillunmount "Link for this heading")

If you define the `componentWillUnmount` method, React will call it before your component is removed *(unmounted)* from the screen. This is a common place to cancel data fetching or remove subscriptions.

The logic inside `componentWillUnmount` should “mirror” the logic inside [`componentDidMount`.](#componentdidmount) For example, if `componentDidMount` sets up a subscription, `componentWillUnmount` should clean up that subscription. If the cleanup logic in your `componentWillUnmount` reads some props or state, you will usually also need to implement [`componentDidUpdate`](#componentdidupdate) to clean up resources (such as subscriptions) corresponding to the old props and state.

```
class ChatRoom extends Component {

  state = {

    serverUrl: 'https://localhost:1234'

  };



  componentDidMount() {

    this.setupConnection();

  }



  componentDidUpdate(prevProps, prevState) {

    if (

      this.props.roomId !== prevProps.roomId ||

      this.state.serverUrl !== prevState.serverUrl

    ) {

      this.destroyConnection();

      this.setupConnection();

    }

  }



  componentWillUnmount() {

    this.destroyConnection();

  }



  // ...

}
```

***

***

### `getChildContext()`[](#getchildcontext "Link for this heading")

### Deprecated

This API will be removed in a future major version of React. [Use `Context.Provider` instead.](/reference/react/createContext#provider)

Lets you specify the values for the [legacy context](https://reactjs.org/docs/legacy-context.html) is provided by this component.

***

### `getSnapshotBeforeUpdate(prevProps, prevState)`[](#getsnapshotbeforeupdate "Link for this heading")

If you implement `getSnapshotBeforeUpdate`, React will call it immediately before React updates the DOM. It enables your component to capture some information from the DOM (e.g. scroll position) before it is potentially changed. Any value returned by this lifecycle method will be passed as a parameter to [`componentDidUpdate`.](#componentdidupdate)

For example, you can use it in a UI like a chat thread that needs to preserve its scroll position during updates:

```
class ScrollingList extends React.Component {

  constructor(props) {

    super(props);

    this.listRef = React.createRef();

  }



  getSnapshotBeforeUpdate(prevProps, prevState) {

    // Are we adding new items to the list?

    // Capture the scroll position so we can adjust scroll later.

    if (prevProps.list.length < this.props.list.length) {

      const list = this.listRef.current;

      return list.scrollHeight - list.scrollTop;

    }

    return null;

  }



  componentDidUpdate(prevProps, prevState, snapshot) {

    // If we have a snapshot value, we've just added new items.

    // Adjust scroll so these new items don't push the old ones out of view.

    // (snapshot here is the value returned from getSnapshotBeforeUpdate)

    if (snapshot !== null) {

      const list = this.listRef.current;

      list.scrollTop = list.scrollHeight - snapshot;

    }

  }



  render() {

    return (

      <div ref={this.listRef}>{/* ...contents... */}</div>

    );

  }

}
```

***

### `render()`[](#render "Link for this heading")

The `render` method is the only required method in a class component.

The `render` method should specify what you want to appear on the screen, for example:

```
import { Component } from 'react';



class Greeting extends Component {

  render() {

    return <h1>Hello, {this.props.name}!</h1>;

  }

}
```

***

### `setState(nextState, callback?)`[](#setstate "Link for this heading")

Call `setState` to update the state of your React component.

```
class Form extends Component {

  state = {

    name: 'Taylor',

  };



  handleNameChange = (e) => {

    const newName = e.target.value;

    this.setState({

      name: newName

    });

  }



  render() {

    return (

      <>

        <input value={this.state.name} onChange={this.handleNameChange} />

        <p>Hello, {this.state.name}.</p>

      </>

    );

  }

}
```

`setState` enqueues changes to the component state. It tells React that this component and its children need to re-render with the new state. This is the main way you’ll update the user interface in response to interactions.

### Pitfall

Calling `setState` **does not** change the current state in the already executing code:

```
function handleClick() {

  console.log(this.state.name); // "Taylor"

  this.setState({

    name: 'Robin'

  });

  console.log(this.state.name); // Still "Taylor"!

}
```

It only affects what `this.state` will return starting from the *next* render.

You can also pass a function to `setState`. It lets you update state based on the previous state:

```
  handleIncreaseAge = () => {

    this.setState(prevState => {

      return {

        age: prevState.age + 1

      };

    });

  }
```

***

### `shouldComponentUpdate(nextProps, nextState, nextContext)`[](#shouldcomponentupdate "Link for this heading")

If you define `shouldComponentUpdate`, React will call it to determine whether a re-render can be skipped.

If you are confident you want to write it by hand, you may compare `this.props` with `nextProps` and `this.state` with `nextState` and return `false` to tell React the update can be skipped.

```
class Rectangle extends Component {

  state = {

    isHovered: false

  };



  shouldComponentUpdate(nextProps, nextState) {

    if (

      nextProps.position.x === this.props.position.x &&

      nextProps.position.y === this.props.position.y &&

      nextProps.size.width === this.props.size.width &&

      nextProps.size.height === this.props.size.height &&

      nextState.isHovered === this.state.isHovered

    ) {

      // Nothing has changed, so a re-render is unnecessary

      return false;

    }

    return true;

  }



  // ...

}
```

React calls `shouldComponentUpdate` before rendering when new props or state are being received. Defaults to `true`. This method is not called for the initial render or when [`forceUpdate`](#forceupdate) is used.

#### Parameters[](#shouldcomponentupdate-parameters "Link for Parameters ")

* `nextProps`: The next props that the component is about to render with. Compare `nextProps` to [`this.props`](#props) to determine what changed.
* `nextState`: The next state that the component is about to render with. Compare `nextState` to [`this.state`](#props) to determine what changed.
* `nextContext`: The next context that the component is about to render with. Compare `nextContext` to [`this.context`](#context) to determine what changed. Only available if you specify [`static contextType`](#static-contexttype) (modern) or [`static contextTypes`](#static-contexttypes) (legacy).

***

***

* `nextContext`: The next context that the component is about to receive from the closest provider. Compare `nextContext` to [`this.context`](#context) to determine what changed. Only available if you specify [`static contextType`](#static-contexttype) (modern) or [`static contextTypes`](#static-contexttypes) (legacy).

***

***

### `static childContextTypes`[](#static-childcontexttypes "Link for this heading")

### Deprecated

This API will be removed in a future major version of React. [Use `static contextType` instead.](#static-contexttype)

Lets you specify which [legacy context](https://reactjs.org/docs/legacy-context.html) is provided by this component.

***

### `static contextTypes`[](#static-contexttypes "Link for this heading")

### Deprecated

This API will be removed in a future major version of React. [Use `static contextType` instead.](#static-contexttype)

Lets you specify which [legacy context](https://reactjs.org/docs/legacy-context.html) is consumed by this component.

***

### `static contextType`[](#static-contexttype "Link for this heading")

If you want to read [`this.context`](#context-instance-field) from your class component, you must specify which context it needs to read. The context you specify as the `static contextType` must be a value previously created by [`createContext`.](/reference/react/createContext)

```
class Button extends Component {

  static contextType = ThemeContext;



  render() {

    const theme = this.context;

    const className = 'button-' + theme;

    return (

      <button className={className}>

        {this.props.children}

      </button>

    );

  }

}
```

### Note

Reading `this.context` in class components is equivalent to [`useContext`](/reference/react/useContext) in function components.

[See how to migrate.](#migrating-a-component-with-context-from-a-class-to-a-function)

***

### `static defaultProps`[](#static-defaultprops "Link for this heading")

You can define `static defaultProps` to set the default props for the class. They will be used for `undefined` and missing props, but not for `null` props.

For example, here is how you define that the `color` prop should default to `'blue'`:

```
class Button extends Component {

  static defaultProps = {

    color: 'blue'

  };



  render() {

    return <button className={this.props.color}>click me</button>;

  }

}
```

If the `color` prop is not provided or is `undefined`, it will be set by default to `'blue'`:

```
<>

  {/* this.props.color is "blue" */}

  <Button />



  {/* this.props.color is "blue" */}

  <Button color={undefined} />



  {/* this.props.color is null */}

  <Button color={null} />



  {/* this.props.color is "red" */}

  <Button color="red" />

</>
```

### Note

Defining `defaultProps` in class components is similar to using [default values](/learn/passing-props-to-a-component#specifying-a-default-value-for-a-prop) in function components.

***

### `static propTypes`[](#static-proptypes "Link for this heading")

You can define `static propTypes` together with the [`prop-types`](https://www.npmjs.com/package/prop-types) library to declare the types of the props accepted by your component. These types will be checked during rendering and in development only.

```
import PropTypes from 'prop-types';



class Greeting extends React.Component {

  static propTypes = {

    name: PropTypes.string

  };



  render() {

    return (

      <h1>Hello, {this.props.name}</h1>

    );

  }

}
```

### Note

We recommend using [TypeScript](https://www.typescriptlang.org/) instead of checking prop types at runtime.

***

### `static getDerivedStateFromError(error)`[](#static-getderivedstatefromerror "Link for this heading")

If you define `static getDerivedStateFromError`, React will call it when a child component (including distant children) throws an error during rendering. This lets you display an error message instead of clearing the UI.

Typically, it is used together with [`componentDidCatch`](#componentdidcatch) which lets you send the error report to some analytics service. A component with these methods is called an *error boundary.*

***

### `static getDerivedStateFromProps(props, state)`[](#static-getderivedstatefromprops "Link for this heading")

If you define `static getDerivedStateFromProps`, React will call it right before calling [`render`,](#render) both on the initial mount and on subsequent updates. It should return an object to update the state, or `null` to update nothing.

This method exists for [rare use cases](https://legacy.reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#when-to-use-derived-state) where the state depends on changes in props over time. For example, this `Form` component resets the `email` state when the `userID` prop changes:

```
class Form extends Component {

  state = {

    email: this.props.defaultEmail,

    prevUserID: this.props.userID

  };



  static getDerivedStateFromProps(props, state) {

    // Any time the current user changes,

    // Reset any parts of state that are tied to that user.

    // In this simple example, that's just the email.

    if (props.userID !== state.prevUserID) {

      return {

        prevUserID: props.userID,

        email: props.defaultEmail

      };

    }

    return null;

  }



  // ...

}
```

***

## Usage[](#usage "Link for Usage ")

### Defining a class component[](#defining-a-class-component "Link for Defining a class component ")

To define a React component as a class, extend the built-in `Component` class and define a [`render` method:](#render)

```
import { Component } from 'react';



class Greeting extends Component {

  render() {

    return <h1>Hello, {this.props.name}!</h1>;

  }

}
```

React will call your [`render`](#render) method whenever it needs to figure out what to display on the screen. Usually, you will return some [JSX](/learn/writing-markup-with-jsx) from it. Your `render` method should be a [pure function:](https://en.wikipedia.org/wiki/Pure_function) it should only calculate the JSX.

Similarly to [function components,](/learn/your-first-component#defining-a-component) a class component can [receive information by props](/learn/your-first-component#defining-a-component) from its parent component. However, the syntax for reading props is different. For example, if the parent component renders `<Greeting name="Taylor" />`, then you can read the `name` prop from [`this.props`](#props), like `this.props.name`:

```
import { Component } from 'react';

class Greeting extends Component {
  render() {
    return <h1>Hello, {this.props.name}!</h1>;
  }
}

export default function App() {
  return (
    <>
      <Greeting name="Sara" />
      <Greeting name="Cahal" />
      <Greeting name="Edite" />
    </>
  );
}
```

Note that Hooks (functions starting with `use`, like [`useState`](/reference/react/useState)) are not supported inside class components.

### Pitfall

We recommend defining components as functions instead of classes. [See how to migrate.](#migrating-a-simple-component-from-a-class-to-a-function)

***

### Adding state to a class component[](#adding-state-to-a-class-component "Link for Adding state to a class component ")

To add [state](/learn/state-a-components-memory) to a class, assign an object to a property called [`state`](#state). To update state, call [`this.setState`](#setstate).

```
import { Component } from 'react';

export default class Counter extends Component {
  state = {
    name: 'Taylor',
    age: 42,
  };

  handleNameChange = (e) => {
    this.setState({
      name: e.target.value
    });
  }

  handleAgeChange = () => {
    this.setState({
      age: this.state.age + 1 
    });
  };

  render() {
    return (
      <>
        <input
          value={this.state.name}
          onChange={this.handleNameChange}
        />
        <button onClick={this.handleAgeChange}>
          Increment age
        </button>
        <p>Hello, {this.state.name}. You are {this.state.age}.</p>
      </>
    );
  }
}
```

### Pitfall

We recommend defining components as functions instead of classes. [See how to migrate.](#migrating-a-component-with-state-from-a-class-to-a-function)

***

### Adding lifecycle methods to a class component[](#adding-lifecycle-methods-to-a-class-component "Link for Adding lifecycle methods to a class component ")

There are a few special methods you can define on your class.

If you define the [`componentDidMount`](#componentdidmount) method, React will call it when your component is added *(mounted)* to the screen. React will call [`componentDidUpdate`](#componentdidupdate) after your component re-renders due to changed props or state. React will call [`componentWillUnmount`](#componentwillunmount) after your component has been removed *(unmounted)* from the screen.

If you implement `componentDidMount`, you usually need to implement all three lifecycles to avoid bugs. For example, if `componentDidMount` reads some state or props, you also have to implement `componentDidUpdate` to handle their changes, and `componentWillUnmount` to clean up whatever `componentDidMount` was doing.

For example, this `ChatRoom` component keeps a chat connection synchronized with props and state:

```
import { Component } from 'react';
import { createConnection } from './chat.js';

export default class ChatRoom extends Component {
  state = {
    serverUrl: 'https://localhost:1234'
  };

  componentDidMount() {
    this.setupConnection();
  }

  componentDidUpdate(prevProps, prevState) {
    if (
      this.props.roomId !== prevProps.roomId ||
      this.state.serverUrl !== prevState.serverUrl
    ) {
      this.destroyConnection();
      this.setupConnection();
    }
  }

  componentWillUnmount() {
    this.destroyConnection();
  }

  setupConnection() {
    this.connection = createConnection(
      this.state.serverUrl,
      this.props.roomId
    );
    this.connection.connect();    
  }

  destroyConnection() {
    this.connection.disconnect();
    this.connection = null;
  }

  render() {
    return (
      <>
        <label>
          Server URL:{' '}
          <input
            value={this.state.serverUrl}
            onChange={e => {
              this.setState({
                serverUrl: e.target.value
              });
            }}
          />
        </label>
        <h1>Welcome to the {this.props.roomId} room!</h1>
      </>
    );
  }
}
```

Note that in development when [Strict Mode](/reference/react/StrictMode) is on, React will call `componentDidMount`, immediately call `componentWillUnmount`, and then call `componentDidMount` again. This helps you notice if you forgot to implement `componentWillUnmount` or if its logic doesn’t fully “mirror” what `componentDidMount` does.

### Pitfall

We recommend defining components as functions instead of classes. [See how to migrate.](#migrating-a-component-with-lifecycle-methods-from-a-class-to-a-function)

***

### Catching rendering errors with an error boundary[](#catching-rendering-errors-with-an-error-boundary "Link for Catching rendering errors with an error boundary ")

By default, if your application throws an error during rendering, React will remove its UI from the screen. To prevent this, you can wrap a part of your UI into an *error boundary*. An error boundary is a special component that lets you display some fallback UI instead of the part that crashed—for example, an error message.

To implement an error boundary component, you need to provide [`static getDerivedStateFromError`](#static-getderivedstatefromerror) which lets you update state in response to an error and display an error message to the user. You can also optionally implement [`componentDidCatch`](#componentdidcatch) to add some extra logic, for example, to log the error to an analytics service.

```
class ErrorBoundary extends React.Component {

  constructor(props) {

    super(props);

    this.state = { hasError: false };

  }



  static getDerivedStateFromError(error) {

    // Update state so the next render will show the fallback UI.

    return { hasError: true };

  }



  componentDidCatch(error, info) {

    // Example "componentStack":

    //   in ComponentThatThrows (created by App)

    //   in ErrorBoundary (created by App)

    //   in div (created by App)

    //   in App

    logErrorToMyService(error, info.componentStack);

  }



  render() {

    if (this.state.hasError) {

      // You can render any custom fallback UI

      return this.props.fallback;

    }



    return this.props.children;

  }

}
```

Then you can wrap a part of your component tree with it:

```
<ErrorBoundary fallback={<p>Something went wrong</p>}>

  <Profile />

</ErrorBoundary>
```

If `Profile` or its child component throws an error, `ErrorBoundary` will “catch” that error, display a fallback UI with the error message you’ve provided, and send a production error report to your error reporting service.

You don’t need to wrap every component into a separate error boundary. When you think about the [granularity of error boundaries,](https://www.brandondail.com/posts/fault-tolerance-react) consider where it makes sense to display an error message. For example, in a messaging app, it makes sense to place an error boundary around the list of conversations. It also makes sense to place one around every individual message. However, it wouldn’t make sense to place a boundary around every avatar.

### Note

There is currently no way to write an error boundary as a function component. However, you don’t have to write the error boundary class yourself. For example, you can use [`react-error-boundary`](https://github.com/bvaughn/react-error-boundary) instead.

***

## Alternatives[](#alternatives "Link for Alternatives ")

### Migrating a simple component from a class to a function[](#migrating-a-simple-component-from-a-class-to-a-function "Link for Migrating a simple component from a class to a function ")

Typically, you will [define components as functions](/learn/your-first-component#defining-a-component) instead.

For example, suppose you’re converting this `Greeting` class component to a function:

```
import { Component } from 'react';

class Greeting extends Component {
  render() {
    return <h1>Hello, {this.props.name}!</h1>;
  }
}

export default function App() {
  return (
    <>
      <Greeting name="Sara" />
      <Greeting name="Cahal" />
      <Greeting name="Edite" />
    </>
  );
}
```

Define a function called `Greeting`. This is where you will move the body of your `render` function.

```
function Greeting() {

  // ... move the code from the render method here ...

}
```

Instead of `this.props.name`, define the `name` prop [using the destructuring syntax](/learn/passing-props-to-a-component) and read it directly:

```
function Greeting({ name }) {

  return <h1>Hello, {name}!</h1>;

}
```

Here is a complete example:

```
function Greeting({ name }) {
  return <h1>Hello, {name}!</h1>;
}

export default function App() {
  return (
    <>
      <Greeting name="Sara" />
      <Greeting name="Cahal" />
      <Greeting name="Edite" />
    </>
  );
}
```

***

### Migrating a component with state from a class to a function[](#migrating-a-component-with-state-from-a-class-to-a-function "Link for Migrating a component with state from a class to a function ")

Suppose you’re converting this `Counter` class component to a function:

```
import { Component } from 'react';

export default class Counter extends Component {
  state = {
    name: 'Taylor',
    age: 42,
  };

  handleNameChange = (e) => {
    this.setState({
      name: e.target.value
    });
  }

  handleAgeChange = (e) => {
    this.setState({
      age: this.state.age + 1 
    });
  };

  render() {
    return (
      <>
        <input
          value={this.state.name}
          onChange={this.handleNameChange}
        />
        <button onClick={this.handleAgeChange}>
          Increment age
        </button>
        <p>Hello, {this.state.name}. You are {this.state.age}.</p>
      </>
    );
  }
}
```

Start by declaring a function with the necessary [state variables:](/reference/react/useState#adding-state-to-a-component)

```
import { useState } from 'react';



function Counter() {

  const [name, setName] = useState('Taylor');

  const [age, setAge] = useState(42);

  // ...
```

Next, convert the event handlers:

```
function Counter() {

  const [name, setName] = useState('Taylor');

  const [age, setAge] = useState(42);



  function handleNameChange(e) {

    setName(e.target.value);

  }



  function handleAgeChange() {

    setAge(age + 1);

  }

  // ...
```

Finally, replace all references starting with `this` with the variables and functions you defined in your component. For example, replace `this.state.age` with `age`, and replace `this.handleNameChange` with `handleNameChange`.

Here is a fully converted component:

```
import { useState } from 'react';

export default function Counter() {
  const [name, setName] = useState('Taylor');
  const [age, setAge] = useState(42);

  function handleNameChange(e) {
    setName(e.target.value);
  }

  function handleAgeChange() {
    setAge(age + 1);
  }

  return (
    <>
      <input
        value={name}
        onChange={handleNameChange}
      />
      <button onClick={handleAgeChange}>
        Increment age
      </button>
      <p>Hello, {name}. You are {age}.</p>
    </>
  )
}
```

***

### Migrating a component with lifecycle methods from a class to a function[](#migrating-a-component-with-lifecycle-methods-from-a-class-to-a-function "Link for Migrating a component with lifecycle methods from a class to a function ")

Suppose you’re converting this `ChatRoom` class component with lifecycle methods to a function:

```
import { Component } from 'react';
import { createConnection } from './chat.js';

export default class ChatRoom extends Component {
  state = {
    serverUrl: 'https://localhost:1234'
  };

  componentDidMount() {
    this.setupConnection();
  }

  componentDidUpdate(prevProps, prevState) {
    if (
      this.props.roomId !== prevProps.roomId ||
      this.state.serverUrl !== prevState.serverUrl
    ) {
      this.destroyConnection();
      this.setupConnection();
    }
  }

  componentWillUnmount() {
    this.destroyConnection();
  }

  setupConnection() {
    this.connection = createConnection(
      this.state.serverUrl,
      this.props.roomId
    );
    this.connection.connect();    
  }

  destroyConnection() {
    this.connection.disconnect();
    this.connection = null;
  }

  render() {
    return (
      <>
        <label>
          Server URL:{' '}
          <input
            value={this.state.serverUrl}
            onChange={e => {
              this.setState({
                serverUrl: e.target.value
              });
            }}
          />
        </label>
        <h1>Welcome to the {this.props.roomId} room!</h1>
      </>
    );
  }
}
```

First, verify that your [`componentWillUnmount`](#componentwillunmount) does the opposite of [`componentDidMount`.](#componentdidmount) In the above example, that’s true: it disconnects the connection that `componentDidMount` sets up. If such logic is missing, add it first.

Next, verify that your [`componentDidUpdate`](#componentdidupdate) method handles changes to any props and state you’re using in `componentDidMount`. In the above example, `componentDidMount` calls `setupConnection` which reads `this.state.serverUrl` and `this.props.roomId`. This is why `componentDidUpdate` checks whether `this.state.serverUrl` and `this.props.roomId` have changed, and resets the connection if they did. If your `componentDidUpdate` logic is missing or doesn’t handle changes to all relevant props and state, fix that first.

In the above example, the logic inside the lifecycle methods connects the component to a system outside of React (a chat server). To connect a component to an external system, [describe this logic as a single Effect:](/reference/react/useEffect#connecting-to-an-external-system)

```
import { useState, useEffect } from 'react';



function ChatRoom({ roomId }) {

  const [serverUrl, setServerUrl] = useState('https://localhost:1234');



  useEffect(() => {

    const connection = createConnection(serverUrl, roomId);

    connection.connect();

    return () => {

      connection.disconnect();

    };

  }, [serverUrl, roomId]);



  // ...

}
```

This [`useEffect`](/reference/react/useEffect) call is equivalent to the logic in the lifecycle methods above. If your lifecycle methods do multiple unrelated things, [split them into multiple independent Effects.](/learn/removing-effect-dependencies#is-your-effect-doing-several-unrelated-things) Here is a complete example you can play with:

```
import { useState, useEffect } from 'react';
import { createConnection } from './chat.js';

export default function ChatRoom({ roomId }) {
  const [serverUrl, setServerUrl] = useState('https://localhost:1234');

  useEffect(() => {
    const connection = createConnection(serverUrl, roomId);
    connection.connect();
    return () => {
      connection.disconnect();
    };
  }, [roomId, serverUrl]);

  return (
    <>
      <label>
        Server URL:{' '}
        <input
          value={serverUrl}
          onChange={e => setServerUrl(e.target.value)}
        />
      </label>
      <h1>Welcome to the {roomId} room!</h1>
    </>
  );
}
```

### Note

If your component does not synchronize with any external systems, [you might not need an Effect.](/learn/you-might-not-need-an-effect)

***

### Migrating a component with context from a class to a function[](#migrating-a-component-with-context-from-a-class-to-a-function "Link for Migrating a component with context from a class to a function ")

In this example, the `Panel` and `Button` class components read [context](/learn/passing-data-deeply-with-context) from [`this.context`:](#context)

```
import { createContext, Component } from 'react';

const ThemeContext = createContext(null);

class Panel extends Component {
  static contextType = ThemeContext;

  render() {
    const theme = this.context;
    const className = 'panel-' + theme;
    return (
      <section className={className}>
        <h1>{this.props.title}</h1>
        {this.props.children}
      </section>
    );    
  }
}

class Button extends Component {
  static contextType = ThemeContext;

  render() {
    const theme = this.context;
    const className = 'button-' + theme;
    return (
      <button className={className}>
        {this.props.children}
      </button>
    );
  }
}

function Form() {
  return (
    <Panel title="Welcome">
      <Button>Sign up</Button>
      <Button>Log in</Button>
    </Panel>
  );
}

export default function MyApp() {
  return (
    <ThemeContext.Provider value="dark">
      <Form />
    </ThemeContext.Provider>
  )
}
```

When you convert them to function components, replace `this.context` with [`useContext`](/reference/react/useContext) calls:

```
import { createContext, useContext } from 'react';

const ThemeContext = createContext(null);

function Panel({ title, children }) {
  const theme = useContext(ThemeContext);
  const className = 'panel-' + theme;
  return (
    <section className={className}>
      <h1>{title}</h1>
      {children}
    </section>
  )
}

function Button({ children }) {
  const theme = useContext(ThemeContext);
  const className = 'button-' + theme;
  return (
    <button className={className}>
      {children}
    </button>
  );
}

function Form() {
  return (
    <Panel title="Welcome">
      <Button>Sign up</Button>
      <Button>Log in</Button>
    </Panel>
  );
}

export default function MyApp() {
  return (
    <ThemeContext.Provider value="dark">
      <Form />
    </ThemeContext.Provider>
  )
}
```

[PreviouscloneElement](/reference/react/cloneElement)

[NextcreateElement](/reference/react/createElement)

***

----
url: https://legacy.reactjs.org/docs/react-without-es6.html
----

> These docs are old and won’t be updated. Go to [react.dev](https://react.dev/) for the new React docs.

Normally you would define a React component as a plain JavaScript class:

```
class Greeting extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}
```

If you don’t use ES6 yet, you may use the `create-react-class` module instead:

```
var createReactClass = require('create-react-class');
var Greeting = createReactClass({
  render: function() {
    return <h1>Hello, {this.props.name}</h1>;
  }
});
```

The API of ES6 classes is similar to `createReactClass()` with a few exceptions.

## [](#declaring-default-props)Declaring Default Props

With functions and ES6 classes `defaultProps` is defined as a property on the component itself:

```
class Greeting extends React.Component {
  // ...
}

Greeting.defaultProps = {
  name: 'Mary'
};
```

With `createReactClass()`, you need to define `getDefaultProps()` as a function on the passed object:

```
var Greeting = createReactClass({
  getDefaultProps: function() {
    return {
      name: 'Mary'
    };
  },

  // ...

});
```

## [](#setting-the-initial-state)Setting the Initial State

In ES6 classes, you can define the initial state by assigning `this.state` in the constructor:

```
class Counter extends React.Component {
  constructor(props) {
    super(props);
    this.state = {count: props.initialCount};
  }
  // ...
}
```

With `createReactClass()`, you have to provide a separate `getInitialState` method that returns the initial state:

```
var Counter = createReactClass({
  getInitialState: function() {
    return {count: this.props.initialCount};
  },
  // ...
});
```

## [](#autobinding)Autobinding

In React components declared as ES6 classes, methods follow the same semantics as regular ES6 classes. This means that they don’t automatically bind `this` to the instance. You’ll have to explicitly use `.bind(this)` in the constructor:

```
class SayHello extends React.Component {
  constructor(props) {
    super(props);
    this.state = {message: 'Hello!'};
    // This line is important!
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    alert(this.state.message);
  }

  render() {
    // Because `this.handleClick` is bound, we can use it as an event handler.
    return (
      <button onClick={this.handleClick}>
        Say hello
      </button>
    );
  }
}
```

With `createReactClass()`, this is not necessary because it binds all methods:

```
var SayHello = createReactClass({
  getInitialState: function() {
    return {message: 'Hello!'};
  },

  handleClick: function() {
    alert(this.state.message);
  },

  render: function() {
    return (
      <button onClick={this.handleClick}>
        Say hello
      </button>
    );
  }
});
```

This means writing ES6 classes comes with a little more boilerplate code for event handlers, but the upside is slightly better performance in large applications.

If the boilerplate code is too unattractive to you, you may use [ES2022 Class Properties](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Public_class_fields#public_instance_fields) syntax:

```
class SayHello extends React.Component {
  constructor(props) {
    super(props);
    this.state = {message: 'Hello!'};
  }
  
  // Using an arrow here binds the method:
  handleClick = () => {
    alert(this.state.message);
  };

  render() {
    return (
      <button onClick={this.handleClick}>
        Say hello
      </button>
    );
  }
}
```

You also have a few other options:

* Bind methods in the constructor.
* Use arrow functions, e.g. `onClick={(e) => this.handleClick(e)}`.
* Keep using `createReactClass`.

## [](#mixins)Mixins

> **Note:**
>
> ES6 launched without any mixin support. Therefore, there is no support for mixins when you use React with ES6 classes.
>
> **We also found numerous issues in codebases using mixins, [and don’t recommend using them in the new code](/blog/2016/07/13/mixins-considered-harmful.html).**
>
> This section exists only for the reference.

Sometimes very different components may share some common functionality. These are sometimes called [cross-cutting concerns](https://en.wikipedia.org/wiki/Cross-cutting_concern). `createReactClass` lets you use a legacy `mixins` system for that.

One common use case is a component wanting to update itself on a time interval. It’s easy to use `setInterval()`, but it’s important to cancel your interval when you don’t need it anymore to save memory. React provides [lifecycle methods](/docs/react-component.html#the-component-lifecycle) that let you know when a component is about to be created or destroyed. Let’s create a simple mixin that uses these methods to provide an easy `setInterval()` function that will automatically get cleaned up when your component is destroyed.

```
var SetIntervalMixin = {
  componentWillMount: function() {
    this.intervals = [];
  },
  setInterval: function() {
    this.intervals.push(setInterval.apply(null, arguments));
  },
  componentWillUnmount: function() {
    this.intervals.forEach(clearInterval);
  }
};

var createReactClass = require('create-react-class');

var TickTock = createReactClass({
  mixins: [SetIntervalMixin], // Use the mixin
  getInitialState: function() {
    return {seconds: 0};
  },
  componentDidMount: function() {
    this.setInterval(this.tick, 1000); // Call a method on the mixin
  },
  tick: function() {
    this.setState({seconds: this.state.seconds + 1});
  },
  render: function() {
    return (
      <p>
        React has been running for {this.state.seconds} seconds.
      </p>
    );
  }
});

const root = ReactDOM.createRoot(document.getElementById('example'));
root.render(<TickTock />);
```

If a component is using multiple mixins and several mixins define the same lifecycle method (i.e. several mixins want to do some cleanup when the component is destroyed), all of the lifecycle methods are guaranteed to be called. Methods defined on mixins run in the order mixins were listed, followed by a method call on the component.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/react-without-es6.md)

----
url: https://legacy.reactjs.org/blog/2015/05/01/graphql-introduction.html
----

May 01, 2015 by [Nick Schrock](https://twitter.com/schrockn)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

At the React.js conference in late January 2015, we revealed our next major technology in the React family: [Relay](/blog/2015/02/20/introducing-relay-and-graphql.html).

Relay is a new way of structuring client applications that co-locates data-fetching requirements and React components. Instead of placing data fetching logic in some other part of the client application – or embedding this logic in a custom endpoint on the server – we instead co-locate a *declarative* data-fetching specification alongside the React component. The language of this declarative specification is GraphQL.

GraphQL was not invented to enable Relay. In fact, GraphQL predates Relay by nearly three years. It was invented during the move from Facebook’s HTML5-driven mobile applications to purely native applications. It is a query language for graph data that powers the lion’s share of interactions in the Facebook Android and iOS applications. Any user of the native iOS or Android app in the last two years has used an app powered by GraphQL.

We plan to open-source a reference implementation of a GraphQL server and publish a language specification in the coming months. Our goal is to evolve GraphQL to adapt to a wide range of backends, so that projects and companies can use this technology to access their own data. We believe that this is a compelling way to structure servers and to provide powerful abstractions, frameworks and tools – including, but not exclusively, Relay – for product developers.

## [](#what-is-graphql)What is GraphQL?

A GraphQL query is a string interpreted by a server that returns data in a specified format. Here is an example query:

```
{
  user(id: 3500401) {
    id,
    name,
    isViewerFriend,
    profilePicture(size: 50)  {
      uri,
      width,
      height
    }
  }
}
```

(Note: this syntax is slightly different from previous GraphQL examples. We’ve recently been making improvements to the language.)

And here is the response to that query.

```
{
  "user" : {
    "id": 3500401,
    "name": "Jing Chen",
    "isViewerFriend": true,
    "profilePicture": {
      "uri": "http://someurl.cdn/pic.jpg",
      "width": 50,
      "height": 50
    }
  }
}
```

We will dig into the syntax and semantics of GraphQL in a later post, but even a simple example shows many of its design principles:

* **Hierarchical:** Most product development today involves the creation and manipulation of view hierarchies. To achieve congruence with the structure of these applications, a GraphQL query itself is a hierarchical set of fields. The query is shaped just like the data it returns. It is a natural way for product engineers to describe data requirements.
* **Product-centric:** GraphQL is unapologetically driven by the requirements of views and the front-end engineers that write them. We start with their way of thinking and requirements and build the language and runtime necessary to enable that.
* **Client-specified queries:** In GraphQL, the specification for queries are encoded in the *client* rather than the *server*. These queries are specified at field-level granularity. In the vast majority of applications written without GraphQL, the server determines the data returned in its various scripted endpoints. A GraphQL query, on the other hand, returns exactly what a client asks for and no more.
* **Backwards Compatible:** In a world of deployed native mobile applications with no forced upgrades, backwards compatibility is a challenge. Facebook, for example, releases apps on a two week fixed cycle and pledges to maintain those apps for *at least* two years. This means there are at a *minimum* 52 versions of our clients per platform querying our servers at any given time. Client-specified queries simplifies managing our backwards compatibility guarantees.
* **Structured, Arbitrary Code:** Query languages with field-level granularity have typically queried storage engines directly, such as SQL. GraphQL instead imposes a structure onto a server, and exposes fields that are backed by *arbitrary code*. This allows for both server-side flexibility and a uniform, powerful API across the entire surface area of an application.
* **Application-Layer Protocol:** GraphQL is an application-layer protocol and does not require a particular transport. It is a string that is parsed and interpreted by a server.
* **Strongly-typed:** GraphQL is strongly-typed. Given a query, tooling can ensure that the query is both syntactically correct and valid within the GraphQL type system before execution, i.e. at development time, and the server can make certain guarantees about the shape and nature of the response. This makes it easier to build high quality client tools.
* **Introspective:** GraphQL is introspective. Clients and tools can query the type system using the GraphQL syntax itself. This is a powerful platform for building tools and client software, such as automatic parsing of incoming data into strongly-typed interfaces. It is especially useful in statically typed languages such as Swift, Objective-C and Java, as it obviates the need for repetitive and error-prone code to shuffle raw, untyped JSON into strongly-typed business objects.

## [](#why-invent-something-new)Why invent something new?

Obviously GraphQL is not the first system to manage client-server interactions. In today’s world there are two dominant architectural styles for client-server interaction: REST and *ad hoc* endpoints.

### [](#rest)REST

REST, an acronym for Representational State Transfer, is an architectural style rather than a formal protocol. There is actually much debate about what exactly REST is and is not. We wish to avoid such debates. We are interested in the typical attributes of systems that *self-identify* as REST, rather than systems which are formally REST.

Objects in a typical REST system are addressable by URI and interacted with using verbs in the HTTP protocol. An HTTP GET to a particular URI fetches an object and returns a server-specified set of fields. An HTTP PUT edits an object; an HTTP DELETE deletes an object; and so on.

We believe there are a number of weakness in typical REST systems, ones that are particularly problematic in mobile applications:

* Fetching complicated object graphs require multiple round trips between the client and server to render single views. For mobile applications operating in variable network conditions, these multiple roundtrips are highly undesirable.
* Invariably fields and additional data are added to REST endpoints as the system requirements change. However, old clients also receive this additional data as well, because the data fetching specification is encoded on the server rather than the client. As result, these payloads tend to grow over time for all clients. When this becomes a problem for a system, one solution is to overlay a versioning system onto the REST endpoints. Versioning also complicates a server, and results in code duplication, spaghetti code, or a sophisticated, hand-rolled infrastructure to manage it. Another solution to limit over-fetching is to provide multiple views – such as “compact” vs “full” – of the same REST endpoint, however this coarse granularity often does not offer adequate flexibility.
* REST endpoints are usually weakly-typed and lack machine-readable metadata. While there is much debate about the merits of strong- versus weak-typing in distributed systems, we believe in strong typing because of the correctness guarantees and tooling opportunities it provides. Developers deal with systems that lack this metadata by inspecting frequently out-of-date documentation and then writing code against the documentation.
* Many of these attributes are linked to the fact that “REST is intended for long-lived network-based applications that span multiple organizations” [according to its inventor](http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven). This is not a requirement for APIs that serve a client app built within the same organization.

Nearly all externally facing REST APIs we know of trend or end up in these non-ideal states, as well as nearly all *internal* REST APIs. The consequences of opaqueness and over-fetching are more severe in internal APIs since their velocity of change and level of usage is almost always higher.

Because of multiple round-trips and over-fetching, applications built in the REST style inevitably end up building *ad hoc* endpoints that are superficially in the REST style. These actually couple the data to a particular view which explicitly violates one of REST’s major goals. Most REST systems of any complexity end up as a continuum of endpoints that span from “traditional” REST to *ad hoc* endpoints.

### [](#ad-hoc-endpoints)Ad Hoc Endpoints

Many applications have no formalized client-server contract. Product developers access server capabilities through *ad hoc* endpoints and write custom code to fetch the data they need. Servers define procedures, and they return data. This approach has the virtue of simplicity, but can often become untenable as systems age.

* These systems typically define a custom endpoint per view. For systems with a wide surface area this can quickly grow into a maintenance nightmare of orphaned endpoints, inconsistent tooling, and massive server code duplication. Disciplined engineering organizations can mitigate these issues with great engineering practices, high quality abstractions, and custom tooling. However, given our experience we believe that custom endpoints tend to lead to entropic server codebases.
* Much like REST, the payloads of custom endpoints grow monotonically (even with mitigation from versioning systems) as the server evolves. Deployed clients cannot break, and, with rapid release cycles and backwards compatibility guarantees, distributed applications will have large numbers of extant versions. Under these constraints it is difficult to remove data from a custom endpoint.
* Custom endpoints tend to – for a client developer – create a clunky, multi-language, multi-environment development process. No matter if the data has been accessed before in a different view, they are required to first change the custom endpoint, then deploy that code to a server accessible from a mobile device, and only then change the client to utilize that data. In GraphQL – unless the data in the view is completely new to the entire system – a product developer adds a field to a GraphQL query and the work on the client continues unabated.
* Much like REST, most systems with custom endpoints do not have a formalized type system, which eliminates the possibility for the tools and guarantees that introspective type systems can provide. Some custom-endpoint-driven systems do use a strongly typed serialization scheme, such as Protocol Buffers, Thrift, or XML. Those do allow for direct parsing of responses into typed classes and eliminating boilerplate shuffling from JSON into handwritten classes. These systems are as not as expressive and flexible as GraphQL, and the other downsides of *ad hoc* endpoints remain.

We believe that GraphQL represents a novel way of structuring the client-server contract. Servers publish a type system specific to their application, and GraphQL provides a unified language to query data within the constraints of that type system. That language allows product developers to express data requirements in a form natural to them: a declarative and hierarchal one.

This is a liberating platform for product developers. With GraphQL, no more contending with *ad hoc* endpoints or object retrieval with multiple roundtrips to access server data; instead an elegant, hierarchical, declarative query dispatched to a single endpoint. No more frequent jumps between client and server development environments to do experimentation or to change or create views of existing data; instead experiments are done and new views built within a native, client development environment exclusively. No more shuffling unstructured data from *ad hoc* endpoints into business objects; instead a powerful, introspective type system that serves as a platform for tool building.

Product developers are free to focus on their client software and requirements while rarely leaving their development environment; they can more confidently support shipped clients as a system evolves; and they are using a protocol designed to operate well within the constraints of mobile applications. Product developers can query for exactly what they want, in the way they think about it, across their entire application’s data model.

## [](#whats-next)What’s next?

Over the coming months, we will share more technical details about GraphQL, including additional language features, tools that support it, and how it is built and used at Facebook. These posts will culminate in a formal specification of GraphQL to guide implementors across various languages and platforms. We also plan on releasing a reference implementation in the summer, in order to provide a basis for custom deployments and a platform for experimentation. We’re incredibly excited to share this system and work with the open source community to improve it.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2015-05-01-graphql-introduction.md)

----
url: https://legacy.reactjs.org/warnings/unknown-prop.html
----

The unknown-prop warning will fire if you attempt to render a DOM element with a prop that is not recognized by React as a legal DOM attribute/property. You should ensure that your DOM elements do not have spurious props floating around.

There are a couple of likely reasons this warning could be appearing:

1. Are you using `{...this.props}` or `cloneElement(element, this.props)`? Your component is transferring its own props directly to a child element (eg. [transferring props](/docs/transferring-props.html)). When transferring props to a child component, you should ensure that you are not accidentally forwarding props that were intended to be interpreted by the parent component.
2. You are using a non-standard DOM attribute on a native DOM node, perhaps to represent custom data. If you are trying to attach custom data to a standard DOM element, consider using a custom data attribute as described [on MDN](https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Using_data_attributes).
3. React does not yet recognize the attribute you specified. This will likely be fixed in a future version of React. However, React currently strips all unknown attributes, so specifying them in your React app will not cause them to be rendered.
4. You are using a React component without an upper case. React interprets it as a DOM tag because [React JSX transform uses the upper vs. lower case convention to distinguish between user-defined components and DOM tags](/docs/jsx-in-depth.html#user-defined-components-must-be-capitalized).

***

To fix this, composite components should “consume” any prop that is intended for the composite component and not intended for the child component. Example:

**Bad:** Unexpected `layout` prop is forwarded to the `div` tag.

```
function MyDiv(props) {
  if (props.layout === 'horizontal') {
    // BAD! Because you know for sure "layout" is not a prop that <div> understands.
    return <div {...props} style={getHorizontalStyle()} />
  } else {
    // BAD! Because you know for sure "layout" is not a prop that <div> understands.
    return <div {...props} style={getVerticalStyle()} />
  }
}
```

**Good:** The spread syntax can be used to pull variables off props, and put the remaining props into a variable.

```
function MyDiv(props) {
  const { layout, ...rest } = props
  if (layout === 'horizontal') {
    return <div {...rest} style={getHorizontalStyle()} />
  } else {
    return <div {...rest} style={getVerticalStyle()} />
  }
}
```

**Good:** You can also assign the props to a new object and delete the keys that you’re using from the new object. Be sure not to delete the props from the original `this.props` object, since that object should be considered immutable.

```
function MyDiv(props) {

  const divProps = Object.assign({}, props);
  delete divProps.layout;

  if (props.layout === 'horizontal') {
    return <div {...divProps} style={getHorizontalStyle()} />
  } else {
    return <div {...divProps} style={getVerticalStyle()} />
  }
}
```

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/warnings/unknown-prop.md)

----
url: https://legacy.reactjs.org/blog/2014/10/16/react-v0.12-rc1.html
----

October 16, 2014 by [Sebastian Markbåge](https://twitter.com/sebmarkbage)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

We are finally ready to share the work we’ve been doing over the past couple months. A lot has gone into this and we want to make sure we iron out any potential issues before we make this final. So, we’re shipping a Release Candidate for React v0.12 today. If you get a chance, please give it a try and report any issues you find! A full changelog will accompany the final release but we’ve highlighted the interesting and breaking changes below.

The release candidate is available for download:

* **React**\
  Dev build with warnings: <https://fb.me/react-0.12.0-rc1.js>\
  Minified build for production: <https://fb.me/react-0.12.0-rc1.min.js>
* **React with Add-Ons**\
  Dev build with warnings: <https://fb.me/react-with-addons-0.12.0-rc1.js>\
  Minified build for production: <https://fb.me/react-with-addons-0.12.0-rc1.min.js>
* **In-Browser JSX transformer**\
  <https://fb.me/JSXTransformer-0.12.0-rc1.js>

We’ve also published version `0.12.0-rc1` of the `react` and `react-tools` packages on npm and the `react` package on bower.

## [](#react-elements)React Elements

The biggest conceptual change we made in v0.12 is the move to React Elements. [We talked about this topic in depth earlier this week](/blog/2014/10/14/introducing-react-elements.html). If you haven’t already, you should read up on the exciting changes in there!

## [](#jsx-changes)JSX Changes

Earlier this year we decided to write [a specification for JSX](https://facebook.github.io/jsx/). This has allowed us to make some changes focused on the React specific JSX and still allow others to innovate in the same space.

### [](#the-jsx-pragma-is-gone)The `@jsx` Pragma is Gone!

We have wanted to do this since before we even open sourced React. No more `/** @jsx React.DOM */`!. The React specific JSX transform assumes you have `React` in scope (which had to be true before anyway).

`JSXTransformer` and `react-tools` have both been updated to account for this.

### [](#jsx-for-function-calls-is-no-longer-supported)JSX for Function Calls is No Longer Supported

The React specific JSX transform no longer transforms to function calls. Instead we use `React.createElement` and pass it arguments. This allows us to make optimizations and better support React as a compile target for things like Om. Read more in the [React Elements introduction](/blog/2014/10/14/introducting-react-elements.html).

The result of this change is that we will no longer support arbitrary function calls. We understand that the ability to do was a convenient shortcut for many people but we believe the gains will be worth it.

### [](#jsx-lower-case-convention)JSX Lower-case Convention

We used to have a whitelist of HTML tags that got special treatment in JSX. However as new HTML tags got added to the spec, or we added support for more SVG tags, we had to go update our whitelist. Additionally, there was ambiguity about the behavior. There was always the chance that something new added to the tag list would result in breaking your code. For example:

```
return <component />;
```

Is `component` an existing HTML tag? What if it becomes one?

To address this, we decided on a convention: **All JSX tags that start with a lower-case letter or contain a dash are treated as HTML.**

This means that you no longer have to wait for us to upgrade JSX to use new tags. This also introduces the possibility to consume custom elements (Web Components) - although custom attributes are not yet fully supported.

Currently we still use the whitelist as a sanity check. The transform will fail when it encounters an unknown tag. This allows you to update your code without hitting errors in production.

In addition, the HTML tags are converted to strings instead of using `React.DOM` directly. `<div/>` becomes `React.createElement('div')` instead of `React.DOM.div()`.

### [](#jsx-spread-attributes)JSX Spread Attributes

Previously there wasn’t a way to for you to pass a dynamic or unknown set of properties through JSX. This is now possible using the spread `...` operator.

```
var myProps = { a: 1, b: 2 };
return <MyComponent {...myProps} />;
```

This merges the properties of the object onto the props of `MyComponent`.

[Read More About Spread Attributes](https://gist.github.com/sebmarkbage/07bbe37bc42b6d4aef81)

If you used to use plain function calls to pass arbitrary props objects…

```
return MyComponent(myProps);
```

You can now switch to using Spread Attributes instead:

```
return <MyComponent {...myProps} />;
```

## [](#breaking-change-key-and-ref-removed-from-thisprops)Breaking Change: `key` and `ref` Removed From `this.props`

The props `key` and `ref` were already reserved property names. This turned out to be difficult to explicitly statically type since any object can accept these extra props. It also screws up JIT optimizations of React internals in modern VMs.

These are concepts that React manages from outside the Component before it even gets created so it shouldn’t be part of the props.

We made this distinction clearer by moving them off the props object and onto the `ReactElement` itself. This means that you need to rename:

`someElement.props.key` -> `someElement.key`

You can no longer access `this.props.ref` and `this.props.key` from inside the Component instance itself. So you need to use a different name for those props.

You do NOT need to change the way to define `key` and `ref`, only if you need to read it. E.g. `<div key="my-key" />` and `div({ key: 'my-key' })` still works.

## [](#breaking-change-default-props-resolution)Breaking Change: Default Props Resolution

This is a subtle difference but `defaultProps` are now resolved at `ReactElement` creation time instead of when it’s mounted. This is means that we can avoid allocating an extra object for the resolved props.

You will primarily see this breaking if you’re also using `transferPropsTo`.

## [](#deprecated-transferpropsto)Deprecated: transferPropsTo

`transferPropsTo` is deprecated in v0.12 and will be removed in v0.13. This helper function was a bit magical. It auto-merged a certain whitelist of properties and excluded others. It was also transferring too many properties. This meant that we have to keep a whitelist of valid HTML attributes in the React runtime. It also means that we can’t catch typos on props.

Our suggested solution is to use the Spread Attributes.

```
return <div {...this.props} />;
```

Or, just if you’re not using JSX:

```
return div(this.props);
```

Although to avoid passing too many props down, you’ll probably want to use something like ES7 rest properties. [Read more about upgrading from transferPropsTo](https://gist.github.com/sebmarkbage/a6e220b7097eb3c79ab7).

## [](#deprecated-returning-false-in-event-handlers)Deprecated: Returning `false` in Event Handlers

It used to be possible to return `false` from event handlers to preventDefault. We did this because this works in most browsers. This is a confusing API and we might want to use the return value for something else. Therefore, this is deprecated. Use `event.preventDefault()` instead.

## [](#renamed-apis)Renamed APIs

As part of the [new React terminology](https://gist.github.com/sebmarkbage/fcb1b6ab493b0c77d589) we aliased some existing APIs to use the new naming convention:

* `React.renderComponent` -> `React.render`
* `React.renderComponentToString` -> `React.renderToString`
* `React.renderComponentToStaticMarkup` -> `React.renderToStaticMarkup`
* `React.isValidComponent` -> `React.isValidElement`
* `React.PropTypes.component` -> `React.PropTypes.element`
* `React.PropTypes.renderable` -> `React.PropTypes.node`

The older APIs will log a warning but work the same. They will be removed in v0.13.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2014-10-16-react-v0.12-rc1.md)

----
url: https://react.dev/reference/react-compiler/panicThreshold
----

[API Reference](/reference/react)

[Configuration](/reference/react-compiler/configuration)

# panicThreshold[](#undefined "Link for this heading")

The `panicThreshold` option controls how the React Compiler handles errors during compilation.

```
{

  panicThreshold: 'none' // Recommended

}
```

* [Reference](#reference)
  * [`panicThreshold`](#panicthreshold)

* [Usage](#usage)

  * [Production configuration (recommended)](#production-configuration)
  * [Development debugging](#development-debugging)

***

## Reference[](#reference "Link for Reference ")

### `panicThreshold`[](#panicthreshold "Link for this heading")

Determines whether compilation errors should fail the build or skip optimization.

#### Type[](#type "Link for Type ")

```
'none' | 'critical_errors' | 'all_errors'
```

#### Default value[](#default-value "Link for Default value ")

`'none'`

#### Options[](#options "Link for Options ")

* **`'none'`** (default, recommended): Skip components that can’t be compiled and continue building
* **`'critical_errors'`**: Fail the build only on critical compiler errors
* **`'all_errors'`**: Fail the build on any compiler diagnostic

#### Caveats[](#caveats "Link for Caveats ")

* Production builds should always use `'none'`
* Build failures prevent your application from building
* The compiler automatically detects and skips problematic code with `'none'`
* Higher thresholds are only useful during development for debugging

***

## Usage[](#usage "Link for Usage ")

### Production configuration (recommended)[](#production-configuration "Link for Production configuration (recommended) ")

For production builds, always use `'none'`. This is the default value:

```
{

  panicThreshold: 'none'

}
```

This ensures:

* Your build never fails due to compiler issues
* Components that can’t be optimized run normally
* Maximum components get optimized
* Stable production deployments

### Development debugging[](#development-debugging "Link for Development debugging ")

Temporarily use stricter thresholds to find issues:

```
const isDevelopment = process.env.NODE_ENV === 'development';



{

  panicThreshold: isDevelopment ? 'critical_errors' : 'none',

  logger: {

    logEvent(filename, event) {

      if (isDevelopment && event.kind === 'CompileError') {

        // ...

      }

    }

  }

}
```

[Previouslogger](/reference/react-compiler/logger)

[Nexttarget](/reference/react-compiler/target)

***

----
url: https://18.react.dev/reference/react-dom/preload
----

[API Reference](/reference/react)

[APIs](/reference/react-dom)

# preload[](#undefined "Link for this heading")

### Canary

The `preload` function is currently only available in React’s Canary and experimental channels. Learn more about [React’s release channels here](/community/versioning-policy#all-release-channels).

### Note

[React-based frameworks](/learn/start-a-new-react-project) frequently handle resource loading for you, so you might not have to call this API yourself. Consult your framework’s documentation for details.

`preload` lets you eagerly fetch a resource such as a stylesheet, font, or external script that you expect to use.

```
preload("https://example.com/font.woff2", {as: "font"});
```

* [Reference](#reference)
  * [`preload(href, options)`](#preload)

* [Usage](#usage)

  * [Preloading when rendering](#preloading-when-rendering)
  * [Preloading in an event handler](#preloading-in-an-event-handler)

***

## Reference[](#reference "Link for Reference ")

### `preload(href, options)`[](#preload "Link for this heading")

To preload a resource, call the `preload` function from `react-dom`.

```
import { preload } from 'react-dom';



function AppRoot() {

  preload("https://example.com/font.woff2", {as: "font"});

  // ...

}
```

***

## Usage[](#usage "Link for Usage ")

### Preloading when rendering[](#preloading-when-rendering "Link for Preloading when rendering ")

Call `preload` when rendering a component if you know that it or its children will use a specific resource.

#### Examples of preloading[](#examples "Link for Examples of preloading")

#### Example 1 of 4:Preloading an external script[](#preloading-an-external-script "Link for this heading")

```
import { preload } from 'react-dom';



function AppRoot() {

  preload("https://example.com/script.js", {as: "script"});

  return ...;

}
```

If you want the browser to start executing the script immediately (rather than just downloading it), use [`preinit`](/reference/react-dom/preinit) instead. If you want to load an ESM module, use [`preloadModule`](/reference/react-dom/preloadModule).

### Preloading in an event handler[](#preloading-in-an-event-handler "Link for Preloading in an event handler ")

Call `preload` in an event handler before transitioning to a page or state where external resources will be needed. This gets the process started earlier than if you call it during the rendering of the new page or state.

```
import { preload } from 'react-dom';



function CallToAction() {

  const onClick = () => {

    preload("https://example.com/wizardStyles.css", {as: "style"});

    startWizard();

  }

  return (

    <button onClick={onClick}>Start Wizard</button>

  );

}
```

[PreviouspreinitModule](/reference/react-dom/preinitModule)

[NextpreloadModule](/reference/react-dom/preloadModule)

***

----
url: https://legacy.reactjs.org/docs/hello-world.html
----

> These docs are old and won’t be updated. Go to [react.dev](https://react.dev/) for the new React docs.
>
> See [Quick Start](https://react.dev/learn) for an introduction to React.

The smallest React example looks like this:

```
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<h1>Hello, world!</h1>);
```

It displays a heading saying “Hello, world!” on the page.

**[Try it on CodePen](https://codepen.io/gaearon/pen/rrpgNB?editors=1010)**

Click the link above to open an online editor. Feel free to make some changes, and see how they affect the output. Most pages in this guide will have editable examples like this one.

## [](#how-to-read-this-guide)How to Read This Guide

In this guide, we will examine the building blocks of React apps: elements and components. Once you master them, you can create complex apps from small reusable pieces.

> Tip
>
> This guide is designed for people who prefer **learning concepts step by step**. If you prefer to learn by doing, check out our [practical tutorial](/tutorial/tutorial.html). You might find this guide and the tutorial complementary to each other.

This is the first chapter in a step-by-step guide about main React concepts. You can find a list of all its chapters in the navigation sidebar. If you’re reading this from a mobile device, you can access the navigation by pressing the button in the bottom right corner of your screen.

Every chapter in this guide builds on the knowledge introduced in earlier chapters. **You can learn most of React by reading the “Main Concepts” guide chapters in the order they appear in the sidebar.** For example, [“Introducing JSX”](/docs/introducing-jsx.html) is the next chapter after this one.

## [](#knowledge-level-assumptions)Knowledge Level Assumptions

React is a JavaScript library, and so we’ll assume you have a basic understanding of the JavaScript language. **If you don’t feel very confident, we recommend [going through a JavaScript tutorial](https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript) to check your knowledge level** and enable you to follow along this guide without getting lost. It might take you between 30 minutes and an hour, but as a result you won’t have to feel like you’re learning both React and JavaScript at the same time.

> Note
>
> This guide occasionally uses some newer JavaScript syntax in the examples. If you haven’t worked with JavaScript in the last few years, [these three points](https://gist.github.com/gaearon/683e676101005de0add59e8bb345340c) should get you most of the way.

## [](#lets-get-started)Let’s Get Started!

Keep scrolling down, and you’ll find the link to the [next chapter of this guide](/docs/introducing-jsx.html) right before the website footer.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/hello-world.md)

* Previous article

  [Release Channels](/docs/release-channels.html)

* Next article

  [Introducing JSX](/docs/introducing-jsx.html)

----
url: https://legacy.reactjs.org/docs/code-splitting.html
----

> These docs are old and won’t be updated. Go to [react.dev](https://react.dev/) for the new React docs.
>
> These new documentation pages teach modern React and include live examples:
>
> * [`lazy`](https://react.dev/reference/react/lazy)
> * [`<Suspense>`](https://react.dev/reference/react/Suspense)

## [](#bundling)Bundling

Most React apps will have their files “bundled” using tools like [Webpack](https://webpack.js.org/), [Rollup](https://rollupjs.org/) or [Browserify](http://browserify.org/). Bundling is the process of following imported files and merging them into a single file: a “bundle”. This bundle can then be included on a webpage to load an entire app at once.

#### [](#example)Example

**App:**

```
// app.js
import { add } from './math.js';

console.log(add(16, 26)); // 42
```

```
// math.js
export function add(a, b) {
  return a + b;
}
```

**Bundle:**

```
function add(a, b) {
  return a + b;
}

console.log(add(16, 26)); // 42
```

> Note:
>
> Your bundles will end up looking a lot different than this.

If you’re using [Create React App](https://create-react-app.dev/), [Next.js](https://nextjs.org/), [Gatsby](https://www.gatsbyjs.org/), or a similar tool, you will have a Webpack setup out of the box to bundle your app.

If you aren’t, you’ll need to set up bundling yourself. For example, see the [Installation](https://webpack.js.org/guides/installation/) and [Getting Started](https://webpack.js.org/guides/getting-started/) guides on the Webpack docs.

## [](#code-splitting)Code Splitting

Bundling is great, but as your app grows, your bundle will grow too. Especially if you are including large third-party libraries. You need to keep an eye on the code you are including in your bundle so that you don’t accidentally make it so large that your app takes a long time to load.

To avoid winding up with a large bundle, it’s good to get ahead of the problem and start “splitting” your bundle. Code-Splitting is a feature supported by bundlers like [Webpack](https://webpack.js.org/guides/code-splitting/), [Rollup](https://rollupjs.org/guide/en/#code-splitting) and Browserify (via [factor-bundle](https://github.com/browserify/factor-bundle)) which can create multiple bundles that can be dynamically loaded at runtime.

Code-splitting your app can help you “lazy-load” just the things that are currently needed by the user, which can dramatically improve the performance of your app. While you haven’t reduced the overall amount of code in your app, you’ve avoided loading code that the user may never need, and reduced the amount of code needed during the initial load.

## [](#import)`import()`

The best way to introduce code-splitting into your app is through the dynamic `import()` syntax.

**Before:**

```
import { add } from './math';

console.log(add(16, 26));
```

**After:**

```
import("./math").then(math => {
  console.log(math.add(16, 26));
});
```

When Webpack comes across this syntax, it automatically starts code-splitting your app. If you’re using Create React App, this is already configured for you and you can [start using it](https://create-react-app.dev/docs/code-splitting/) immediately. It’s also supported out of the box in [Next.js](https://nextjs.org/docs/advanced-features/dynamic-import).

If you’re setting up Webpack yourself, you’ll probably want to read Webpack’s [guide on code splitting](https://webpack.js.org/guides/code-splitting/). Your Webpack config should look vaguely [like this](https://gist.github.com/gaearon/ca6e803f5c604d37468b0091d9959269).

When using [Babel](https://babeljs.io/), you’ll need to make sure that Babel can parse the dynamic import syntax but is not transforming it. For that you will need [@babel/plugin-syntax-dynamic-import](https://classic.yarnpkg.com/en/package/@babel/plugin-syntax-dynamic-import).

## [](#reactlazy)`React.lazy`

The `React.lazy` function lets you render a dynamic import as a regular component.

**Before:**

```
import OtherComponent from './OtherComponent';
```

**After:**

```
const OtherComponent = React.lazy(() => import('./OtherComponent'));
```

This will automatically load the bundle containing the `OtherComponent` when this component is first rendered.

`React.lazy` takes a function that must call a dynamic `import()`. This must return a `Promise` which resolves to a module with a `default` export containing a React component.

The lazy component should then be rendered inside a `Suspense` component, which allows us to show some fallback content (such as a loading indicator) while we’re waiting for the lazy component to load.

```
import React, { Suspense } from 'react';

const OtherComponent = React.lazy(() => import('./OtherComponent'));

function MyComponent() {
  return (
    <div>
      <Suspense fallback={<div>Loading...</div>}>
        <OtherComponent />
      </Suspense>
    </div>
  );
}
```

The `fallback` prop accepts any React elements that you want to render while waiting for the component to load. You can place the `Suspense` component anywhere above the lazy component. You can even wrap multiple lazy components with a single `Suspense` component.

```
import React, { Suspense } from 'react';

const OtherComponent = React.lazy(() => import('./OtherComponent'));
const AnotherComponent = React.lazy(() => import('./AnotherComponent'));

function MyComponent() {
  return (
    <div>
      <Suspense fallback={<div>Loading...</div>}>
        <section>
          <OtherComponent />
          <AnotherComponent />
        </section>
      </Suspense>
    </div>
  );
}
```

### [](#avoiding-fallbacks)Avoiding fallbacks

Any component may suspend as a result of rendering, even components that were already shown to the user. In order for screen content to always be consistent, if an already shown component suspends, React has to hide its tree up to the closest `<Suspense>` boundary. However, from the user’s perspective, this can be disorienting.

Consider this tab switcher:

```
import React, { Suspense } from 'react';
import Tabs from './Tabs';
import Glimmer from './Glimmer';

const Comments = React.lazy(() => import('./Comments'));
const Photos = React.lazy(() => import('./Photos'));

function MyComponent() {
  const [tab, setTab] = React.useState('photos');
  
  function handleTabSelect(tab) {
    setTab(tab);
  };

  return (
    <div>
      <Tabs onTabSelect={handleTabSelect} />
      <Suspense fallback={<Glimmer />}>
        {tab === 'photos' ? <Photos /> : <Comments />}
      </Suspense>
    </div>
  );
}
```

In this example, if tab gets changed from `'photos'` to `'comments'`, but `Comments` suspends, the user will see a glimmer. This makes sense because the user no longer wants to see `Photos`, the `Comments` component is not ready to render anything, and React needs to keep the user experience consistent, so it has no choice but to show the `Glimmer` above.

However, sometimes this user experience is not desirable. In particular, it is sometimes better to show the “old” UI while the new UI is being prepared. You can use the new [`startTransition`](/docs/react-api.html#starttransition) API to make React do this:

```
function handleTabSelect(tab) {
  startTransition(() => {
    setTab(tab);
  });
}
```

Here, you tell React that setting tab to `'comments'` is not an urgent update, but is a [transition](/docs/react-api.html#transitions) that may take some time. React will then keep the old UI in place and interactive, and will switch to showing `<Comments />` when it is ready. See [Transitions](/docs/react-api.html#transitions) for more info.

### [](#error-boundaries)Error boundaries

If the other module fails to load (for example, due to network failure), it will trigger an error. You can handle these errors to show a nice user experience and manage recovery with [Error Boundaries](/docs/error-boundaries.html). Once you’ve created your Error Boundary, you can use it anywhere above your lazy components to display an error state when there’s a network error.

```
import React, { Suspense } from 'react';
import MyErrorBoundary from './MyErrorBoundary';

const OtherComponent = React.lazy(() => import('./OtherComponent'));
const AnotherComponent = React.lazy(() => import('./AnotherComponent'));

const MyComponent = () => (
  <div>
    <MyErrorBoundary>
      <Suspense fallback={<div>Loading...</div>}>
        <section>
          <OtherComponent />
          <AnotherComponent />
        </section>
      </Suspense>
    </MyErrorBoundary>
  </div>
);
```

## [](#route-based-code-splitting)Route-based code splitting

Deciding where in your app to introduce code splitting can be a bit tricky. You want to make sure you choose places that will split bundles evenly, but won’t disrupt the user experience.

A good place to start is with routes. Most people on the web are used to page transitions taking some amount of time to load. You also tend to be re-rendering the entire page at once so your users are unlikely to be interacting with other elements on the page at the same time.

Here’s an example of how to setup route-based code splitting into your app using libraries like [React Router](https://reactrouter.com/) with `React.lazy`.

```
import React, { Suspense, lazy } from 'react';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';

const Home = lazy(() => import('./routes/Home'));
const About = lazy(() => import('./routes/About'));

const App = () => (
  <Router>
    <Suspense fallback={<div>Loading...</div>}>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
      </Routes>
    </Suspense>
  </Router>
);
```

## [](#named-exports)Named Exports

`React.lazy` currently only supports default exports. If the module you want to import uses named exports, you can create an intermediate module that reexports it as the default. This ensures that tree shaking keeps working and that you don’t pull in unused components.

```
// ManyComponents.js
export const MyComponent = /* ... */;
export const MyUnusedComponent = /* ... */;
```

```
// MyComponent.js
export { MyComponent as default } from "./ManyComponents.js";
```

```
// MyApp.js
import React, { lazy } from 'react';
const MyComponent = lazy(() => import("./MyComponent.js"));
```

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/code-splitting.md)

----
url: https://react.dev/reference/react-dom/server
----

[API Reference](/reference/react)

# Server React DOM APIs[](#undefined "Link for this heading")

The `react-dom/server` APIs let you server-side render React components to HTML. These APIs are only used on the server at the top level of your app to generate the initial HTML. A [framework](/learn/creating-a-react-app#full-stack-frameworks) may call them for you. Most of your components don’t need to import or use them.

***

## Server APIs for Web Streams[](#server-apis-for-web-streams "Link for Server APIs for Web Streams ")

These methods are only available in the environments with [Web Streams](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API), which includes browsers, Deno, and some modern edge runtimes:

* [`renderToReadableStream`](/reference/react-dom/server/renderToReadableStream) renders a React tree to a [Readable Web Stream.](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream)
* [`resume`](/reference/react-dom/server/renderToPipeableStream) resumes [`prerender`](/reference/react-dom/static/prerender) to a [Readable Web Stream](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream).

### Note

Node.js also includes these methods for compatibility, but they are not recommended due to worse performance. Use the [dedicated Node.js APIs](#server-apis-for-nodejs-streams) instead.

***

## Server APIs for Node.js Streams[](#server-apis-for-nodejs-streams "Link for Server APIs for Node.js Streams ")

These methods are only available in the environments with [Node.js Streams:](https://nodejs.org/api/stream.html)

* [`renderToPipeableStream`](/reference/react-dom/server/renderToPipeableStream) renders a React tree to a pipeable [Node.js Stream.](https://nodejs.org/api/stream.html)
* [`resumeToPipeableStream`](/reference/react-dom/server/renderToPipeableStream) resumes [`prerenderToNodeStream`](/reference/react-dom/static/prerenderToNodeStream) to a pipeable [Node.js Stream.](https://nodejs.org/api/stream.html)

***

## Legacy Server APIs for non-streaming environments[](#legacy-server-apis-for-non-streaming-environments "Link for Legacy Server APIs for non-streaming environments ")

These methods can be used in the environments that don’t support streams:

* [`renderToString`](/reference/react-dom/server/renderToString) renders a React tree to a string.
* [`renderToStaticMarkup`](/reference/react-dom/server/renderToStaticMarkup) renders a non-interactive React tree to a string.

They have limited functionality compared to the streaming APIs.

[PrevioushydrateRoot](/reference/react-dom/client/hydrateRoot)

[NextrenderToPipeableStream](/reference/react-dom/server/renderToPipeableStream)

***

----
url: https://react.dev/reference/eslint-plugin-react-hooks/lints/error-boundaries
----

[API Reference](/reference/react)

[Lints](/reference/eslint-plugin-react-hooks)

# error-boundaries[](#undefined "Link for this heading")

Validates usage of Error Boundaries instead of try/catch for errors in child components.

## Rule Details[](#rule-details "Link for Rule Details ")

Try/catch blocks can’t catch errors that happen during React’s rendering process. Errors thrown in rendering methods or hooks bubble up through the component tree. Only [Error Boundaries](/reference/react/Component#catching-rendering-errors-with-an-error-boundary) can catch these errors.

### Invalid[](#invalid "Link for Invalid ")

Examples of incorrect code for this rule:

```
// ❌ Try/catch won't catch render errors

function Parent() {

  try {

    return <ChildComponent />; // If this throws, catch won't help

  } catch (error) {

    return <div>Error occurred</div>;

  }

}
```

### Valid[](#valid "Link for Valid ")

Examples of correct code for this rule:

```
// ✅ Using error boundary

function Parent() {

  return (

    <ErrorBoundary>

      <ChildComponent />

    </ErrorBoundary>

  );

}
```

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### Why is the linter telling me not to wrap `use` in `try`/`catch`?[](#why-is-the-linter-telling-me-not-to-wrap-use-in-trycatch "Link for this heading")

The `use` hook doesn’t throw errors in the traditional sense, it suspends component execution. When `use` encounters a pending promise, it suspends the component and lets React show a fallback. Only Suspense and Error Boundaries can handle these cases. The linter warns against `try`/`catch` around `use` to prevent confusion as the `catch` block would never run.

```
// ❌ Try/catch around `use` hook

function Component({promise}) {

  try {

    const data = use(promise); // Won't catch - `use` suspends, not throws

    return <div>{data}</div>;

  } catch (error) {

    return <div>Failed to load</div>; // Unreachable

  }

}



// ✅ Error boundary catches `use` errors

function App() {

  return (

    <ErrorBoundary fallback={<div>Failed to load</div>}>

      <Suspense fallback={<div>Loading...</div>}>

        <DataComponent promise={fetchData()} />

      </Suspense>

    </ErrorBoundary>

  );

}
```

[Previousconfig](/reference/eslint-plugin-react-hooks/lints/config)

[Nextgating](/reference/eslint-plugin-react-hooks/lints/gating)

***

----
url: https://legacy.reactjs.org/blog/2018/12/19/react-v-16-7.html
----

December 19, 2018 by [Andrew Clark](https://twitter.com/acdlite)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

Our latest release includes an important performance bugfix for `React.lazy`. Although there are no API changes, we’re releasing it as a minor instead of a patch.

## [](#why-is-this-bugfix-a-minor-instead-of-a-patch)Why Is This Bugfix a Minor Instead of a Patch?

React follows [semantic versioning](/docs/faq-versioning.html). Typically, this means that we use patch versions for bugfixes, and minors for new (non-breaking) features. However, we reserve the option to release minor versions even if they do not include new features. The motivation is to reserve patches for changes that have a very low chance of breaking. Patches are the most important type of release because they sometimes contain critical bugfixes. That means patch releases have a higher bar for reliability. It’s unacceptable for a patch to introduce additional bugs, because if people come to distrust patches, it compromises our ability to fix critical bugs when they arise — for example, to fix a security vulnerability.

We never intend to ship bugs. React has a hard-earned reputation for stability, and we intend to keep it that way. We thoroughly test every version of React before releasing. This includes unit tests, generative (fuzzy) tests, integration tests, and internal dogfooding across tens of thousands of components. However, sometimes we make mistakes. That’s why, going forward, our policy will be that if a release contains non-trivial changes, we will bump the minor version, even if the external behavior is the same. We’ll also bump the minor when changing `unstable_`-prefixed APIs.

## [](#can-i-use-hooks-yet)Can I Use Hooks Yet?

Not yet, but soon!

At React Conf, we said that 16.7 would be the first release to include Hooks. This was a mistake. We shouldn’t have attached a specific version number to an unreleased feature. We’ll avoid this in the future.

Although 16.7 does not include Hooks, please do not infer anything about the timeline of the Hooks launch. Our plans for Hooks are unchanged:

* The [Hooks proposal](https://github.com/reactjs/rfcs/pull/68) was accepted ([with minor planned changes in response to feedback](https://github.com/reactjs/rfcs/pull/68#issuecomment-439314884)).
* The [implementation](https://github.com/facebook/react/commit/7bee9fbdd49aa5b9365a94b0ddf6db04bc1bf51c) was merged into the React repo (behind a feature flag).
* We’re currently in the testing phase, and you can expect a public release within a few months.

We’ve heard from many people who want to start using Hooks in their apps. We also can’t wait to ship them! But because Hooks changes how we write React components, we are taking extra time to get the details right. We appreciate your patience as we prepare this exciting new feature for widespread, ahem, *use*.

Learn more about [our roadmap](/blog/2018/11/27/react-16-roadmap.html) in our previous post.

## [](#installation)Installation

React v16.7.0 is available on the npm registry.

To install React 16 with Yarn, run:

```
yarn add react@^16.7.0 react-dom@^16.7.0
```

To install React 16 with npm, run:

```
npm install --save react@^16.7.0 react-dom@^16.7.0
```

We also provide UMD builds of React via a CDN:

```
<script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
```

Refer to the documentation for [detailed installation instructions](/docs/installation.html).

## [](#changelog)Changelog

### [](#react-dom)React DOM

* Fix performance of `React.lazy` for large numbers of lazily-loaded components. ([@acdlite](http://github.com/acdlite) in [#14429](https://github.com/facebook/react/pull/14429))
* Clear fields on unmount to avoid memory leaks. ([@trueadm](http://github.com/trueadm) in [#14276](https://github.com/facebook/react/pull/14276))
* Fix bug with SSR and context when mixing `react-dom/server@16.6` and `react@<16.6`. ([@gaearon](http://github.com/gaearon) in [#14291](https://github.com/facebook/react/pull/14291))
* Fix a performance regression in profiling mode. ([@bvaughn](http://github.com/bvaughn) in [#14383](https://github.com/facebook/react/pull/14383))

### [](#scheduler-experimental)Scheduler (Experimental)

* Post to MessageChannel instead of window. ([@acdlite](http://github.com/acdlite) in [#14234](https://github.com/facebook/react/pull/14234))
* Reduce serialization overhead. ([@developit](http://github.com/developit) in [#14249](https://github.com/facebook/react/pull/14249))
* Fix fallback to `setTimeout` in testing environments. ([@bvaughn](http://github.com/bvaughn) in [#14358](https://github.com/facebook/react/pull/14358))
* Add methods for debugging. ([@mrkev](http://github.com/mrkev) in [#14053](https://github.com/facebook/react/pull/14053))

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2018-12-19-react-v-16-7.md)

----
url: https://legacy.reactjs.org/blog/2016/03/07/react-v15-rc1.html
----

March 07, 2016 by [Paul O’Shannessy](https://twitter.com/zpao)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

Sorry for the small delay in releasing this. As we said, we’ve been busy binge-watching House of Cards. That scene in the last episode where Francis and Claire Underwood ████████████████████████████████████. WOW!

But now we’re ready, so without further ado, we’re shipping a release candidate for React v15 now. As a reminder, [we’re switching to major versions](/blog/2016/02/19/new-versioning-scheme.html) to indicate that we have been using React in production for a long time. This 15.0 release follows our previous 0.14 version and we’ll continue to follow semver like we’ve been doing since 2013. It’s also worth noting that [we no longer actively support Internet Explorer 8](/blog/2016/01/12/discontinuing-ie8-support.html). We believe React will work in its current form there but we will not be prioritizing any efforts to fix new issues that only affect IE8.

Please try it out before we publish the final release. Let us know if you run into any problems by filing issues on our [GitHub repo](https://github.com/facebook/react).

## [](#upgrade-guide)Upgrade Guide

Like always, we have a few breaking changes in this release. We know changes can be painful (the Facebook codebase has over 15,000 React components), so we always try to make changes gradually in order to minimize the pain.

If your code is free of warnings when running under React 0.14, upgrading should be easy. The bulk of changes in this release are actually behind the scenes, impacting the way that React interacts with the DOM. The other substantial change is that React now supports the full range of SVG elements and attributes. Beyond that we have a large number of incremental improvements and additional warnings aimed to aid developers. We’ve also laid some groundwork in the core to bring you some new capabilities in future releases.

See the changelog below for more details.

## [](#installation)Installation

We recommend using React from `npm` and using a tool like browserify or webpack to build your code into a single bundle. To install the two packages:

* `npm install --save react@15.0.0-rc.1 react-dom@15.0.0-rc.1`

Remember that by default, React runs extra checks and provides helpful warnings in development mode. When deploying your app, set the `NODE_ENV` environment variable to `production` to use the production build of React which does not include the development warnings and runs significantly faster.

If you can’t use `npm` yet, we provide pre-built browser builds for your convenience, which are also available in the `react` package on bower.

* **React**\
  Dev build with warnings: <https://fb.me/react-15.0.0-rc.1.js>\
  Minified build for production: <https://fb.me/react-15.0.0-rc.1.min.js>
* **React with Add-Ons**\
  Dev build with warnings: <https://fb.me/react-with-addons-15.0.0-rc.1.js>\
  Minified build for production: <https://fb.me/react-with-addons-15.0.0-rc.1.min.js>
* **React DOM** (include React in the page before React DOM)\
  Dev build with warnings: <https://fb.me/react-dom-15.0.0-rc.1.js>\
  Minified build for production: <https://fb.me/react-dom-15.0.0-rc.1.min.js>

## [](#changelog)Changelog

### [](#major-changes)Major changes

* #### [](#documentcreateelement-is-in-and-data-reactid-is-out)`document.createElement` is in and `data-reactid` is out

  There were a number of large changes to our interactions with the DOM. One of the most noticeable changes is that we no longer set the `data-reactid` attribute for each DOM node. While this will make it much more difficult to know if a website is using React, the advantage is that the DOM is much more lightweight. This change was made possible by us switching to use `document.createElement` on initial render. Previously we would generate a large string of HTML and then set `node.innerHTML`. At the time, this was decided to be faster than using `document.createElement` for the majority of cases and browsers that we supported. Browsers have continued to improve and so overwhelmingly this is no longer true. By using `createElement` we can make other parts of React faster. The ids were used to map back from events to the original React component, meaning we had to do a bunch of work on every event, even though we cached this data heavily. As we’ve all experienced, caching and in particularly invalidating caches, can be error prone and we saw many hard to reproduce issues over the years as a result. Now we can build up a direct mapping at render time since we already have a handle on the node.

* #### [](#no-more-extra-spans)No more extra `<span>`s

  Another big change with our DOM interaction is how we render text blocks. Previously you may have noticed that React rendered a lot of extra `<span>`s. Eg, in our most basic example on the home page we render `<div>Hello {this.props.name}</div>`, resulting in markup that contained 2 `<span>`s. Now we’ll render plain text nodes interspersed with comment nodes that are used for demarcation. This gives us the same ability to update individual pieces of text, without creating extra nested nodes. Very few people have depended on the actual markup generated here so it’s likely you are not impacted. However if you were targeting these `<span>`s in your CSS, you will need to adjust accordingly. You can always render them explicitly in your components.

* #### [](#rendering-null-now-uses-comment-nodes)Rendering `null` now uses comment nodes

  We’ve also made use of these comment nodes to change what `null` renders to. Rendering to `null` was a feature we added in React v0.11 and was implemented by rendering `<noscript>` elements. By rendering to comment nodes now, there’s a chance some of your CSS will be targeting the wrong thing, specifically if you are making use of `:nth-child` selectors. This, along with the other changes mentioned above, have always been considered implementation details of how React targets the DOM. We believe they are safe changes to make without going through a release with warnings detailing the subtle differences as they are details that should not be depended upon. Additionally, we have seen that these changes have improved React performance for many typical applications.

* #### [](#improved-svg-support)Improved SVG support

  All SVG tags and attributes are now fully supported. (Uncommon SVG tags are not present on the `React.DOM` element helper, but JSX and `React.createElement` work on all tag names.) All SVG attributes match their original capitalization and hyphenation as defined in the specification (ex: `gradientTransform` must be camel-cased but `clip-path` should be hyphenated).

### [](#breaking-changes)Breaking changes

It’s worth calling out the DOM structure changes above again, in particular the change from `<span>`s. In the course of updating the Facebook codebase, we found a very small amount of code that was depending on the markup that React generated. Some of these cases were integration tests like WebDriver which were doing very specific XPath queries to target nodes. Others were simply tests using `ReactDOM.renderToStaticMarkup` and comparing markup. Again, there were a very small number of changes that had to be made, but we don’t want anybody to be blindsided. We encourage everybody to run their test suites when upgrading and consider alternative approaches when possible. One approach that will work for some cases is to explicitly use `<span>`s in your `render` method.

These deprecations were introduced in v0.14 with a warning and the APIs are now removed.

* Deprecated APIs removed from `React`, specifically `findDOMNode`, `render`, `renderToString`, `renderToStaticMarkup`, and `unmountComponentAtNode`.
* Deprecated APIs removed from `React.addons`, specifically `batchedUpdates` and `cloneWithProps`.
* Deprecated APIs removed from component instances, specifically `setProps`, `replaceProps`, and `getDOMNode`.

### [](#new-deprecations-introduced-with-a-warning)New deprecations, introduced with a warning

Each of these changes will continue to work as before with a new warning until the release of React 16 so you can upgrade your code gradually.

* `LinkedStateMixin` and `valueLink` are now deprecated due to very low popularity. If you need this, you can use a wrapper component that implements the same behavior: [react-linked-input](https://www.npmjs.com/package/react-linked-input).

### [](#new-helpful-warnings)New helpful warnings

* If you use a minified copy of the *development* build, React DOM kindly encourages you to use the faster production build instead.
* React DOM: When specifying a unit-less CSS value as a string, a future version will not add `px` automatically. This version now warns in this case (ex: writing `style={{width: '300'}}`. (Unitless *number* values like `width: 300` are unchanged.)
* Synthetic Events will now warn when setting and accessing properties (which will not get cleared appropriately), as well as warn on access after an event has been returned to the pool.
* Elements will now warn when attempting to read `ref` and `key` from the props.
* React DOM now attempts to warn for mistyped event handlers on DOM elements (ex: `onclick` which should be `onClick`)

### [](#notable-bug-fixes)Notable bug fixes

* Fixed multiple small memory leaks
* Input events are handled more reliably in IE 10 and IE 11; spurious events no longer fire when using a placeholder.
* React DOM now supports the `cite` and `profile` HTML attributes.
* React DOM now supports the `onAnimationStart`, `onAnimationEnd`, `onAnimationIteration`, `onTransitionEnd`, and `onInvalid` events. Support for `onLoad` has been added to `object` elements.
* `Object.is` is used in a number of places to compare values, which leads to fewer false positives, especially involving `NaN`. In particular, this affects the `shallowCompare` add-on.
* React DOM now defaults to using DOM attributes instead of properties, which fixes a few edge case bugs. Additionally the nullification of values (ex: `href={null}`) now results in the forceful removal, no longer trying to set to the default value used by browsers in the absence of a value.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2016-03-07-react-v15-rc1.md)

----
url: https://legacy.reactjs.org/blog/2016/09/28/our-first-50000-stars.html
----

September 28, 2016 by [Vjeux](https://twitter.com/vjeux)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

Just three and a half years ago we open sourced a little JavaScript library called React. The journey since that day has been incredibly exciting.

## [](#commemorative-t-shirt)Commemorative T-Shirt

In order to celebrate 50,000 GitHub stars, [Maggie Appleton](http://www.maggieappleton.com/) from [egghead.io](http://egghead.io/) has designed us a special T-shirt, which will be available for purchase from Teespring **only for a week** through Thursday, October 6. Maggie also wrote [a blog post](https://www.behance.net/gallery/43269677/Reacts-50000-Stars-Shirt) showing all the different concepts she came up with before settling on the final design.

[](https://teespring.com/react-50000-stars)

The T-shirts are super soft using American Apparel’s tri-blend fabric; we also have kids and toddler T-shirts and baby onesies available.

* [Adult T-shirts (straight-cut and fitted)](https://teespring.com/react-50000-stars)
* [Kids T-shirts](https://teespring.com/react-50000-stars-kids)
* [Toddler T-Shirts](https://teespring.com/react-50000-stars-toddler)
* [Baby Onesies](https://teespring.com/react-50000-stars-baby)

Proceeds from the shirts will be donated to [CODE2040](http://www.code2040.org/), a nonprofit that creates access, awareness, and opportunities in technology for underrepresented minorities with a specific focus on Black and Latinx talent.

## [](#archeology)Archeology

We’ve spent a lot of time trying to explain the concepts behind React and the problems it attempts to solve, but we haven’t talked much about how React evolved before being open sourced. This milestone seemed like as good a time as any to dig through the earliest commits and share some of the more important moments and fun facts.

The story begins in our ads org, where we were building incredibly sophisticated client side web apps using an internal MVC framework called [BoltJS](http://web.archive.org/web/20130608154901/http://shaneosullivan.github.io/boltjs/intro.html). Here’s a sample of what some Bolt code looked like:

```
var CarView = require('javelin/core').createClass({
  name: 'CarView',
  extend: require('container').Container,
  properties: {
    wheels: 4,
  },
  declare: function() {
    return {
      childViews: [
        { content: 'I have ' },
        { ref: 'wheelView' },
        { content: ' wheels' }
      ]
    };
  },
  setWheels: function(wheels) {
    this.findRef('wheelView').setContent(wheels);
  },
  getWheels: function() {
    return this.findRef('wheelView').getContent();
  },
});

var car = new CarView();
car.setWheels(3);
car.placeIn(document.body);
//<div>
//  <div>I have </div>
//  <div>3</div>
//  <div> wheels</div>
//</div>
```

Bolt introduced a number of APIs and features that would eventually make their way into React including `render`, `createClass`, and `refs`. Bolt introduced the concept of `refs` as a way to create references to nodes that can be used imperatively. This was relevant for legacy interoperability and incremental adoption, and while React would eventually strive to be a lot more functional, `refs` proved to be a very useful way to break out of the functional paradigm when the need arose.

But as our applications grew more and more sophisticated, our Bolt codebases got pretty complicated. Recognizing some of the framework’s shortcomings, [Jordan Walke](https://twitter.com/jordwalke) started experimenting with a side-project called [FaxJS](https://github.com/jordwalke/FaxJs). His goal was to solve many of the same problems as Bolt, but in a very different way. This is actually where most of React’s fundamentals were born, including props, state, re-evaluating large portions of the tree to “diff” the UI, server-side rendering, and a basic concept of components.

```
TestProject.PersonDisplayer = {
  structure : function() {
    return Div({
      classSet: { personDisplayerContainer: true },
      titleDiv: Div({
        classSet: { personNameTitle: true },
        content: this.props.name
      }),
      nestedAgeDiv: Div({
        content: 'Interests: ' + this.props.interests
      })
    });
  }
};
```

## [](#fbolt-is-born)FBolt is Born

Through his FaxJS experiment, Jordan became convinced that functional APIs — which discouraged mutation — offered a better, more scalable way to build user interfaces. He imported his library into Facebook’s codebase in March of 2012 and renamed it “FBolt”, signifying an extension of Bolt where components are written in a functional programming style. Or maybe “FBolt” was a nod to FaxJS – he didn’t tell us! ;)

The interoperability between FBolt and Bolt allowed us to experiment with replacing just one component at a time with more functional component APIs. We could test the waters of this new functional paradigm, without having to go all in. We started with the components that were clearly best expressed functionally and then we would later continue to push the boundaries of what we could express as functions.

Realizing that FBolt wouldn’t be a great name for the library when used on its own, Jordan Walke and [Tom Occhino](https://twitter.com/tomocchino) decided on a new name: “React.” After Tom sent out the diff to rename everything to React, Jordan commented:

> Jordan Walke: I might add for the sake of discussion, that many systems advertise some kind of reactivity, but they usually require that you set up some kind of point-to-point listeners and won’t work on structured data. This API reacts to any state or property changes, and works with data of any form (as deeply structured as the graph itself) so I think the name is fitting.

Most of Tom’s other commits at the time were on the first version of [GraphiQL](https://github.com/graphql/graphiql), a project which was recently open sourced.

## [](#adding-jsx)Adding JSX

Since about 2010 Facebook has been using an extension of PHP called [XHP](https://www.facebook.com/notes/facebook-engineering/xhp-a-new-way-to-write-php/294003943919/), which enables engineers to create UIs using XML literals right inside their PHP code. It was first introduced to help prevent XSS holes but ended up being an excellent way to structure applications with custom components.

```
final class :a:post extends :x:element {
  attribute :a;
  protected function render(): XHPRoot {
    $anchor = <a>{$this->getChildren()}</a>;
    $form = (
      <form
        method="post"
        action={$this->:href}
        target={$this->:target}
        class="postLink"
      >{$anchor}</form>
    );
    $this->transferAllAttributes($anchor);
    return $form;
  }
}
```

Before Jordan’s work had even made its way into the Facebook codebase, Adam Hupp implemented an XHP-like concept for JavaScript, written in Haskell. This system enabled you to write the following inside a JavaScript file:

```
function :example:hello(attrib, children) {
  return (
    <div class="special">
      <h1>Hello, World!</h1>
      {children}
    </div>
  );
}
```

It would compile the above into the following normal ES3-compatible JavaScript:

```
function jsx_example_hello(attrib, children) {
  return (
    S.create("div", {"class": "special"}, [
      S.create("h1", {}, ["Hello, World!"]),
      children
    ]
  );
}
```

In this prototype, `S.create` would immediately create and return a DOM node. Most of the conversations on this prototype revolved around the performance characteristics of `innerHTML` versus creating DOM nodes directly. At the time, it would have been less than ideal to push developers universally in the direction of creating DOM nodes directly since it did not perform as well, especially in Firefox and IE. Facebook’s then-CTO [Bret Taylor](https://twitter.com/btaylor) chimed in on the discussion at the time in favor of `innerHTML` over `document.createElement`:

> Bret Taylor: If you are not convinced about innerHTML, here is a small microbenchmark. It is about the same in Chrome. innerHTML is about 30% faster in the latest version of Firefox (much more in previous versions), and about 90% faster in IE8.

This work was eventually abandoned but was revived after React made its way into the codebase. Jordan sidelined the previous performance discussions by introducing the concept of a “Virtual DOM,” though its eventual name didn’t exist yet.

> Jordan Walke: For the first step, I propose that we do the easiest, yet most general transformation possible. My suggestion is to simply map xml expressions to function call expressions.
>
> * `<x></x>` becomes `x( )`
> * `<x height=12></x>` becomes `x( {height:12} )`
> * `<x> <y> </y> </x>` becomes `x({ childList: [y( )] })`
>
> At this point, JSX doesn’t need to know about React - it’s just a convenient way to write function calls. Coincidentally, React’s primary abstraction is the function. Okay maybe it’s not so coincidental ;)

Adam made a very insightful comment, which is now the default way we write lists in React with JSX.

> Adam Hupp: I think we should just treat arrays of elements as a frag. This is useful for constructs like:
>
> ```
> <ul>{foo.map(function(i) { return <li>{i.data}</li>; })}</ul>
> ```
>
> In this case the ul(..) will get a childList with a single child, which is itself a list.

React didn’t end up using Adam’s implementation directly. Instead, we created JSX by forking [js-xml-literal](https://github.com/laverdet/js-xml-literal), a side project by XHP creator Marcel Laverdet. JSX took its name from js-xml-literal, which Jordan modified to just be syntactic sugar for deeply nested function calls.

## [](#api-churn)API Churn

During the first year of React, internal adoption was growing quickly but there was quite a lot of churn in the component APIs and naming conventions:

* `project` was renamed to `declare` then to `structure` and finally to `render`.
* `Componentize` was renamed to `createComponent` and finally to `createClass`.

As the project was about to be open sourced, [Lee Byron](https://twitter.com/leeb) sat down with Jordan Walke, Tom Occhino and Sebastian Markbåge in order to refactor, reimplement, and rename one of React’s most beloved features – the lifecycle API. Lee [came up with a well-designed API](https://gist.github.com/vjeux/f2b015d230cc1ab18ed1df30550495ed) that is still in place today.

* Concepts

  * component - a ReactComponent instance
  * state - internal state to a component
  * props - external state to a component
  * markup - the stringy HTML-ish stuff components generate
  * DOM - the document and elements within the document

* Actions

  * mount - to put a component into a DOM
  * initialize - to prepare a component for rendering
  * update - a transition of state (and props) resulting a render.
  * render - a side-effect-free process to get the representation (markup) of a component.
  * validate - make assertions about something created and provided
  * destroy - opposite of initialize

* Operands

  * create - make a new thing
  * get - get an existing thing
  * set - merge into existing
  * replace - replace existing
  * receive - respond to new data
  * force - skip checks to do action

* Notifications

  * shouldObjectAction
  * objectWillAction
  * objectDidAction

## [](#instagram)Instagram

In 2012, Instagram got acquired by Facebook. [Pete Hunt](https://twitter.com/floydophone), who was working on Facebook photos and videos at the time, joined their newly formed web team. He wanted to build their website completely in React, which was in stark contrast with the incremental adoption model that had been used at Facebook.

To make this happen, React had to be decoupled from Facebook’s infrastructure, since Instagram didn’t use any of it. This project acted as a forcing function to do the work needed to open source React. In the process, Pete also discovered and promoted a little project called webpack. He also implemented the `renderToString` primitive which was needed to do server-side rendering.

As we started to prepare for the open source launch, [Maykel Loomans](https://twitter.com/miekd), a designer on Instagram, made a mock of what the website could look like. The header ended up defining the visual identity of React: its logo and the electric blue color!

[](../images/blog/react-50k-mock-full.jpg)

In its earliest days, React benefited tremendously from feedback, ideas, and technical contributions of early adopters and collaborators all over the company. While it might look like an overnight success in hindsight, the story of React is actually a great example of how new ideas often need to go through several rounds of refinement, iteration, and course correction over a long period of time before reaching their full potential.

React’s approach to building user interfaces with functional programming principles has changed the way we do things in just a few short years. It goes without saying, but React would be nothing without the amazing open source community that’s built up around it!

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2016-09-28-our-first-50000-stars.md)

----
url: https://legacy.reactjs.org/blog/2014/07/28/community-roundup-20.html
----

July 28, 2014 by [Lou Husson](https://twitter.com/loukan42)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

It’s an exciting time for React as there are now more commits from open source contributors than from Facebook engineers! Keep up the good work :)

## [](#atom-moves-to-react)Atom moves to React

[Atom, GitHub’s code editor, is now using React](http://blog.atom.io/2014/07/02/moving-atom-to-react.html) to build the editing experience. They made the move in order to improve performance. By default, React helped them eliminate unnecessary reflows, enabling them to focus on architecting the rendering pipeline in order to minimize repaints by using hardware acceleration. This is a testament to the fact that React’s architecture is perfect for high performant applications.

[](http://blog.atom.io/2014/07/02/moving-atom-to-react.html)

## [](#why-does-react-scale)Why Does React Scale?

At the last [JSConf.us](http://2014.jsconf.us/), Vjeux talked about the design decisions made in the API that allows it to scale to a large number of developers. If you don’t have 20 minutes, take a look at the [annotated slides](https://speakerdeck.com/vjeux/why-does-react-scale-jsconf-2014).

## [](#live-editing)Live Editing

One of the best features of React is that it provides the foundations to implement concepts that were otherwise extremely difficult, like server-side rendering, undo-redo, rendering to non-DOM environments like canvas… [Dan Abramov](https://twitter.com/dan_abramov) got hot code reloading working with webpack in order to [live edit a React project](https://gaearon.github.io/react-hot-loader/)!

## [](#reactintl-mixin-by-yahoo)ReactIntl Mixin by Yahoo

There are a couple of React-related projects that recently appeared on Yahoo’s GitHub, the first one being an [internationalization mixin](https://github.com/yahoo/react-intl). It’s great to see them getting excited about React and contributing back to the community.

```
var MyComponent = React.createClass({
  mixins: [ReactIntlMixin],
  render: function() {
    return (
      <div>
        <p>{this.intlDate(1390518044403, { hour: 'numeric', minute: 'numeric' })}</p>
        <p>{this.intlNumber(400, { style: 'percent' })}</p>
      </div>
    );
  }
});

React.renderComponent(
  <MyComponent locales={['fr-FR']} />,
  document.getElementById('example')
);
```

## [](#thinking-and-learning-react)Thinking and Learning React

Josephine Hall, working at Icelab, used React to write a mobile-focused application. She wrote a blog post [“Thinking and Learning React.js”](http://icelab.com.au/articles/thinking-and-learning-reactjs/) to share her experience with elements they had to use. You’ll learn about routing, event dispatch, touchable components, and basic animations.

## [](#london-react-meetup)London React Meetup

If you missed the last [London React Meetup](http://www.meetup.com/London-React-User-Group/events/191406572/), the video is available, with lots of great content.

* What’s new in React 0.11 and how to improve performance by guaranteeing immutability
* State handling in React with Morearty.JS
* React on Rails - How to use React with Ruby on Rails to build isomorphic apps
* Building an isomorphic, real-time to-do list with moped and node.js

In related news, the next [React SF Meetup](http://www.meetup.com/ReactJS-San-Francisco/events/195518392/) will be from Prezi: [“Immediate Mode on the Web: How We Implemented the Prezi Viewer in JavaScript”](https://medium.com/prezi-engineering/how-and-why-prezi-turned-to-javascript-56e0ca57d135). While not in React, their tech is really awesome and shares a lot of React’s design principles and perf optimizations.

## [](#using-react-and-kendoui-together)Using React and KendoUI Together

One of the strengths of React is that it plays nicely with other libraries. Jim Cowart proved it by writing a tutorial that explains how to write [React component adapters for KendoUI](http://www.ifandelse.com/using-reactjs-and-kendoui-together/).

[](http://www.ifandelse.com/using-reactjs-and-kendoui-together/)

## [](#acorn-jsx)Acorn JSX

Ingvar Stepanyan extended the Acorn JavaScript parser to support JSX. The result is a [JSX parser](https://github.com/RReverser/acorn-jsx) that’s 1.5–2.0x faster than the official JSX implementation. It is an experiment and is not meant to be used for serious things, but it’s always a good thing to get competition on performance!

## [](#reactscriptloader)ReactScriptLoader

Yariv Sadan created [ReactScriptLoader](https://github.com/yariv/ReactScriptLoader) to make it easier to write components that require an external script.

```
var Foo = React.createClass({
  mixins: [ReactScriptLoaderMixin],
  getScriptURL: function() {
    return 'http://d3js.org/d3.v3.min.js';
  },
  getInitialState: function() {
    return { scriptLoading: true, scriptLoadError: false };
  },
  onScriptLoaded: function() {
    this.setState({scriptLoading: false});
  },
  onScriptError: function() {
    this.setState({scriptLoading: false, scriptLoadError: true});
  },
  render: function() {
    var message =
      this.state.scriptLoading ? 'Loading script...' :
      this.state.scriptLoadError ? 'Loading failed' :
      'Loading succeeded';
    return <span>{message}</span>;
  }
});
```

## [](#random-tweet)Random Tweet

> “[@apphacker](https://twitter.com/apphacker): I take back the mean things I said about [@reactjs](https://twitter.com/reactjs) I actually like it.” Summarizing the life of ReactJS in a single tweet.
>
> — Jordan (@jordwalke) [July 20, 2014](https://twitter.com/jordwalke/statuses/490747339607265280)

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2014-07-28-community-roundup-20.md)

----
url: https://react.dev/reference/react/use
----

[API Reference](/reference/react)

[APIs](/reference/react/apis)

# use[](#undefined "Link for this heading")

`use` is a React API that lets you read the value of a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) or [context](/learn/passing-data-deeply-with-context).

```
const value = use(resource);
```

* [Reference](#reference)

  * [`use(context)`](#use-context)
  * [`use(promise)`](#use-promise)

* [Usage (Context)](#usage-context)

  * [Reading context with `use`](#reading-context-with-use)
  * [Reading a Promise from context](#reading-a-promise-from-context)

* [Usage (Promises)](#usage-promises)

  * [Reading a Promise with `use`](#reading-a-promise-with-use)
  * [Caching Promises for Client Components](#caching-promises-for-client-components)
  * [Re-fetching data in Client Components](#re-fetching-data-in-client-components)
  * [Preloading data on hover](#preloading-data-on-hover)
  * [Streaming data from server to client](#streaming-data-from-server-to-client)
  * [Displaying an error with an Error Boundary](#displaying-an-error-with-an-error-boundary)

* [Troubleshooting](#troubleshooting)

  * [I’m getting an error: “Suspense Exception: This is not a real error!”](#suspense-exception-error)
  * [I’m getting a warning: “A component was suspended by an uncached promise”](#uncached-promise-error)

***

## Reference[](#reference "Link for Reference ")

### `use(context)`[](#use-context "Link for this heading")

Call `use` with a [context](/learn/passing-data-deeply-with-context) to read its value. Unlike [`useContext`](/reference/react/useContext), `use` can be called within loops and conditional statements like `if`.

```
import { use } from 'react';



function Button() {

  const theme = use(ThemeContext);

  // ...
```

[See more examples below.](#usage-context)

#### Parameters[](#context-parameters "Link for Parameters ")

* `context`: A [context](/learn/passing-data-deeply-with-context) created with [`createContext`](/reference/react/createContext).

#### Returns[](#context-returns "Link for Returns ")

The context value for the passed context, determined by the closest context provider above the calling component. If there is no provider, the returned value is the `defaultValue` passed to [`createContext`](/reference/react/createContext).

#### Caveats[](#context-caveats "Link for Caveats ")

* `use` must be called inside a Component or a Hook.
* Reading context with `use` is not supported in [Server Components](/reference/rsc/server-components).

***

### `use(promise)`[](#use-promise "Link for this heading")

Call `use` with a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) to read its resolved value. The component calling `use` *suspends* while the Promise is pending. Despite its name, `use` is not a Hook. Unlike Hooks, it can be called inside loops and conditional statements like `if`.

```
import { use } from 'react';



function MessageComponent({ messagePromise }) {

  const message = use(messagePromise);

  // ...
```

If the component that calls `use` is wrapped in a [Suspense](/reference/react/Suspense) boundary, the fallback will be displayed while the Promise is pending. Once the Promise is resolved, the Suspense fallback is replaced by the rendered components using the data returned by `use`. If the Promise is rejected, the fallback of the nearest [Error Boundary](/reference/react/Component#catching-rendering-errors-with-an-error-boundary) will be displayed.

[See more examples below.](#usage-promises)

#### Parameters[](#promise-parameters "Link for Parameters ")

* `promise`: A [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) whose resolved value you want to read. The Promise must be [cached](#caching-promises-for-client-components) so that the same instance is reused across re-renders.

#### Returns[](#promise-returns "Link for Returns ")

The resolved value of the Promise.

#### Caveats[](#promise-caveats "Link for Caveats ")

* `use` must be called inside a Component or a Hook.
* `use` cannot be called inside a try-catch block. Instead, wrap your component in an [Error Boundary](#displaying-an-error-with-an-error-boundary) to catch the error and display a fallback.
* Promises passed to `use` must be cached so the same Promise instance is reused across re-renders. [See caching Promises below.](#caching-promises-for-client-components)
* When passing a Promise from a Server Component to a Client Component, its resolved value must be [serializable](/reference/rsc/use-client#serializable-types).

***

## Usage (Context)[](#usage-context "Link for Usage (Context) ")

### Reading context with `use`[](#reading-context-with-use "Link for this heading")

When a [context](/learn/passing-data-deeply-with-context) is passed to `use`, it works similarly to [`useContext`](/reference/react/useContext). While `useContext` must be called at the top level of your component, `use` can be called inside conditionals like `if` and loops like `for`.

```
import { use } from 'react';



function Button() {

  const theme = use(ThemeContext);

  // ...
```

`use` returns the context value for the context you passed. To determine the context value, React searches the component tree and finds **the closest context provider above** for that particular context.

To pass context to a `Button`, wrap it or one of its parent components into the corresponding context provider.

```
function MyPage() {

  return (

    <ThemeContext value="dark">

      <Form />

    </ThemeContext>

  );

}



function Form() {

  // ... renders buttons inside ...

}
```

It doesn’t matter how many layers of components there are between the provider and the `Button`. When a `Button` *anywhere* inside of `Form` calls `use(ThemeContext)`, it will receive `"dark"` as the value.

Unlike [`useContext`](/reference/react/useContext), `use` can be called in conditionals and loops like `if`.

```
function HorizontalRule({ show }) {

  if (show) {

    const theme = use(ThemeContext);

    return <hr className={theme} />;

  }

  return false;

}
```

`use` is called from inside a `if` statement, allowing you to conditionally read values from a Context.

### Pitfall

Like `useContext`, `use(context)` always looks for the closest context provider *above* the component that calls it. It searches upwards and **does not** consider context providers in the component from which you’re calling `use(context)`.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { createContext, use } from 'react';

const ThemeContext = createContext(null);

export default function MyApp() {
  return (
    <ThemeContext value="dark">
      <Form />
    </ThemeContext>
  )
}

function Form() {
  return (
    <Panel title="Welcome">
      <Button show={true}>Sign up</Button>
      <Button show={false}>Log in</Button>
    </Panel>
  );
}

function Panel({ title, children }) {
  const theme = use(ThemeContext);
  const className = 'panel-' + theme;
  return (
    <section className={className}>
      <h1>{title}</h1>
      {children}
    </section>
  )
}

function Button({ show, children }) {
  if (show) {
    const theme = use(ThemeContext);
    const className = 'button-' + theme;
    return (
      <button className={className}>
        {children}
      </button>
    );
  }
  return false
}
```

### Reading a Promise from context[](#reading-a-promise-from-context "Link for Reading a Promise from context ")

To share asynchronous data without prop drilling, set a Promise as a context value, then read it with `use(context)` and resolve it with `use(promise)`:

```
import { use } from 'react';

import { UserContext } from './UserContext';



function Profile() {

  const userPromise = use(UserContext);

  const user = use(userPromise);

  return <h1>{user.name}</h1>;

}
```

Reading the value requires two `use` calls because the context value itself isn’t awaited. See [Before you use context](/learn/passing-data-deeply-with-context#before-you-use-context) for alternatives to consider before reaching for context.

Wrap the components that read the Promise in a [Suspense](/reference/react/Suspense) boundary so only that subtree suspends while the Promise is pending. See [Usage (Promises)](#usage-promises) below for more on reading Promises with `use`.

### Pitfall

When this pattern is used with [Server Components](/reference/rsc/server-components), refetching the Promise requires refetching the Server Component that sets the Promise in context. Avoid setting the Promise in context high in the tree, since that would refetch large parts of the app unnecessarily.

***

## Usage (Promises)[](#usage-promises "Link for Usage (Promises) ")

### Reading a Promise with `use`[](#reading-a-promise-with-use "Link for this heading")

Call `use` with a Promise to read its resolved value. The component will [suspend](/reference/react/Suspense) while the Promise is pending.

```
import { use } from 'react';



function Albums({ albumsPromise }) {

  const albums = use(albumsPromise);

  return (

    <ul>

      {albums.map(album => (

        <li key={album.id}>

          {album.title} ({album.year})

        </li>

      ))}

    </ul>

  );

}
```

Wrap the component that calls `use` in a [Suspense](/reference/react/Suspense) boundary so React can show a fallback while the Promise is pending. The closest Suspense boundary above the suspending component shows its fallback. Once the Promise resolves, React reads the value with `use` and replaces the fallback with the rendered component.

#### Reading a Promise with use vs fetching in an Effect[](#examples-promise "Link for Reading a Promise with use vs fetching in an Effect")

#### Example 1 of 2:Fetching data with `use`[](#fetching-data-with-use "Link for this heading")

In this example, `Albums` calls `use` with a cached Promise. The component suspends while the Promise is pending, and React displays the nearest Suspense fallback. Rejected Promises propagate to the nearest [Error Boundary](/reference/react/Component#catching-rendering-errors-with-an-error-boundary).

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { use, Suspense } from 'react';
import { ErrorBoundary } from 'react-error-boundary';
import { fetchData } from './data.js';

export default function App() {
  return (
    <ErrorBoundary fallback={<p>Could not fetch albums.</p>}>
      <Suspense fallback={<Loading />}>
        <Albums />
      </Suspense>
    </ErrorBoundary>
  );
}

function Albums() {
  const albums = use(fetchData('/albums'));
  return (
    <ul>
      {albums.map(album => (
        <li key={album.id}>
          {album.title} ({album.year})
        </li>
      ))}
    </ul>
  );
}

function Loading() {
  return <h2>Loading...</h2>;
}
```

### Pitfall

##### Promises passed to `use` must be cached[](#promises-must-cached "Link for this heading")

Promises created during render are recreated on every render, which causes React to show the Suspense fallback repeatedly and prevents content from appearing.

```
function Albums() {

  // 🔴 `fetch` creates a new Promise on every render.

  const albums = use(fetch('/albums'));

  // ...

}
```

Instead, pass a Promise from a cache, a Suspense-enabled framework, or a Server Component:

```
// ✅ fetchData reads the Promise from a cache.

const albums = use(fetchData('/albums'));
```

##### Deep Dive#### Why are Promises recreated on every render?[](#why-promises-recreated "Link for Why are Promises recreated on every render? ")

[React doesn’t preserve state for renders that suspended before mounting](/reference/react/Suspense#caveats). After each suspension, React retries rendering from scratch, so any Promise created during render is recreated.

Common ways a Promise can be unintentionally recreated during render:

```
function Albums() {

  // 🔴 `fetch` creates a new Promise on every render.

  const albums = use(fetch('/albums'));



  // 🔴 Uncached `async` function calls create a new Promise on every render.

  const albums = use((async () => {

    const res = await fetch('/albums');

    return res.json();

  })());



  // 🔴 Adding `.then` returns a new Promise on every render,

  // even if `fetchData` is cached.

  const albums = use(fetchData('/albums').then(res => res.json()));

  // ...

}
```

Ideally, Promises are created before rendering, such as in an event handler, a route loader, or a Server Component, and passed to the component that calls `use`. Fetching lazily in render delays network requests and can create waterfalls.

```
// ✅ fetchData reads the Promise from a cache.

const albums = use(fetchData('/albums'));
```

***

### Caching Promises for Client Components[](#caching-promises-for-client-components "Link for Caching Promises for Client Components ")

Promises passed to `use` in Client Components must be cached so the same Promise instance is reused across re-renders. If a new Promise is created directly in render, React will display the Suspense fallback on every re-render.

```
// ✅ Cache the Promise so the same one is reused across renders

let cache = new Map();



export function fetchData(url) {

  if (!cache.has(url)) {

    cache.set(url, getData(url));

  }

  return cache.get(url);

}
```

The `fetchData` function returns the same Promise each time it’s called with the same URL. When `use` receives the same Promise on a re-render, it reads the already-resolved value synchronously without suspending.

### Note

The way you cache Promises depends on the framework you use with Suspense. Frameworks typically provide built-in caching mechanisms. If you don’t use a framework, you can use a simple module-level cache like the one above, or a [Suspense-enabled data source](/reference/react/Suspense#displaying-a-fallback-while-content-is-loading).

In the example below, clicking “Re-render” updates state in `App` and triggers a re-render. Because `fetchData` returns the same cached Promise, `Albums` reads the value synchronously instead of showing the Suspense fallback again.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { use, Suspense, useState } from 'react';
import { fetchData } from './data.js';

export default function App() {
  const [count, setCount] = useState(0);
  return (
    <>
      <button onClick={() => setCount(count + 1)}>
        Re-render
      </button>
      <p>Render count: {count}</p>
      <Suspense fallback={<p>Loading...</p>}>
        <Albums />
      </Suspense>
    </>
  );
}

function Albums() {
  const albums = use(fetchData('/albums'));
  return (
    <ul>
      {albums.map(album => (
        <li key={album.id}>
          {album.title} ({album.year})
        </li>
      ))}
    </ul>
  );
}
```

##### Deep Dive#### How to implement a promise cache[](#how-to-implement-a-promise-cache "Link for How to implement a promise cache ")

A basic cache stores the Promise keyed by URL so the same instance is reused across renders. To also avoid unnecessary Suspense fallbacks when data is already available, you can set `status` and `value` (or `reason`) fields on the Promise. React checks these fields when `use` is called: if `status` is `'fulfilled'`, it reads `value` synchronously without suspending. If `status` is `'rejected'`, it throws `reason`. If the field is missing or `'pending'`, it suspends.

```
let cache = new Map();



function fetchData(url) {

  if (!cache.has(url)) {

    const promise = getData(url);

    promise.status = 'pending';

    promise.then(

      value => {

        promise.status = 'fulfilled';

        promise.value = value;

      },

      reason => {

        promise.status = 'rejected';

        promise.reason = reason;

      },

    );

    cache.set(url, promise);

  }

  return cache.get(url);

}
```

This is primarily useful for library authors building Suspense-compatible data layers. React will set the `status` field itself on Promises that don’t have it, but setting it yourself avoids an extra render when the data is already available.

This cache pattern is the foundation for [re-fetching data](#re-fetching-data-in-client-components) (where changing the cache key triggers a new fetch) and [preloading data on hover](#preloading-data-on-hover) (where calling `fetchData` early means the Promise may already be resolved by the time `use` reads it).

### Pitfall

Don’t skip calling `use` based on whether a Promise is already settled.

Unlike other hooks, `use` can be called inside conditions and loops — but it must always be called for the Promise itself. Never read `promise.status` or `promise.value` directly to bypass `use`; always pass the Promise to `use` and let React handle it.

```
// 🔴 Don't bypass `use` by reading promise status directly

if (promise.status === 'fulfilled') {

  return promise.value;

}

const value = use(promise);
```

```
// ✅ Pass the promise to `use` and let React track the promise

const value = use(promise);
```

Bypassing `use` this way can break React Suspense optimizations and Suspense features for React DevTools. You can `use(promise)` conditionally, but don’t conditionally `use(promise)` based on the promise itself.

***

### Re-fetching data in Client Components[](#re-fetching-data-in-client-components "Link for Re-fetching data in Client Components ")

To refresh data at the same URL (for example, with a “Refresh” button), invalidate the cache entry and start a new fetch inside a [`startTransition`](/reference/react/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.

```
function App() {

  const [albumsPromise, setAlbumsPromise] = useState(fetchData('/albums'));

  const [isPending, startTransition] = useTransition();



  function handleRefresh() {

    startTransition(() => {

      setAlbumsPromise(refetchData('/albums'));

    });

  }

  // ...

}
```

`refetchData` clears the old cache entry and starts a new fetch at the same URL. Storing the resulting Promise in state triggers a re-render inside the Transition. On re-render, `Albums` receives the new Promise and `use` suspends on it while React keeps showing the old content.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { Suspense, useState, useTransition } from 'react';
import { use } from 'react';
import { fetchData, refetchData } from './data.js';

export default function App() {
  const [albumsPromise, setAlbumsPromise] = useState(
    () => fetchData('/the-beatles/albums')
  );
  const [isPending, startTransition] = useTransition();

  function handleRefresh() {
    startTransition(() => {
      setAlbumsPromise(refetchData('/the-beatles/albums'));
    });
  }

  return (
    <>
      <button
        onClick={handleRefresh}
        disabled={isPending}
      >
        {isPending ? 'Refreshing...' : 'Refresh'}
      </button>
      <div style={{ opacity: isPending ? 0.6 : 1 }}>
        <Suspense fallback={<Loading />}>
          <Albums albumsPromise={albumsPromise} />
        </Suspense>
      </div>
    </>
  );
}

function Albums({ albumsPromise }) {
  const albums = use(albumsPromise);
  return (
    <ul>
      {albums.map(album => (
        <li key={album.id}>
          {album.title} ({album.year})
        </li>
      ))}
    </ul>
  );
}

function Loading() {
  return <h2>Loading...</h2>;
}
```

### Note

Frameworks that support Suspense typically provide their own caching and invalidation mechanisms. The custom cache above is useful for understanding the pattern, but in practice prefer your framework’s data fetching solution.

***

### Preloading data on hover[](#preloading-data-on-hover "Link for Preloading data on hover ")

You can start loading data before it’s 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.

```
<button

  onMouseEnter={() => fetchData(`/${id}/albums`)}

  onClick={() => {

    startTransition(() => {

      setArtistId(id);

    });

  }}

>
```

In this example, hovering over an artist button starts fetching their albums in the background. Without hovering first, clicking shows a loading fallback. Try hovering over a button for a moment before clicking to see the difference.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { Suspense, useState, useTransition } from 'react';
import Albums from './Albums.js';
import { fetchData } from './data.js';

export default function App() {
  const [artistId, setArtistId] = useState('the-beatles');
  const [isPending, startTransition] = useTransition();

  return (
    <>
      <div>
        {['the-beatles', 'led-zeppelin', 'pink-floyd'].map(id => (
          <button
            key={id}
            onMouseEnter={() => {
              fetchData(`/${id}/albums`);
            }}
            onClick={() => {
              startTransition(() => {
                setArtistId(id);
              });
            }}
          >
            {id === 'the-beatles' ? 'The Beatles' :
             id === 'led-zeppelin' ? 'Led Zeppelin' :
             'Pink Floyd'}
          </button>
        ))}
      </div>
      <Suspense key={artistId} fallback={<Loading />}>
        <Albums artistId={artistId} />
      </Suspense>
    </>
  );
}

function Loading() {
  return <h2>Loading...</h2>;
}
```

***

### Streaming data from server to client[](#streaming-data-from-server-to-client "Link for Streaming data from server to client ")

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.

```
import { fetchMessage } from './lib.js';

import { Message } from './message.js';



export default function App() {

  const messagePromise = fetchMessage();

  return (

    <Suspense fallback={<p>waiting for message...</p>}>

      <Message messagePromise={messagePromise} />

    </Suspense>

  );

}
```

The Client Component then takes the Promise it received as a prop and passes it to the `use` API. This allows the Client Component to read the value from the Promise that was initially created by the Server Component.

```
// message.js

'use client';



import { use } from 'react';



export function Message({ messagePromise }) {

  const messageContent = use(messagePromise);

  return <p>Here is the message: {messageContent}</p>;

}
```

Because `Message` is wrapped in a [Suspense](/reference/react/Suspense) boundary, the fallback will be displayed until the Promise is resolved. When the Promise is resolved, the value will be read by the `use` API and the `Message` component will replace the Suspense fallback.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
"use client";

import { use, Suspense } from "react";

function Message({ messagePromise }) {
  const messageContent = use(messagePromise);
  return <p>Here is the message: {messageContent}</p>;
}

export function MessageContainer({ messagePromise }) {
  return (
    <Suspense fallback={<p>⌛Downloading message...</p>}>
      <Message messagePromise={messagePromise} />
    </Suspense>
  );
}
```

##### Deep Dive#### Should I resolve a Promise in a Server or Client Component?[](#resolve-promise-in-server-or-client-component "Link for Should I resolve a Promise in a Server or Client Component? ")

A Promise can be resolved with `await` in a Server Component, or passed as a prop to a Client Component and resolved there with `use`.

Using `await` in a Server Component suspends the Server Component itself, and the Client Component receives the resolved value as a prop:

```
// Server Component

export default async function App() {

  // Will suspend the Server Component.

  const messageContent = await fetchMessage();

  return <Message messageContent={messageContent} />;

}
```

A Server Component can also start a Promise without awaiting it and pass the Promise to a Client Component. The Server Component returns immediately, and the Client Component suspends when it calls `use`:

```
// Server Component

export default function App() {

  // Not awaited: starts here, resolves on the client.

  const messagePromise = fetchMessage();

  return <Message messagePromise={messagePromise} />;

}
```

```
// Client Component

'use client';

import { use } from 'react';



export function Message({ messagePromise }) {

  // Will suspend until the data is available.

  const messageContent = use(messagePromise);

  return <p>{messageContent}</p>;

}
```

Prefer `await` in a Server Component when possible, since it keeps the data fetching on the server. If a Server Component above already awaits the data, pass the resolved value down as a prop instead of creating a new Promise to call `use`.

You can also pass promise as a prop to a Client Component without awaiting it, and then read it with `use(promise)` to suspend deeper in the tree. This allows more of the surrounding UI to complete while the Promise is pending. A common case is interactive content like popovers and tooltips, where the data is needed only after a hover or click. Client Components can’t `await`, so they rely on `use` to suspend on a Promise.

In either case, wrap the component that reads the Promise in a Suspense boundary so React can show a fallback while the Promise is pending. See [Revealing content together at once](/reference/react/Suspense#revealing-content-together-at-once) for guidance on boundary placement.

***

### Displaying an error with an Error Boundary[](#displaying-an-error-with-an-error-boundary "Link for Displaying an error with an Error Boundary ")

If the Promise passed to `use` is rejected, the error propagates to the nearest [Error Boundary](/reference/react/Component#catching-rendering-errors-with-an-error-boundary). Wrap the component that calls `use` in an Error Boundary to display a fallback when the Promise is rejected.

In the example below, `fetchData` rejects on the first attempt and succeeds on retry. The Error Boundary catches the rejection and shows a fallback with a “Try again” button.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { use, Suspense, useState, startTransition } from "react";
import { ErrorBoundary } from "react-error-boundary";
import { fetchData, refetchData } from "./data.js";

export default function App() {
  const [albumsPromise, setAlbumsPromise] = useState(
    () => fetchData('/the-beatles/albums')
  );

  function handleRetry() {
    startTransition(() => {
      setAlbumsPromise(refetchData('/the-beatles/albums'));
    });
  }

  return (
    <ErrorBoundary
      resetKeys={[albumsPromise]}
      fallbackRender={() => (
        <>
          <p>⚠️ Something went wrong loading the albums.</p>
          <button onClick={handleRetry}>Try again</button>
        </>
      )}
    >
      <Suspense fallback={<p>Loading...</p>}>
        <Albums albumsPromise={albumsPromise} />
      </Suspense>
    </ErrorBoundary>
  );
}

function Albums({ albumsPromise }) {
  const albums = use(albumsPromise);
  return (
    <ul>
      {albums.map(album => (
        <li key={album.id}>
          {album.title} ({album.year})
        </li>
      ))}
    </ul>
  );
}
```

***

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### I’m getting an error: “Suspense Exception: This is not a real error!”[](#suspense-exception-error "Link for I’m getting an error: “Suspense Exception: This is not a real error!” ")

You are calling `use` inside a try-catch block. `use` throws internally to integrate with Suspense, so it cannot be wrapped in try-catch. Instead, wrap the component that calls `use` in an [Error Boundary](#displaying-an-error-with-an-error-boundary) to handle errors.

```
function Albums({ albumsPromise }) {

  try {

    // ❌ Don't wrap `use` in try-catch

    const albums = use(albumsPromise);

  } catch (e) {

    return <p>Error</p>;

  }

  // ...
```

Instead, wrap the component in an Error Boundary:

```
function Albums({ albumsPromise }) {

  // ✅ Call `use` without try-catch

  const albums = use(albumsPromise);

  // ...
```

```
// ✅ Use an Error Boundary to handle errors

<ErrorBoundary fallback={<p>Error</p>}>

  <Albums albumsPromise={albumsPromise} />

</ErrorBoundary>
```

***

### I’m getting a warning: “A component was suspended by an uncached promise”[](#uncached-promise-error "Link for I’m getting a warning: “A component was suspended by an uncached promise” ")

The Promise passed to `use` is not cached, so React cannot reuse it across re-renders.

This commonly happens when calling `fetch` or an `async` function directly in render:

```
function Albums() {

  // 🔴 This creates a new Promise on every render

  const albums = use(fetch('/albums'));

  // ...

}
```

To fix this, cache the Promise so the same instance is reused:

```
// ✅ fetchData returns the same Promise for the same URL

const albums = use(fetchData('/albums'));
```

See [caching Promises for Client Components](#caching-promises-for-client-components) for more details.

[PreviousstartTransition](/reference/react/startTransition)

[Nextexperimental\_taintObjectReference](/reference/react/experimental_taintObjectReference)

***

----
url: https://react.dev/learn/tutorial-tic-tac-toe
----

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

function Square({ value, onSquareClick }) {
  return (
    <button className="square" onClick={onSquareClick}>
      {value}
    </button>
  );
}

function Board({ xIsNext, squares, onPlay }) {
  function handleClick(i) {
    if (calculateWinner(squares) || squares[i]) {
      return;
    }
    const nextSquares = squares.slice();
    if (xIsNext) {
      nextSquares[i] = 'X';
    } else {
      nextSquares[i] = 'O';
    }
    onPlay(nextSquares);
  }

  const winner = calculateWinner(squares);
  let status;
  if (winner) {
    status = 'Winner: ' + winner;
  } else {
    status = 'Next player: ' + (xIsNext ? 'X' : 'O');
  }

  return (
    <>
      <div className="status">{status}</div>
      <div className="board-row">
        <Square value={squares[0]} onSquareClick={() => handleClick(0)} />
        <Square value={squares[1]} onSquareClick={() => handleClick(1)} />
        <Square value={squares[2]} onSquareClick={() => handleClick(2)} />
      </div>
      <div className="board-row">
        <Square value={squares[3]} onSquareClick={() => handleClick(3)} />
        <Square value={squares[4]} onSquareClick={() => handleClick(4)} />
        <Square value={squares[5]} onSquareClick={() => handleClick(5)} />
      </div>
      <div className="board-row">
        <Square value={squares[6]} onSquareClick={() => handleClick(6)} />
        <Square value={squares[7]} onSquareClick={() => handleClick(7)} />
        <Square value={squares[8]} onSquareClick={() => handleClick(8)} />
      </div>
    </>
  );
}

export default function Game() {
  const [history, setHistory] = useState([Array(9).fill(null)]);
  const [currentMove, setCurrentMove] = useState(0);
  const xIsNext = currentMove % 2 === 0;
  const currentSquares = history[currentMove];

  function handlePlay(nextSquares) {
    const nextHistory = [...history.slice(0, currentMove + 1), nextSquares];
    setHistory(nextHistory);
    setCurrentMove(nextHistory.length - 1);
  }

  function jumpTo(nextMove) {
    setCurrentMove(nextMove);
  }

  const moves = history.map((squares, move) => {
    let description;
    if (move > 0) {
      description = 'Go to move #' + move;
    } else {
      description = 'Go to game start';
    }
    return (
      <li key={move}>
        <button onClick={() => jumpTo(move)}>{description}</button>
      </li>
    );
  });

  return (
    <div className="game">
      <div className="game-board">
        <Board xIsNext={xIsNext} squares={currentSquares} onPlay={handlePlay} />
      </div>
      <div className="game-info">
        <ol>{moves}</ol>
      </div>
    </div>
  );
}

function calculateWinner(squares) {
  const lines = [
    [0, 1, 2],
    [3, 4, 5],
    [6, 7, 8],
    [0, 3, 6],
    [1, 4, 7],
    [2, 5, 8],
    [0, 4, 8],
    [2, 4, 6],
  ];
  for (let i = 0; i < lines.length; i++) {
    const [a, b, c] = lines[i];
    if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
      return squares[a];
    }
  }
  return null;
}
```

If the code doesn’t make sense to you yet, or if you are unfamiliar with the code’s syntax, don’t worry! The goal of this tutorial is to help you understand React and its syntax.

We recommend that you check out the tic-tac-toe game above before continuing with the tutorial. One of the features that you’ll notice is that there is a numbered list to the right of the game’s board. This list gives you a history of all of the moves that have occurred in the game, and it is updated as the game progresses.

Once you’ve played around with the finished tic-tac-toe game, keep scrolling. You’ll start with a simpler template in this tutorial. Our next step is to set you up so that you can start building the game.

## Setup for the tutorial[](#setup-for-the-tutorial "Link for Setup for the tutorial ")

In the live code editor below, click **Fork** in the top-right corner to open the editor in a new tab using the website CodeSandbox. CodeSandbox lets you write code in your browser and preview how your users will see the app you’ve created. The new tab should display an empty square and the starter code for this tutorial.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
export default function Square() {
  return <button className="square">X</button>;
}
```

1. The *Files* section with a list of files like `App.js`, `index.js`, `styles.css` in `src` folder and a folder called `public`
2. The *code editor* where you’ll see the source code of your selected file
3. The *browser* section where you’ll see how the code you’ve written will be displayed

The `App.js` file should be selected in the *Files* section. The contents of that file in the *code editor* should be:

```
export default function Square() {

  return <button className="square">X</button>;

}
```

The *browser* section should be displaying a square with an X in it like this:

Now let’s have a look at the files in the starter code.

#### `App.js`[](#appjs "Link for this heading")

The code in `App.js` creates a *component*. In React, a component is a piece of reusable code that represents a part of a user interface. Components are used to render, manage, and update the UI elements in your application. Let’s look at the component line by line to see what’s going on:

```
export default function Square() {

  return <button className="square">X</button>;

}
```

The first line defines a function called `Square`. The `export` JavaScript keyword makes this function accessible outside of this file. The `default` keyword tells other files using your code that it’s the main function in your file.

```
export default function Square() {

  return <button className="square">X</button>;

}
```

The second line returns a button. The `return` JavaScript keyword means whatever comes after is returned as a value to the caller of the function. `<button>` is a *JSX element*. A JSX element is a combination of JavaScript code and HTML tags that describes what you’d like to display. `className="square"` is a button property or *prop* that tells CSS how to style the button. `X` is the text displayed inside of the button and `</button>` closes the JSX element to indicate that any following content shouldn’t be placed inside the button.

#### `styles.css`[](#stylescss "Link for this heading")

Click on the file labeled `styles.css` in the *Files* section of CodeSandbox. This file defines the styles for your React app. The first two *CSS selectors* (`*` and `body`) define the style of large parts of your app while the `.square` selector defines the style of any component where the `className` property is set to `square`. In your code, that would match the button from your Square component in the `App.js` file.

#### `index.js`[](#indexjs "Link for this heading")

Click on the file labeled `index.js` in the *Files* section of CodeSandbox. You won’t be editing this file during the tutorial but it is the bridge between the component you created in the `App.js` file and the web browser.

```
import { StrictMode } from 'react';

import { createRoot } from 'react-dom/client';

import './styles.css';



import App from './App';
```

```
export default function Square() {

  return <button className="square">X</button><button className="square">X</button>;

}
```

You’ll get this error:

Console

/src/App.js: Adjacent JSX elements must be wrapped in an enclosing tag. Did you want a JSX Fragment `<>...</>`?

React components need to return a single JSX element and not multiple adjacent JSX elements like two buttons. To fix this you can use *Fragments* (`<>` and `</>`) to wrap multiple adjacent JSX elements like this:

```
export default function Square() {

  return (

    <>

      <button className="square">X</button>

      <button className="square">X</button>

    </>

  );

}
```

Now you should see:

Great! Now you just need to copy-paste a few times to add nine squares and…

Oh no! The squares are all in a single line, not in a grid like you need for our board. To fix this you’ll need to group your squares into rows with `div`s and add some CSS classes. While you’re at it, you’ll give each square a number to make sure you know where each square is displayed.

In the `App.js` file, update the `Square` component to look like this:

```
export default function Square() {

  return (

    <>

      <div className="board-row">

        <button className="square">1</button>

        <button className="square">2</button>

        <button className="square">3</button>

      </div>

      <div className="board-row">

        <button className="square">4</button>

        <button className="square">5</button>

        <button className="square">6</button>

      </div>

      <div className="board-row">

        <button className="square">7</button>

        <button className="square">8</button>

        <button className="square">9</button>

      </div>

    </>

  );

}
```

The CSS defined in `styles.css` styles the divs with the `className` of `board-row`. Now that you’ve grouped your components into rows with the styled `div`s you have your tic-tac-toe board:

But you now have a problem. Your component named `Square`, really isn’t a square anymore. Let’s fix that by changing the name to `Board`:

```
export default function Board() {

  //...

}
```

At this point your code should look something like this:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
export default function Board() {
  return (
    <>
      <div className="board-row">
        <button className="square">1</button>
        <button className="square">2</button>
        <button className="square">3</button>
      </div>
      <div className="board-row">
        <button className="square">4</button>
        <button className="square">5</button>
        <button className="square">6</button>
      </div>
      <div className="board-row">
        <button className="square">7</button>
        <button className="square">8</button>
        <button className="square">9</button>
      </div>
    </>
  );
}
```

### Note

Psssst… That’s a lot to type! It’s okay to copy and paste code from this page. However, if you’re up for a little challenge, we recommend only copying code that you’ve manually typed at least once yourself.

### Passing data through props[](#passing-data-through-props "Link for Passing data through props ")

Next, you’ll want to change the value of a square from empty to “X” when the user clicks on the square. With how you’ve built the board so far you would need to copy-paste the code that updates the square nine times (once for each square you have)! Instead of copy-pasting, React’s component architecture allows you to create a reusable component to avoid messy, duplicated code.

First, you are going to copy the line defining your first square (`<button className="square">1</button>`) from your `Board` component into a new `Square` component:

```
function Square() {

  return <button className="square">1</button>;

}



export default function Board() {

  // ...

}
```

Then you’ll update the Board component to render that `Square` component using JSX syntax:

```
// ...

export default function Board() {

  return (

    <>

      <div className="board-row">

        <Square />

        <Square />

        <Square />

      </div>

      <div className="board-row">

        <Square />

        <Square />

        <Square />

      </div>

      <div className="board-row">

        <Square />

        <Square />

        <Square />

      </div>

    </>

  );

}
```

Note how unlike the browser `div`s, your own components `Board` and `Square` must start with a capital letter.

Let’s take a look:

Oh no! You lost the numbered squares you had before. Now each square says “1”. To fix this, you will use *props* to pass the value each square should have from the parent component (`Board`) to its child (`Square`).

Update the `Square` component to read the `value` prop that you’ll pass from the `Board`:

```
function Square({ value }) {

  return <button className="square">1</button>;

}
```

`function Square({ value })` indicates the Square component can be passed a prop called `value`.

Now you want to display that `value` instead of `1` inside every square. Try doing it like this:

```
function Square({ value }) {

  return <button className="square">value</button>;

}
```

Oops, this is not what you wanted:

You wanted to render the JavaScript variable called `value` from your component, not the word “value”. To “escape into JavaScript” from JSX, you need curly braces. Add curly braces around `value` in JSX like so:

```
function Square({ value }) {

  return <button className="square">{value}</button>;

}
```

For now, you should see an empty board:

This is because the `Board` component hasn’t passed the `value` prop to each `Square` component it renders yet. To fix it you’ll add the `value` prop to each `Square` component rendered by the `Board` component:

```
export default function Board() {

  return (

    <>

      <div className="board-row">

        <Square value="1" />

        <Square value="2" />

        <Square value="3" />

      </div>

      <div className="board-row">

        <Square value="4" />

        <Square value="5" />

        <Square value="6" />

      </div>

      <div className="board-row">

        <Square value="7" />

        <Square value="8" />

        <Square value="9" />

      </div>

    </>

  );

}
```

Now you should see a grid of numbers again:

Your updated code should look like this:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
function Square({ value }) {
  return <button className="square">{value}</button>;
}

export default function Board() {
  return (
    <>
      <div className="board-row">
        <Square value="1" />
        <Square value="2" />
        <Square value="3" />
      </div>
      <div className="board-row">
        <Square value="4" />
        <Square value="5" />
        <Square value="6" />
      </div>
      <div className="board-row">
        <Square value="7" />
        <Square value="8" />
        <Square value="9" />
      </div>
    </>
  );
}
```

### Making an interactive component[](#making-an-interactive-component "Link for Making an interactive component ")

Let’s fill the `Square` component with an `X` when you click it. Declare a function called `handleClick` inside of the `Square`. Then, add `onClick` to the props of the button JSX element returned from the `Square`:

```
function Square({ value }) {

  function handleClick() {

    console.log('clicked!');

  }



  return (

    <button

      className="square"

      onClick={handleClick}

    >

      {value}

    </button>

  );

}
```

If you click on a square now, you should see a log saying `"clicked!"` in the *Console* tab at the bottom of the *Browser* section in CodeSandbox. Clicking the square more than once will log `"clicked!"` again. Repeated console logs with the same message will not create more lines in the console. Instead, you will see an incrementing counter next to your first `"clicked!"` log.

### Note

If you are following this tutorial using your local development environment, you need to open your browser’s Console. For example, if you use the Chrome browser, you can view the Console with the keyboard shortcut **Shift + Ctrl + J** (on Windows/Linux) or **Option + ⌘ + J** (on macOS).

As a next step, you want the Square component to “remember” that it got clicked, and fill it with an “X” mark. To “remember” things, components use *state*.

React provides a special function called `useState` that you can call from your component to let it “remember” things. Let’s store the current value of the `Square` in state, and change it when the `Square` is clicked.

Import `useState` at the top of the file. Remove the `value` prop from the `Square` component. Instead, add a new line at the start of the `Square` that calls `useState`. Have it return a state variable called `value`:

```
import { useState } from 'react';



function Square() {

  const [value, setValue] = useState(null);



  function handleClick() {

    //...
```

`value` stores the value and `setValue` is a function that can be used to change the value. The `null` passed to `useState` is used as the initial value for this state variable, so `value` here starts off equal to `null`.

Since the `Square` component no longer accepts props anymore, you’ll remove the `value` prop from all nine of the Square components created by the Board component:

```
// ...

export default function Board() {

  return (

    <>

      <div className="board-row">

        <Square />

        <Square />

        <Square />

      </div>

      <div className="board-row">

        <Square />

        <Square />

        <Square />

      </div>

      <div className="board-row">

        <Square />

        <Square />

        <Square />

      </div>

    </>

  );

}
```

Now you’ll change `Square` to display an “X” when clicked. Replace the `console.log("clicked!");` event handler with `setValue('X');`. Now your `Square` component looks like this:

```
function Square() {

  const [value, setValue] = useState(null);



  function handleClick() {

    setValue('X');

  }



  return (

    <button

      className="square"

      onClick={handleClick}

    >

      {value}

    </button>

  );

}
```

By calling this `set` function from an `onClick` handler, you’re telling React to re-render that `Square` whenever its `<button>` is clicked. After the update, the `Square`’s `value` will be `'X'`, so you’ll see the “X” on the game board. Click on any Square, and “X” should show up:

Each Square has its own state: the `value` stored in each Square is completely independent of the others. When you call a `set` function in a component, React automatically updates the child components inside too.

After you’ve made the above changes, your code will look like this:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

function Square() {
  const [value, setValue] = useState(null);

  function handleClick() {
    setValue('X');
  }

  return (
    <button
      className="square"
      onClick={handleClick}
    >
      {value}
    </button>
  );
}

export default function Board() {
  return (
    <>
      <div className="board-row">
        <Square />
        <Square />
        <Square />
      </div>
      <div className="board-row">
        <Square />
        <Square />
        <Square />
      </div>
      <div className="board-row">
        <Square />
        <Square />
        <Square />
      </div>
    </>
  );
}
```

```
// ...

export default function Board() {

  const [squares, setSquares] = useState(Array(9).fill(null));

  return (

    // ...

  );

}
```

`Array(9).fill(null)` creates an array with nine elements and sets each of them to `null`. The `useState()` call around it declares a `squares` state variable that’s initially set to that array. Each entry in the array corresponds to the value of a square. When you fill the board in later, the `squares` array will look like this:

```
['O', null, 'X', 'X', 'X', 'O', 'O', null, null]
```

Now your `Board` component needs to pass the `value` prop down to each `Square` that it renders:

```
export default function Board() {

  const [squares, setSquares] = useState(Array(9).fill(null));

  return (

    <>

      <div className="board-row">

        <Square value={squares[0]} />

        <Square value={squares[1]} />

        <Square value={squares[2]} />

      </div>

      <div className="board-row">

        <Square value={squares[3]} />

        <Square value={squares[4]} />

        <Square value={squares[5]} />

      </div>

      <div className="board-row">

        <Square value={squares[6]} />

        <Square value={squares[7]} />

        <Square value={squares[8]} />

      </div>

    </>

  );

}
```

Next, you’ll edit the `Square` component to receive the `value` prop from the Board component. This will require removing the Square component’s own stateful tracking of `value` and the button’s `onClick` prop:

```
function Square({value}) {

  return <button className="square">{value}</button>;

}
```

At this point you should see an empty tic-tac-toe board:

And your code should look like this:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

function Square({ value }) {
  return <button className="square">{value}</button>;
}

export default function Board() {
  const [squares, setSquares] = useState(Array(9).fill(null));
  return (
    <>
      <div className="board-row">
        <Square value={squares[0]} />
        <Square value={squares[1]} />
        <Square value={squares[2]} />
      </div>
      <div className="board-row">
        <Square value={squares[3]} />
        <Square value={squares[4]} />
        <Square value={squares[5]} />
      </div>
      <div className="board-row">
        <Square value={squares[6]} />
        <Square value={squares[7]} />
        <Square value={squares[8]} />
      </div>
    </>
  );
}
```

Each Square will now receive a `value` prop that will either be `'X'`, `'O'`, or `null` for empty squares.

Next, you need to change what happens when a `Square` is clicked. The `Board` component now maintains which squares are filled. You’ll need to create a way for the `Square` to update the `Board`’s state. Since state is private to a component that defines it, you cannot update the `Board`’s state directly from `Square`.

Instead, you’ll pass down a function from the `Board` component to the `Square` component, and you’ll have `Square` call that function when a square is clicked. You’ll start with the function that the `Square` component will call when it is clicked. You’ll call that function `onSquareClick`:

```
function Square({ value }) {

  return (

    <button className="square" onClick={onSquareClick}>

      {value}

    </button>

  );

}
```

Next, you’ll add the `onSquareClick` function to the `Square` component’s props:

```
function Square({ value, onSquareClick }) {

  return (

    <button className="square" onClick={onSquareClick}>

      {value}

    </button>

  );

}
```

Now you’ll connect the `onSquareClick` prop to a function in the `Board` component that you’ll name `handleClick`. To connect `onSquareClick` to `handleClick` you’ll pass a function to the `onSquareClick` prop of the first `Square` component:

```
export default function Board() {

  const [squares, setSquares] = useState(Array(9).fill(null));



  return (

    <>

      <div className="board-row">

        <Square value={squares[0]} onSquareClick={handleClick} />

        //...

  );

}
```

Lastly, you will define the `handleClick` function inside the Board component to update the `squares` array holding your board’s state:

```
export default function Board() {

  const [squares, setSquares] = useState(Array(9).fill(null));



  function handleClick() {

    const nextSquares = squares.slice();

    nextSquares[0] = "X";

    setSquares(nextSquares);

  }



  return (

    // ...

  )

}
```

The `handleClick` function creates a copy of the `squares` array (`nextSquares`) with the JavaScript `slice()` Array method. Then, `handleClick` updates the `nextSquares` array to add `X` to the first (`[0]` index) square.

Calling the `setSquares` function lets React know the state of the component has changed. This will trigger a re-render of the components that use the `squares` state (`Board`) as well as its child components (the `Square` components that make up the board).

### Note

JavaScript supports [closures](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures) which means an inner function (e.g. `handleClick`) has access to variables and functions defined in an outer function (e.g. `Board`). The `handleClick` function can read the `squares` state and call the `setSquares` method because they are both defined inside of the `Board` function.

Now you can add X’s to the board… but only to the upper left square. Your `handleClick` function is hardcoded to update the index for the upper left square (`0`). Let’s update `handleClick` to be able to update any square. Add an argument `i` to the `handleClick` function that takes the index of the square to update:

```
export default function Board() {

  const [squares, setSquares] = useState(Array(9).fill(null));



  function handleClick(i) {

    const nextSquares = squares.slice();

    nextSquares[i] = "X";

    setSquares(nextSquares);

  }



  return (

    // ...

  )

}
```

Next, you will need to pass that `i` to `handleClick`. You could try to set the `onSquareClick` prop of square to be `handleClick(0)` directly in the JSX like this, but it won’t work:

```
<Square value={squares[0]} onSquareClick={handleClick(0)} />
```

```
export default function Board() {

  // ...

  return (

    <>

      <div className="board-row">

        <Square value={squares[0]} onSquareClick={() => handleClick(0)} />

        // ...

  );

}
```

Notice the new `() =>` syntax. Here, `() => handleClick(0)` is an *arrow function,* which is a shorter way to define functions. When the square is clicked, the code after the `=>` “arrow” will run, calling `handleClick(0)`.

Now you need to update the other eight squares to call `handleClick` from the arrow functions you pass. Make sure that the argument for each call of the `handleClick` corresponds to the index of the correct square:

```
export default function Board() {

  // ...

  return (

    <>

      <div className="board-row">

        <Square value={squares[0]} onSquareClick={() => handleClick(0)} />

        <Square value={squares[1]} onSquareClick={() => handleClick(1)} />

        <Square value={squares[2]} onSquareClick={() => handleClick(2)} />

      </div>

      <div className="board-row">

        <Square value={squares[3]} onSquareClick={() => handleClick(3)} />

        <Square value={squares[4]} onSquareClick={() => handleClick(4)} />

        <Square value={squares[5]} onSquareClick={() => handleClick(5)} />

      </div>

      <div className="board-row">

        <Square value={squares[6]} onSquareClick={() => handleClick(6)} />

        <Square value={squares[7]} onSquareClick={() => handleClick(7)} />

        <Square value={squares[8]} onSquareClick={() => handleClick(8)} />

      </div>

    </>

  );

};
```

Now you can again add X’s to any square on the board by clicking on them:

But this time all the state management is handled by the `Board` component!

This is what your code should look like:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

function Square({ value, onSquareClick }) {
  return (
    <button className="square" onClick={onSquareClick}>
      {value}
    </button>
  );
}

export default function Board() {
  const [squares, setSquares] = useState(Array(9).fill(null));

  function handleClick(i) {
    const nextSquares = squares.slice();
    nextSquares[i] = 'X';
    setSquares(nextSquares);
  }

  return (
    <>
      <div className="board-row">
        <Square value={squares[0]} onSquareClick={() => handleClick(0)} />
        <Square value={squares[1]} onSquareClick={() => handleClick(1)} />
        <Square value={squares[2]} onSquareClick={() => handleClick(2)} />
      </div>
      <div className="board-row">
        <Square value={squares[3]} onSquareClick={() => handleClick(3)} />
        <Square value={squares[4]} onSquareClick={() => handleClick(4)} />
        <Square value={squares[5]} onSquareClick={() => handleClick(5)} />
      </div>
      <div className="board-row">
        <Square value={squares[6]} onSquareClick={() => handleClick(6)} />
        <Square value={squares[7]} onSquareClick={() => handleClick(7)} />
        <Square value={squares[8]} onSquareClick={() => handleClick(8)} />
      </div>
    </>
  );
}
```

Now that your state handling is in the `Board` component, the parent `Board` component passes props to the child `Square` components so that they can be displayed correctly. When clicking on a `Square`, the child `Square` component now asks the parent `Board` component to update the state of the board. When the `Board`’s state changes, both the `Board` component and every child `Square` re-renders automatically. Keeping the state of all squares in the `Board` component will allow it to determine the winner in the future.

Let’s recap what happens when a user clicks the top left square on your board to add an `X` to it:

1. Clicking on the upper left square runs the function that the `button` received as its `onClick` prop from the `Square`. The `Square` component received that function as its `onSquareClick` prop from the `Board`. The `Board` component defined that function directly in the JSX. It calls `handleClick` with an argument of `0`.
2. `handleClick` uses the argument (`0`) to update the first element of the `squares` array from `null` to `X`.
3. The `squares` state of the `Board` component was updated, so the `Board` and all of its children re-render. This causes the `value` prop of the `Square` component with index `0` to change from `null` to `X`.

In the end the user sees that the upper left square has changed from empty to having an `X` after clicking it.

### Note

The DOM `<button>` element’s `onClick` attribute has a special meaning to React because it is a built-in component. For custom components like Square, the naming is up to you. You could give any name to the `Square`’s `onSquareClick` prop or `Board`’s `handleClick` function, and the code would work the same. In React, it’s conventional to use `onSomething` names for props which represent events and `handleSomething` for the function definitions which handle those events.

### Why immutability is important[](#why-immutability-is-important "Link for Why immutability is important ")

Note how in `handleClick`, you call `.slice()` to create a copy of the `squares` array instead of modifying the existing array. To explain why, we need to discuss immutability and why immutability is important to learn.

There are generally two approaches to changing data. The first approach is to *mutate* the data by directly changing the data’s values. The second approach is to replace the data with a new copy which has the desired changes. Here is what it would look like if you mutated the `squares` array:

```
const squares = [null, null, null, null, null, null, null, null, null];

squares[0] = 'X';

// Now `squares` is ["X", null, null, null, null, null, null, null, null];
```

And here is what it would look like if you changed data without mutating the `squares` array:

```
const squares = [null, null, null, null, null, null, null, null, null];

const nextSquares = ['X', null, null, null, null, null, null, null, null];

// Now `squares` is unchanged, but `nextSquares` first element is 'X' rather than `null`
```

The result is the same but by not mutating (changing the underlying data) directly, you gain several benefits.

Immutability makes complex features much easier to implement. Later in this tutorial, you will implement a “time travel” feature that lets you review the game’s history and “jump back” to past moves. This functionality isn’t specific to games—an ability to undo and redo certain actions is a common requirement for apps. Avoiding direct data mutation lets you keep previous versions of the data intact, and reuse them later.

There is also another benefit of immutability. By default, all child components re-render automatically when the state of a parent component changes. This includes even the child components that weren’t affected by the change. Although re-rendering is not by itself noticeable to the user (you shouldn’t actively try to avoid it!), you might want to skip re-rendering a part of the tree that clearly wasn’t affected by it for performance reasons. Immutability makes it very cheap for components to compare whether their data has changed or not. You can learn more about how React chooses when to re-render a component in [the `memo` API reference](/reference/react/memo).

### Taking turns[](#taking-turns "Link for Taking turns ")

It’s now time to fix a major defect in this tic-tac-toe game: the “O”s cannot be marked on the board.

You’ll set the first move to be “X” by default. Let’s keep track of this by adding another piece of state to the Board component:

```
function Board() {

  const [xIsNext, setXIsNext] = useState(true);

  const [squares, setSquares] = useState(Array(9).fill(null));



  // ...

}
```

Each time a player moves, `xIsNext` (a boolean) will be flipped to determine which player goes next and the game’s state will be saved. You’ll update the `Board`’s `handleClick` function to flip the value of `xIsNext`:

```
export default function Board() {

  const [xIsNext, setXIsNext] = useState(true);

  const [squares, setSquares] = useState(Array(9).fill(null));



  function handleClick(i) {

    const nextSquares = squares.slice();

    if (xIsNext) {

      nextSquares[i] = "X";

    } else {

      nextSquares[i] = "O";

    }

    setSquares(nextSquares);

    setXIsNext(!xIsNext);

  }



  return (

    //...

  );

}
```

Now, as you click on different squares, they will alternate between `X` and `O`, as they should!

But wait, there’s a problem. Try clicking on the same square multiple times:

The `X` is overwritten by an `O`! While this would add a very interesting twist to the game, we’re going to stick to the original rules for now.

When you mark a square with an `X` or an `O` you aren’t first checking to see if the square already has an `X` or `O` value. You can fix this by *returning early*. You’ll check to see if the square already has an `X` or an `O`. If the square is already filled, you will `return` in the `handleClick` function early—before it tries to update the board state.

```
function handleClick(i) {

  if (squares[i]) {

    return;

  }

  const nextSquares = squares.slice();

  //...

}
```

Now you can only add `X`’s or `O`’s to empty squares! Here is what your code should look like at this point:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

function Square({value, onSquareClick}) {
  return (
    <button className="square" onClick={onSquareClick}>
      {value}
    </button>
  );
}

export default function Board() {
  const [xIsNext, setXIsNext] = useState(true);
  const [squares, setSquares] = useState(Array(9).fill(null));

  function handleClick(i) {
    if (squares[i]) {
      return;
    }
    const nextSquares = squares.slice();
    if (xIsNext) {
      nextSquares[i] = 'X';
    } else {
      nextSquares[i] = 'O';
    }
    setSquares(nextSquares);
    setXIsNext(!xIsNext);
  }

  return (
    <>
      <div className="board-row">
        <Square value={squares[0]} onSquareClick={() => handleClick(0)} />
        <Square value={squares[1]} onSquareClick={() => handleClick(1)} />
        <Square value={squares[2]} onSquareClick={() => handleClick(2)} />
      </div>
      <div className="board-row">
        <Square value={squares[3]} onSquareClick={() => handleClick(3)} />
        <Square value={squares[4]} onSquareClick={() => handleClick(4)} />
        <Square value={squares[5]} onSquareClick={() => handleClick(5)} />
      </div>
      <div className="board-row">
        <Square value={squares[6]} onSquareClick={() => handleClick(6)} />
        <Square value={squares[7]} onSquareClick={() => handleClick(7)} />
        <Square value={squares[8]} onSquareClick={() => handleClick(8)} />
      </div>
    </>
  );
}
```

### Declaring a winner[](#declaring-a-winner "Link for Declaring a winner ")

Now that the players can take turns, you’ll want to show when the game is won and there are no more turns to make. To do this you’ll add a helper function called `calculateWinner` that takes an array of 9 squares, checks for a winner and returns `'X'`, `'O'`, or `null` as appropriate. Don’t worry too much about the `calculateWinner` function; it’s not specific to React:

```
export default function Board() {

  //...

}



function calculateWinner(squares) {

  const lines = [

    [0, 1, 2],

    [3, 4, 5],

    [6, 7, 8],

    [0, 3, 6],

    [1, 4, 7],

    [2, 5, 8],

    [0, 4, 8],

    [2, 4, 6]

  ];

  for (let i = 0; i < lines.length; i++) {

    const [a, b, c] = lines[i];

    if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {

      return squares[a];

    }

  }

  return null;

}
```

### Note

It does not matter whether you define `calculateWinner` before or after the `Board`. Let’s put it at the end so that you don’t have to scroll past it every time you edit your components.

You will call `calculateWinner(squares)` in the `Board` component’s `handleClick` function to check if a player has won. You can perform this check at the same time you check if a user has clicked a square that already has an `X` or an `O`. We’d like to return early in both cases:

```
function handleClick(i) {

  if (squares[i] || calculateWinner(squares)) {

    return;

  }

  const nextSquares = squares.slice();

  //...

}
```

To let the players know when the game is over, you can display text such as “Winner: X” or “Winner: O”. To do that you’ll add a `status` section to the `Board` component. The status will display the winner if the game is over and if the game is ongoing you’ll display which player’s turn is next:

```
export default function Board() {

  // ...

  const winner = calculateWinner(squares);

  let status;

  if (winner) {

    status = "Winner: " + winner;

  } else {

    status = "Next player: " + (xIsNext ? "X" : "O");

  }



  return (

    <>

      <div className="status">{status}</div>

      <div className="board-row">

        // ...

  )

}
```

Congratulations! You now have a working tic-tac-toe game. And you’ve just learned the basics of React too. So *you* are the real winner here. Here is what the code should look like:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

function Square({value, onSquareClick}) {
  return (
    <button className="square" onClick={onSquareClick}>
      {value}
    </button>
  );
}

export default function Board() {
  const [xIsNext, setXIsNext] = useState(true);
  const [squares, setSquares] = useState(Array(9).fill(null));

  function handleClick(i) {
    if (calculateWinner(squares) || squares[i]) {
      return;
    }
    const nextSquares = squares.slice();
    if (xIsNext) {
      nextSquares[i] = 'X';
    } else {
      nextSquares[i] = 'O';
    }
    setSquares(nextSquares);
    setXIsNext(!xIsNext);
  }

  const winner = calculateWinner(squares);
  let status;
  if (winner) {
    status = 'Winner: ' + winner;
  } else {
    status = 'Next player: ' + (xIsNext ? 'X' : 'O');
  }

  return (
    <>
      <div className="status">{status}</div>
      <div className="board-row">
        <Square value={squares[0]} onSquareClick={() => handleClick(0)} />
        <Square value={squares[1]} onSquareClick={() => handleClick(1)} />
        <Square value={squares[2]} onSquareClick={() => handleClick(2)} />
      </div>
      <div className="board-row">
        <Square value={squares[3]} onSquareClick={() => handleClick(3)} />
        <Square value={squares[4]} onSquareClick={() => handleClick(4)} />
        <Square value={squares[5]} onSquareClick={() => handleClick(5)} />
      </div>
      <div className="board-row">
        <Square value={squares[6]} onSquareClick={() => handleClick(6)} />
        <Square value={squares[7]} onSquareClick={() => handleClick(7)} />
        <Square value={squares[8]} onSquareClick={() => handleClick(8)} />
      </div>
    </>
  );
}

function calculateWinner(squares) {
  const lines = [
    [0, 1, 2],
    [3, 4, 5],
    [6, 7, 8],
    [0, 3, 6],
    [1, 4, 7],
    [2, 5, 8],
    [0, 4, 8],
    [2, 4, 6],
  ];
  for (let i = 0; i < lines.length; i++) {
    const [a, b, c] = lines[i];
    if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
      return squares[a];
    }
  }
  return null;
}
```

## Adding time travel[](#adding-time-travel "Link for Adding time travel ")

As a final exercise, let’s make it possible to “go back in time” to the previous moves in the game.

### Storing a history of moves[](#storing-a-history-of-moves "Link for Storing a history of moves ")

If you mutated the `squares` array, implementing time travel would be very difficult.

However, you used `slice()` to create a new copy of the `squares` array after every move, and treated it as immutable. This will allow you to store every past version of the `squares` array, and navigate between the turns that have already happened.

You’ll store the past `squares` arrays in another array called `history`, which you’ll store as a new state variable. The `history` array represents all board states, from the first to the last move, and has a shape like this:

```
[

  // Before first move

  [null, null, null, null, null, null, null, null, null],

  // After first move

  [null, null, null, null, 'X', null, null, null, null],

  // After second move

  [null, null, null, null, 'X', null, null, null, 'O'],

  // ...

]
```

### Lifting state up, again[](#lifting-state-up-again "Link for Lifting state up, again ")

You will now write a new top-level component called `Game` to display a list of past moves. That’s where you will place the `history` state that contains the entire game history.

Placing the `history` state into the `Game` component will let you remove the `squares` state from its child `Board` component. Just like you “lifted state up” from the `Square` component into the `Board` component, you will now lift it up from the `Board` into the top-level `Game` component. This gives the `Game` component full control over the `Board`’s data and lets it instruct the `Board` to render previous turns from the `history`.

First, add a `Game` component with `export default`. Have it render the `Board` component and some markup:

```
function Board() {

  // ...

}



export default function Game() {

  return (

    <div className="game">

      <div className="game-board">

        <Board />

      </div>

      <div className="game-info">

        <ol>{/*TODO*/}</ol>

      </div>

    </div>

  );

}
```

Note that you are removing the `export default` keywords before the `function Board() {` declaration and adding them before the `function Game() {` declaration. This tells your `index.js` file to use the `Game` component as the top-level component instead of your `Board` component. The additional `div`s returned by the `Game` component are making room for the game information you’ll add to the board later.

Add some state to the `Game` component to track which player is next and the history of moves:

```
export default function Game() {

  const [xIsNext, setXIsNext] = useState(true);

  const [history, setHistory] = useState([Array(9).fill(null)]);

  // ...
```

Notice how `[Array(9).fill(null)]` is an array with a single item, which itself is an array of 9 `null`s.

To render the squares for the current move, you’ll want to read the last squares array from the `history`. You don’t need `useState` for this—you already have enough information to calculate it during rendering:

```
export default function Game() {

  const [xIsNext, setXIsNext] = useState(true);

  const [history, setHistory] = useState([Array(9).fill(null)]);

  const currentSquares = history[history.length - 1];

  // ...
```

Next, create a `handlePlay` function inside the `Game` component that will be called by the `Board` component to update the game. Pass `xIsNext`, `currentSquares` and `handlePlay` as props to the `Board` component:

```
export default function Game() {

  const [xIsNext, setXIsNext] = useState(true);

  const [history, setHistory] = useState([Array(9).fill(null)]);

  const currentSquares = history[history.length - 1];



  function handlePlay(nextSquares) {

    // TODO

  }



  return (

    <div className="game">

      <div className="game-board">

        <Board xIsNext={xIsNext} squares={currentSquares} onPlay={handlePlay} />

        //...

  )

}
```

Let’s make the `Board` component fully controlled by the props it receives. Change the `Board` component to take three props: `xIsNext`, `squares`, and a new `onPlay` function that `Board` can call with the updated squares array when a player makes a move. Next, remove the first two lines of the `Board` function that call `useState`:

```
function Board({ xIsNext, squares, onPlay }) {

  function handleClick(i) {

    //...

  }

  // ...

}
```

Now replace the `setSquares` and `setXIsNext` calls in `handleClick` in the `Board` component with a single call to your new `onPlay` function so the `Game` component can update the `Board` when the user clicks a square:

```
function Board({ xIsNext, squares, onPlay }) {

  function handleClick(i) {

    if (calculateWinner(squares) || squares[i]) {

      return;

    }

    const nextSquares = squares.slice();

    if (xIsNext) {

      nextSquares[i] = "X";

    } else {

      nextSquares[i] = "O";

    }

    onPlay(nextSquares);

  }

  //...

}
```

The `Board` component is fully controlled by the props passed to it by the `Game` component. You need to implement the `handlePlay` function in the `Game` component to get the game working again.

What should `handlePlay` do when called? Remember that Board used to call `setSquares` with an updated array; now it passes the updated `squares` array to `onPlay`.

The `handlePlay` function needs to update `Game`’s state to trigger a re-render, but you don’t have a `setSquares` function that you can call any more—you’re now using the `history` state variable to store this information. You’ll want to update `history` by appending the updated `squares` array as a new history entry. You also want to toggle `xIsNext`, just as Board used to do:

```
export default function Game() {

  //...

  function handlePlay(nextSquares) {

    setHistory([...history, nextSquares]);

    setXIsNext(!xIsNext);

  }

  //...

}
```

Here, `[...history, nextSquares]` creates a new array that contains all the items in `history`, followed by `nextSquares`. (You can read the `...history` [*spread syntax*](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax) as “enumerate all the items in `history`”.)

For example, if `history` is `[[null,null,null], ["X",null,null]]` and `nextSquares` is `["X",null,"O"]`, then the new `[...history, nextSquares]` array will be `[[null,null,null], ["X",null,null], ["X",null,"O"]]`.

At this point, you’ve moved the state to live in the `Game` component, and the UI should be fully working, just as it was before the refactor. Here is what the code should look like at this point:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

function Square({ value, onSquareClick }) {
  return (
    <button className="square" onClick={onSquareClick}>
      {value}
    </button>
  );
}

function Board({ xIsNext, squares, onPlay }) {
  function handleClick(i) {
    if (calculateWinner(squares) || squares[i]) {
      return;
    }
    const nextSquares = squares.slice();
    if (xIsNext) {
      nextSquares[i] = 'X';
    } else {
      nextSquares[i] = 'O';
    }
    onPlay(nextSquares);
  }

  const winner = calculateWinner(squares);
  let status;
  if (winner) {
    status = 'Winner: ' + winner;
  } else {
    status = 'Next player: ' + (xIsNext ? 'X' : 'O');
  }

  return (
    <>
      <div className="status">{status}</div>
      <div className="board-row">
        <Square value={squares[0]} onSquareClick={() => handleClick(0)} />
        <Square value={squares[1]} onSquareClick={() => handleClick(1)} />
        <Square value={squares[2]} onSquareClick={() => handleClick(2)} />
      </div>
      <div className="board-row">
        <Square value={squares[3]} onSquareClick={() => handleClick(3)} />
        <Square value={squares[4]} onSquareClick={() => handleClick(4)} />
        <Square value={squares[5]} onSquareClick={() => handleClick(5)} />
      </div>
      <div className="board-row">
        <Square value={squares[6]} onSquareClick={() => handleClick(6)} />
        <Square value={squares[7]} onSquareClick={() => handleClick(7)} />
        <Square value={squares[8]} onSquareClick={() => handleClick(8)} />
      </div>
    </>
  );
}

export default function Game() {
  const [xIsNext, setXIsNext] = useState(true);
  const [history, setHistory] = useState([Array(9).fill(null)]);
  const currentSquares = history[history.length - 1];

  function handlePlay(nextSquares) {
    setHistory([...history, nextSquares]);
    setXIsNext(!xIsNext);
  }

  return (
    <div className="game">
      <div className="game-board">
        <Board xIsNext={xIsNext} squares={currentSquares} onPlay={handlePlay} />
      </div>
      <div className="game-info">
        <ol>{/*TODO*/}</ol>
      </div>
    </div>
  );
}

function calculateWinner(squares) {
  const lines = [
    [0, 1, 2],
    [3, 4, 5],
    [6, 7, 8],
    [0, 3, 6],
    [1, 4, 7],
    [2, 5, 8],
    [0, 4, 8],
    [2, 4, 6],
  ];
  for (let i = 0; i < lines.length; i++) {
    const [a, b, c] = lines[i];
    if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
      return squares[a];
    }
  }
  return null;
}
```

### Showing the past moves[](#showing-the-past-moves "Link for Showing the past moves ")

Since you are recording the tic-tac-toe game’s history, you can now display a list of past moves to the player.

React elements like `<button>` are regular JavaScript objects; you can pass them around in your application. To render multiple items in React, you can use an array of React elements.

You already have an array of `history` moves in state, so now you need to transform it to an array of React elements. In JavaScript, to transform one array into another, you can use the [array `map` method:](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map)

```
[1, 2, 3].map((x) => x * 2) // [2, 4, 6]
```

You’ll use `map` to transform your `history` of moves into React elements representing buttons on the screen, and display a list of buttons to “jump” to past moves. Let’s `map` over the `history` in the Game component:

```
export default function Game() {

  const [xIsNext, setXIsNext] = useState(true);

  const [history, setHistory] = useState([Array(9).fill(null)]);

  const currentSquares = history[history.length - 1];



  function handlePlay(nextSquares) {

    setHistory([...history, nextSquares]);

    setXIsNext(!xIsNext);

  }



  function jumpTo(nextMove) {

    // TODO

  }



  const moves = history.map((squares, move) => {

    let description;

    if (move > 0) {

      description = 'Go to move #' + move;

    } else {

      description = 'Go to game start';

    }

    return (

      <li>

        <button onClick={() => jumpTo(move)}>{description}</button>

      </li>

    );

  });



  return (

    <div className="game">

      <div className="game-board">

        <Board xIsNext={xIsNext} squares={currentSquares} onPlay={handlePlay} />

      </div>

      <div className="game-info">

        <ol>{moves}</ol>

      </div>

    </div>

  );

}
```

You can see what your code should look like below. Note that you should see an error in the developer tools console that says:

Console

Warning: Each child in an array or iterator should have a unique “key” prop. Check the render method of \`Game\`.

You’ll fix this error in the next section.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

function Square({ value, onSquareClick }) {
  return (
    <button className="square" onClick={onSquareClick}>
      {value}
    </button>
  );
}

function Board({ xIsNext, squares, onPlay }) {
  function handleClick(i) {
    if (calculateWinner(squares) || squares[i]) {
      return;
    }
    const nextSquares = squares.slice();
    if (xIsNext) {
      nextSquares[i] = 'X';
    } else {
      nextSquares[i] = 'O';
    }
    onPlay(nextSquares);
  }

  const winner = calculateWinner(squares);
  let status;
  if (winner) {
    status = 'Winner: ' + winner;
  } else {
    status = 'Next player: ' + (xIsNext ? 'X' : 'O');
  }

  return (
    <>
      <div className="status">{status}</div>
      <div className="board-row">
        <Square value={squares[0]} onSquareClick={() => handleClick(0)} />
        <Square value={squares[1]} onSquareClick={() => handleClick(1)} />
        <Square value={squares[2]} onSquareClick={() => handleClick(2)} />
      </div>
      <div className="board-row">
        <Square value={squares[3]} onSquareClick={() => handleClick(3)} />
        <Square value={squares[4]} onSquareClick={() => handleClick(4)} />
        <Square value={squares[5]} onSquareClick={() => handleClick(5)} />
      </div>
      <div className="board-row">
        <Square value={squares[6]} onSquareClick={() => handleClick(6)} />
        <Square value={squares[7]} onSquareClick={() => handleClick(7)} />
        <Square value={squares[8]} onSquareClick={() => handleClick(8)} />
      </div>
    </>
  );
}

export default function Game() {
  const [xIsNext, setXIsNext] = useState(true);
  const [history, setHistory] = useState([Array(9).fill(null)]);
  const currentSquares = history[history.length - 1];

  function handlePlay(nextSquares) {
    setHistory([...history, nextSquares]);
    setXIsNext(!xIsNext);
  }

  function jumpTo(nextMove) {
    // TODO
  }

  const moves = history.map((squares, move) => {
    let description;
    if (move > 0) {
      description = 'Go to move #' + move;
    } else {
      description = 'Go to game start';
    }
    return (
      <li>
        <button onClick={() => jumpTo(move)}>{description}</button>
      </li>
    );
  });

  return (
    <div className="game">
      <div className="game-board">
        <Board xIsNext={xIsNext} squares={currentSquares} onPlay={handlePlay} />
      </div>
      <div className="game-info">
        <ol>{moves}</ol>
      </div>
    </div>
  );
}

function calculateWinner(squares) {
  const lines = [
    [0, 1, 2],
    [3, 4, 5],
    [6, 7, 8],
    [0, 3, 6],
    [1, 4, 7],
    [2, 5, 8],
    [0, 4, 8],
    [2, 4, 6],
  ];
  for (let i = 0; i < lines.length; i++) {
    const [a, b, c] = lines[i];
    if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
      return squares[a];
    }
  }
  return null;
}
```

As you iterate through the `history` array inside the function you passed to `map`, the `squares` argument goes through each element of `history`, and the `move` argument goes through each array index: `0`, `1`, `2`, …. (In most cases, you’d need the actual array elements, but to render a list of moves you will only need indexes.)

For each move in the tic-tac-toe game’s history, you create a list item `<li>` which contains a button `<button>`. The button has an `onClick` handler which calls a function called `jumpTo` (that you haven’t implemented yet).

For now, you should see a list of the moves that occurred in the game and an error in the developer tools console. Let’s discuss what the “key” error means.

### Picking a key[](#picking-a-key "Link for Picking a key ")

When you render a list, React stores some information about each rendered list item. When you update a list, React needs to determine what has changed. You could have added, removed, re-arranged, or updated the list’s items.

Imagine transitioning from

```
<li>Alexa: 7 tasks left</li>

<li>Ben: 5 tasks left</li>
```

to

```
<li>Ben: 9 tasks left</li>

<li>Claudia: 8 tasks left</li>

<li>Alexa: 5 tasks left</li>
```

In addition to the updated counts, a human reading this would probably say that you swapped Alexa and Ben’s ordering and inserted Claudia between Alexa and Ben. However, React is a computer program and does not know what you intended, so you need to specify a *key* property for each list item to differentiate each list item from its siblings. If your data was from a database, Alexa, Ben, and Claudia’s database IDs could be used as keys.

```
<li key={user.id}>

  {user.name}: {user.taskCount} tasks left

</li>
```

```
const moves = history.map((squares, move) => {

  //...

  return (

    <li key={move}>

      <button onClick={() => jumpTo(move)}>{description}</button>

    </li>

  );

});
```

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

function Square({ value, onSquareClick }) {
  return (
    <button className="square" onClick={onSquareClick}>
      {value}
    </button>
  );
}

function Board({ xIsNext, squares, onPlay }) {
  function handleClick(i) {
    if (calculateWinner(squares) || squares[i]) {
      return;
    }
    const nextSquares = squares.slice();
    if (xIsNext) {
      nextSquares[i] = 'X';
    } else {
      nextSquares[i] = 'O';
    }
    onPlay(nextSquares);
  }

  const winner = calculateWinner(squares);
  let status;
  if (winner) {
    status = 'Winner: ' + winner;
  } else {
    status = 'Next player: ' + (xIsNext ? 'X' : 'O');
  }

  return (
    <>
      <div className="status">{status}</div>
      <div className="board-row">
        <Square value={squares[0]} onSquareClick={() => handleClick(0)} />
        <Square value={squares[1]} onSquareClick={() => handleClick(1)} />
        <Square value={squares[2]} onSquareClick={() => handleClick(2)} />
      </div>
      <div className="board-row">
        <Square value={squares[3]} onSquareClick={() => handleClick(3)} />
        <Square value={squares[4]} onSquareClick={() => handleClick(4)} />
        <Square value={squares[5]} onSquareClick={() => handleClick(5)} />
      </div>
      <div className="board-row">
        <Square value={squares[6]} onSquareClick={() => handleClick(6)} />
        <Square value={squares[7]} onSquareClick={() => handleClick(7)} />
        <Square value={squares[8]} onSquareClick={() => handleClick(8)} />
      </div>
    </>
  );
}

export default function Game() {
  const [xIsNext, setXIsNext] = useState(true);
  const [history, setHistory] = useState([Array(9).fill(null)]);
  const currentSquares = history[history.length - 1];

  function handlePlay(nextSquares) {
    setHistory([...history, nextSquares]);
    setXIsNext(!xIsNext);
  }

  function jumpTo(nextMove) {
    // TODO
  }

  const moves = history.map((squares, move) => {
    let description;
    if (move > 0) {
      description = 'Go to move #' + move;
    } else {
      description = 'Go to game start';
    }
    return (
      <li key={move}>
        <button onClick={() => jumpTo(move)}>{description}</button>
      </li>
    );
  });

  return (
    <div className="game">
      <div className="game-board">
        <Board xIsNext={xIsNext} squares={currentSquares} onPlay={handlePlay} />
      </div>
      <div className="game-info">
        <ol>{moves}</ol>
      </div>
    </div>
  );
}

function calculateWinner(squares) {
  const lines = [
    [0, 1, 2],
    [3, 4, 5],
    [6, 7, 8],
    [0, 3, 6],
    [1, 4, 7],
    [2, 5, 8],
    [0, 4, 8],
    [2, 4, 6],
  ];
  for (let i = 0; i < lines.length; i++) {
    const [a, b, c] = lines[i];
    if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
      return squares[a];
    }
  }
  return null;
}
```

Before you can implement `jumpTo`, you need the `Game` component to keep track of which step the user is currently viewing. To do this, define a new state variable called `currentMove`, defaulting to `0`:

```
export default function Game() {

  const [xIsNext, setXIsNext] = useState(true);

  const [history, setHistory] = useState([Array(9).fill(null)]);

  const [currentMove, setCurrentMove] = useState(0);

  const currentSquares = history[history.length - 1];

  //...

}
```

Next, update the `jumpTo` function inside `Game` to update that `currentMove`. You’ll also set `xIsNext` to `true` if the number that you’re changing `currentMove` to is even.

```
export default function Game() {

  // ...

  function jumpTo(nextMove) {

    setCurrentMove(nextMove);

    setXIsNext(nextMove % 2 === 0);

  }

  //...

}
```

You will now make two changes to the `Game`’s `handlePlay` function which is called when you click on a square.

* If you “go back in time” and then make a new move from that point, you only want to keep the history up to that point. Instead of adding `nextSquares` after all items (`...` spread syntax) in `history`, you’ll add it after all items in `history.slice(0, currentMove + 1)` so that you’re only keeping that portion of the old history.
* Each time a move is made, you need to update `currentMove` to point to the latest history entry.

```
function handlePlay(nextSquares) {

  const nextHistory = [...history.slice(0, currentMove + 1), nextSquares];

  setHistory(nextHistory);

  setCurrentMove(nextHistory.length - 1);

  setXIsNext(!xIsNext);

}
```

Finally, you will modify the `Game` component to render the currently selected move, instead of always rendering the final move:

```
export default function Game() {

  const [xIsNext, setXIsNext] = useState(true);

  const [history, setHistory] = useState([Array(9).fill(null)]);

  const [currentMove, setCurrentMove] = useState(0);

  const currentSquares = history[currentMove];



  // ...

}
```

If you click on any step in the game’s history, the tic-tac-toe board should immediately update to show what the board looked like after that step occurred.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

function Square({value, onSquareClick}) {
  return (
    <button className="square" onClick={onSquareClick}>
      {value}
    </button>
  );
}

function Board({ xIsNext, squares, onPlay }) {
  function handleClick(i) {
    if (calculateWinner(squares) || squares[i]) {
      return;
    }
    const nextSquares = squares.slice();
    if (xIsNext) {
      nextSquares[i] = 'X';
    } else {
      nextSquares[i] = 'O';
    }
    onPlay(nextSquares);
  }

  const winner = calculateWinner(squares);
  let status;
  if (winner) {
    status = 'Winner: ' + winner;
  } else {
    status = 'Next player: ' + (xIsNext ? 'X' : 'O');
  }

  return (
    <>
      <div className="status">{status}</div>
      <div className="board-row">
        <Square value={squares[0]} onSquareClick={() => handleClick(0)} />
        <Square value={squares[1]} onSquareClick={() => handleClick(1)} />
        <Square value={squares[2]} onSquareClick={() => handleClick(2)} />
      </div>
      <div className="board-row">
        <Square value={squares[3]} onSquareClick={() => handleClick(3)} />
        <Square value={squares[4]} onSquareClick={() => handleClick(4)} />
        <Square value={squares[5]} onSquareClick={() => handleClick(5)} />
      </div>
      <div className="board-row">
        <Square value={squares[6]} onSquareClick={() => handleClick(6)} />
        <Square value={squares[7]} onSquareClick={() => handleClick(7)} />
        <Square value={squares[8]} onSquareClick={() => handleClick(8)} />
      </div>
    </>
  );
}

export default function Game() {
  const [xIsNext, setXIsNext] = useState(true);
  const [history, setHistory] = useState([Array(9).fill(null)]);
  const [currentMove, setCurrentMove] = useState(0);
  const currentSquares = history[currentMove];

  function handlePlay(nextSquares) {
    const nextHistory = [...history.slice(0, currentMove + 1), nextSquares];
    setHistory(nextHistory);
    setCurrentMove(nextHistory.length - 1);
    setXIsNext(!xIsNext);
  }

  function jumpTo(nextMove) {
    setCurrentMove(nextMove);
    setXIsNext(nextMove % 2 === 0);
  }

  const moves = history.map((squares, move) => {
    let description;
    if (move > 0) {
      description = 'Go to move #' + move;
    } else {
      description = 'Go to game start';
    }
    return (
      <li key={move}>
        <button onClick={() => jumpTo(move)}>{description}</button>
      </li>
    );
  });

  return (
    <div className="game">
      <div className="game-board">
        <Board xIsNext={xIsNext} squares={currentSquares} onPlay={handlePlay} />
      </div>
      <div className="game-info">
        <ol>{moves}</ol>
      </div>
    </div>
  );
}

function calculateWinner(squares) {
  const lines = [
    [0, 1, 2],
    [3, 4, 5],
    [6, 7, 8],
    [0, 3, 6],
    [1, 4, 7],
    [2, 5, 8],
    [0, 4, 8],
    [2, 4, 6],
  ];
  for (let i = 0; i < lines.length; i++) {
    const [a, b, c] = lines[i];
    if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
      return squares[a];
    }
  }
  return null;
}
```

### Final cleanup[](#final-cleanup "Link for Final cleanup ")

If you look at the code very closely, you may notice that `xIsNext === true` when `currentMove` is even and `xIsNext === false` when `currentMove` is odd. In other words, if you know the value of `currentMove`, then you can always figure out what `xIsNext` should be.

There’s no reason for you to store both of these in state. In fact, always try to avoid redundant state. Simplifying what you store in state reduces bugs and makes your code easier to understand. Change `Game` so that it doesn’t store `xIsNext` as a separate state variable and instead figures it out based on the `currentMove`:

```
export default function Game() {

  const [history, setHistory] = useState([Array(9).fill(null)]);

  const [currentMove, setCurrentMove] = useState(0);

  const xIsNext = currentMove % 2 === 0;

  const currentSquares = history[currentMove];



  function handlePlay(nextSquares) {

    const nextHistory = [...history.slice(0, currentMove + 1), nextSquares];

    setHistory(nextHistory);

    setCurrentMove(nextHistory.length - 1);

  }



  function jumpTo(nextMove) {

    setCurrentMove(nextMove);

  }

  // ...

}
```

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

function Square({ value, onSquareClick }) {
  return (
    <button className="square" onClick={onSquareClick}>
      {value}
    </button>
  );
}

function Board({ xIsNext, squares, onPlay }) {
  function handleClick(i) {
    if (calculateWinner(squares) || squares[i]) {
      return;
    }
    const nextSquares = squares.slice();
    if (xIsNext) {
      nextSquares[i] = 'X';
    } else {
      nextSquares[i] = 'O';
    }
    onPlay(nextSquares);
  }

  const winner = calculateWinner(squares);
  let status;
  if (winner) {
    status = 'Winner: ' + winner;
  } else {
    status = 'Next player: ' + (xIsNext ? 'X' : 'O');
  }

  return (
    <>
      <div className="status">{status}</div>
      <div className="board-row">
        <Square value={squares[0]} onSquareClick={() => handleClick(0)} />
        <Square value={squares[1]} onSquareClick={() => handleClick(1)} />
        <Square value={squares[2]} onSquareClick={() => handleClick(2)} />
      </div>
      <div className="board-row">
        <Square value={squares[3]} onSquareClick={() => handleClick(3)} />
        <Square value={squares[4]} onSquareClick={() => handleClick(4)} />
        <Square value={squares[5]} onSquareClick={() => handleClick(5)} />
      </div>
      <div className="board-row">
        <Square value={squares[6]} onSquareClick={() => handleClick(6)} />
        <Square value={squares[7]} onSquareClick={() => handleClick(7)} />
        <Square value={squares[8]} onSquareClick={() => handleClick(8)} />
      </div>
    </>
  );
}

export default function Game() {
  const [history, setHistory] = useState([Array(9).fill(null)]);
  const [currentMove, setCurrentMove] = useState(0);
  const xIsNext = currentMove % 2 === 0;
  const currentSquares = history[currentMove];

  function handlePlay(nextSquares) {
    const nextHistory = [...history.slice(0, currentMove + 1), nextSquares];
    setHistory(nextHistory);
    setCurrentMove(nextHistory.length - 1);
  }

  function jumpTo(nextMove) {
    setCurrentMove(nextMove);
  }

  const moves = history.map((squares, move) => {
    let description;
    if (move > 0) {
      description = 'Go to move #' + move;
    } else {
      description = 'Go to game start';
    }
    return (
      <li key={move}>
        <button onClick={() => jumpTo(move)}>{description}</button>
      </li>
    );
  });

  return (
    <div className="game">
      <div className="game-board">
        <Board xIsNext={xIsNext} squares={currentSquares} onPlay={handlePlay} />
      </div>
      <div className="game-info">
        <ol>{moves}</ol>
      </div>
    </div>
  );
}

function calculateWinner(squares) {
  const lines = [
    [0, 1, 2],
    [3, 4, 5],
    [6, 7, 8],
    [0, 3, 6],
    [1, 4, 7],
    [2, 5, 8],
    [0, 4, 8],
    [2, 4, 6],
  ];
  for (let i = 0; i < lines.length; i++) {
    const [a, b, c] = lines[i];
    if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
      return squares[a];
    }
  }
  return null;
}
```

***

----
url: https://react.dev/reference/react-dom/server/renderToReadableStream
----

[API Reference](/reference/react)

[Server APIs](/reference/react-dom/server)

# renderToReadableStream[](#undefined "Link for this heading")

`renderToReadableStream` renders a React tree to a [Readable Web Stream.](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream)

```
const stream = await renderToReadableStream(reactNode, options?)
```

* [Reference](#reference)
  * [`renderToReadableStream(reactNode, options?)`](#rendertoreadablestream)

* [Usage](#usage)

  * [Rendering a React tree as HTML to a Readable Web Stream](#rendering-a-react-tree-as-html-to-a-readable-web-stream)
  * [Streaming more content as it loads](#streaming-more-content-as-it-loads)
  * [Specifying what goes into the shell](#specifying-what-goes-into-the-shell)
  * [Logging crashes on the server](#logging-crashes-on-the-server)
  * [Recovering from errors inside the shell](#recovering-from-errors-inside-the-shell)
  * [Recovering from errors outside the shell](#recovering-from-errors-outside-the-shell)
  * [Setting the status code](#setting-the-status-code)
  * [Handling different errors in different ways](#handling-different-errors-in-different-ways)
  * [Waiting for all content to load for crawlers and static generation](#waiting-for-all-content-to-load-for-crawlers-and-static-generation)
  * [Aborting server rendering](#aborting-server-rendering)

### Note

This API depends on [Web Streams.](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API) For Node.js, use [`renderToPipeableStream`](/reference/react-dom/server/renderToPipeableStream) instead.

***

## Reference[](#reference "Link for Reference ")

### `renderToReadableStream(reactNode, options?)`[](#rendertoreadablestream "Link for this heading")

Call `renderToReadableStream` to render your React tree as HTML into a [Readable Web Stream.](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream)

```
import { renderToReadableStream } from 'react-dom/server';



async function handler(request) {

  const stream = await renderToReadableStream(<App />, {

    bootstrapScripts: ['/main.js']

  });

  return new Response(stream, {

    headers: { 'content-type': 'text/html' },

  });

}
```

On the client, call [`hydrateRoot`](/reference/react-dom/client/hydrateRoot) to make the server-generated HTML interactive.

[See more examples below.](#usage)

#### Parameters[](#parameters "Link for Parameters ")

* `reactNode`: A React node you want to render to HTML. For example, a JSX element like `<App />`. It is expected to represent the entire document, so the `App` component should render the `<html>` tag.

* **optional** `options`: An object with streaming options.

  * **optional** `bootstrapScriptContent`: If specified, this string will be placed in an inline `<script>` tag.
  * **optional** `bootstrapScripts`: An array of string URLs for the `<script>` tags to emit on the page. Use this to include the `<script>` that calls [`hydrateRoot`.](/reference/react-dom/client/hydrateRoot) Omit it if you don’t want to run React on the client at all.
  * **optional** `bootstrapModules`: Like `bootstrapScripts`, but emits [`<script type="module">`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules) instead.
  * **optional** `identifierPrefix`: A string prefix React uses for IDs generated by [`useId`.](/reference/react/useId) Useful to avoid conflicts when using multiple roots on the same page. Must be the same prefix as passed to [`hydrateRoot`.](/reference/react-dom/client/hydrateRoot#parameters)
  * **optional** `namespaceURI`: A string with the root [namespace URI](https://developer.mozilla.org/en-US/docs/Web/API/Document/createElementNS#important_namespace_uris) for the stream. Defaults to regular HTML. Pass `'http://www.w3.org/2000/svg'` for SVG or `'http://www.w3.org/1998/Math/MathML'` for MathML.
  * **optional** `nonce`: A [`nonce`](http://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#nonce) string to allow scripts for [`script-src` Content-Security-Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src).
  * **optional** `onError`: A callback that fires whenever there is a server error, whether [recoverable](#recovering-from-errors-outside-the-shell) or [not.](#recovering-from-errors-inside-the-shell) By default, this only calls `console.error`. If you override it to [log crash reports,](#logging-crashes-on-the-server) make sure that you still call `console.error`. You can also use it to [adjust the status code](#setting-the-status-code) before the shell is emitted.
  * **optional** `progressiveChunkSize`: The number of bytes in a chunk. [Read more about the default heuristic.](https://github.com/facebook/react/blob/14c2be8dac2d5482fda8a0906a31d239df8551fc/packages/react-server/src/ReactFizzServer.js#L210-L225)
  * **optional** `signal`: An [abort signal](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal) that lets you [abort server rendering](#aborting-server-rendering) and render the rest on the client.

#### Returns[](#returns "Link for Returns ")

`renderToReadableStream` returns a Promise:

* If rendering the [shell](#specifying-what-goes-into-the-shell) is successful, that Promise will resolve to a [Readable Web Stream.](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream)
* If rendering the shell fails, the Promise will be rejected. [Use this to output a fallback shell.](#recovering-from-errors-inside-the-shell)

The returned stream has an additional property:

* `allReady`: A Promise that resolves when all rendering is complete, including both the [shell](#specifying-what-goes-into-the-shell) and all additional [content.](#streaming-more-content-as-it-loads) You can `await stream.allReady` before returning a response [for crawlers and static generation.](#waiting-for-all-content-to-load-for-crawlers-and-static-generation) If you do that, you won’t get any progressive loading. The stream will contain the final HTML.

***

## Usage[](#usage "Link for Usage ")

### Rendering a React tree as HTML to a Readable Web Stream[](#rendering-a-react-tree-as-html-to-a-readable-web-stream "Link for Rendering a React tree as HTML to a Readable Web Stream ")

Call `renderToReadableStream` to render your React tree as HTML into a [Readable Web Stream:](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream)

```
import { renderToReadableStream } from 'react-dom/server';



async function handler(request) {

  const stream = await renderToReadableStream(<App />, {

    bootstrapScripts: ['/main.js']

  });

  return new Response(stream, {

    headers: { 'content-type': 'text/html' },

  });

}
```

Along with the root component, you need to provide a list of bootstrap `<script>` paths. Your root component should return **the entire document including the root `<html>` tag.**

For example, it might look like this:

```
export default function App() {

  return (

    <html>

      <head>

        <meta charSet="utf-8" />

        <meta name="viewport" content="width=device-width, initial-scale=1" />

        <link rel="stylesheet" href="/styles.css"></link>

        <title>My app</title>

      </head>

      <body>

        <Router />

      </body>

    </html>

  );

}
```

React will inject the [doctype](https://developer.mozilla.org/en-US/docs/Glossary/Doctype) and your bootstrap `<script>` tags into the resulting HTML stream:

```
<!DOCTYPE html>

<html>

  <!-- ... HTML from your components ... -->

</html>

<script src="/main.js" async=""></script>
```

On the client, your bootstrap script should [hydrate the entire `document` with a call to `hydrateRoot`:](/reference/react-dom/client/hydrateRoot#hydrating-an-entire-document)

```
import { hydrateRoot } from 'react-dom/client';

import App from './App.js';



hydrateRoot(document, <App />);
```

This will attach event listeners to the server-generated HTML and make it interactive.

##### Deep Dive#### Reading CSS and JS asset paths from the build output[](#reading-css-and-js-asset-paths-from-the-build-output "Link for Reading CSS and JS asset paths from the build output ")

The final asset URLs (like JavaScript and CSS files) are often hashed after the build. For example, instead of `styles.css` you might end up with `styles.123456.css`. Hashing static asset filenames guarantees that every distinct build of the same asset will have a different filename. This is useful because it lets you safely enable long-term caching for static assets: a file with a certain name would never change content.

However, if you don’t know the asset URLs until after the build, there’s no way for you to put them in the source code. For example, hardcoding `"/styles.css"` into JSX like earlier wouldn’t work. To keep them out of your source code, your root component can read the real filenames from a map passed as a prop:

```
export default function App({ assetMap }) {

  return (

    <html>

      <head>

        <title>My app</title>

        <link rel="stylesheet" href={assetMap['styles.css']}></link>

      </head>

      ...

    </html>

  );

}
```

On the server, render `<App assetMap={assetMap} />` and pass your `assetMap` with the asset URLs:

```
// You'd need to get this JSON from your build tooling, e.g. read it from the build output.

const assetMap = {

  'styles.css': '/styles.123456.css',

  'main.js': '/main.123456.js'

};



async function handler(request) {

  const stream = await renderToReadableStream(<App assetMap={assetMap} />, {

    bootstrapScripts: [assetMap['/main.js']]

  });

  return new Response(stream, {

    headers: { 'content-type': 'text/html' },

  });

}
```

Since your server is now rendering `<App assetMap={assetMap} />`, you need to render it with `assetMap` on the client too to avoid hydration errors. You can serialize and pass `assetMap` to the client like this:

```
// You'd need to get this JSON from your build tooling.

const assetMap = {

  'styles.css': '/styles.123456.css',

  'main.js': '/main.123456.js'

};



async function handler(request) {

  const stream = await renderToReadableStream(<App assetMap={assetMap} />, {

    // Careful: It's safe to stringify() this because this data isn't user-generated.

    bootstrapScriptContent: `window.assetMap = ${JSON.stringify(assetMap)};`,

    bootstrapScripts: [assetMap['/main.js']],

  });

  return new Response(stream, {

    headers: { 'content-type': 'text/html' },

  });

}
```

In the example above, the `bootstrapScriptContent` option adds an extra inline `<script>` tag that sets the global `window.assetMap` variable on the client. This lets the client code read the same `assetMap`:

```
import { hydrateRoot } from 'react-dom/client';

import App from './App.js';



hydrateRoot(document, <App assetMap={window.assetMap} />);
```

Both client and server render `App` with the same `assetMap` prop, so there are no hydration errors.

***

### Streaming more content as it loads[](#streaming-more-content-as-it-loads "Link for Streaming more content as it loads ")

Streaming allows the user to start seeing the content even before all the data has loaded on the server. For example, consider a profile page that shows a cover, a sidebar with friends and photos, and a list of posts:

```
function ProfilePage() {

  return (

    <ProfileLayout>

      <ProfileCover />

      <Sidebar>

        <Friends />

        <Photos />

      </Sidebar>

      <Posts />

    </ProfileLayout>

  );

}
```

Imagine that loading data for `<Posts />` takes some time. Ideally, you’d want to show the rest of the profile page content to the user without waiting for the posts. To do this, [wrap `Posts` in a `<Suspense>` boundary:](/reference/react/Suspense#displaying-a-fallback-while-content-is-loading)

```
function ProfilePage() {

  return (

    <ProfileLayout>

      <ProfileCover />

      <Sidebar>

        <Friends />

        <Photos />

      </Sidebar>

      <Suspense fallback={<PostsGlimmer />}>

        <Posts />

      </Suspense>

    </ProfileLayout>

  );

}
```

This tells React to start streaming the HTML before `Posts` loads its data. React will send the HTML for the loading fallback (`PostsGlimmer`) first, and then, when `Posts` finishes loading its data, React will send the remaining HTML along with an inline `<script>` tag that replaces the loading fallback with that HTML. From the user’s perspective, the page will first appear with the `PostsGlimmer`, later replaced by the `Posts`.

You can further [nest `<Suspense>` boundaries](/reference/react/Suspense#revealing-nested-content-as-it-loads) to create a more granular loading sequence:

```
function ProfilePage() {

  return (

    <ProfileLayout>

      <ProfileCover />

      <Suspense fallback={<BigSpinner />}>

        <Sidebar>

          <Friends />

          <Photos />

        </Sidebar>

        <Suspense fallback={<PostsGlimmer />}>

          <Posts />

        </Suspense>

      </Suspense>

    </ProfileLayout>

  );

}
```

***

### Specifying what goes into the shell[](#specifying-what-goes-into-the-shell "Link for Specifying what goes into the shell ")

The part of your app outside of any `<Suspense>` boundaries is called *the shell:*

```
function ProfilePage() {

  return (

    <ProfileLayout>

      <ProfileCover />

      <Suspense fallback={<BigSpinner />}>

        <Sidebar>

          <Friends />

          <Photos />

        </Sidebar>

        <Suspense fallback={<PostsGlimmer />}>

          <Posts />

        </Suspense>

      </Suspense>

    </ProfileLayout>

  );

}
```

It determines the earliest loading state that the user may see:

```
<ProfileLayout>

  <ProfileCover />

  <BigSpinner />

</ProfileLayout>
```

If you wrap the whole app into a `<Suspense>` boundary at the root, the shell will only contain that spinner. However, that’s not a pleasant user experience because seeing a big spinner on the screen can feel slower and more annoying than waiting a bit more and seeing the real layout. This is why usually you’ll want to place the `<Suspense>` boundaries so that the shell feels *minimal but complete*—like a skeleton of the entire page layout.

The async call to `renderToReadableStream` will resolve to a `stream` as soon as the entire shell has been rendered. Usually, you’ll start streaming then by creating and returning a response with that `stream`:

```
async function handler(request) {

  const stream = await renderToReadableStream(<App />, {

    bootstrapScripts: ['/main.js']

  });

  return new Response(stream, {

    headers: { 'content-type': 'text/html' },

  });

}
```

By the time the `stream` is returned, components in nested `<Suspense>` boundaries might still be loading data.

***

### Logging crashes on the server[](#logging-crashes-on-the-server "Link for Logging crashes on the server ")

By default, all errors on the server are logged to console. You can override this behavior to log crash reports:

```
async function handler(request) {

  const stream = await renderToReadableStream(<App />, {

    bootstrapScripts: ['/main.js'],

    onError(error) {

      console.error(error);

      logServerCrashReport(error);

    }

  });

  return new Response(stream, {

    headers: { 'content-type': 'text/html' },

  });

}
```

If you provide a custom `onError` implementation, don’t forget to also log errors to the console like above.

***

### Recovering from errors inside the shell[](#recovering-from-errors-inside-the-shell "Link for Recovering from errors inside the shell ")

In this example, the shell contains `ProfileLayout`, `ProfileCover`, and `PostsGlimmer`:

```
function ProfilePage() {

  return (

    <ProfileLayout>

      <ProfileCover />

      <Suspense fallback={<PostsGlimmer />}>

        <Posts />

      </Suspense>

    </ProfileLayout>

  );

}
```

If an error occurs while rendering those components, React won’t have any meaningful HTML to send to the client. Wrap your `renderToReadableStream` call in a `try...catch` to send a fallback HTML that doesn’t rely on server rendering as the last resort:

```
async function handler(request) {

  try {

    const stream = await renderToReadableStream(<App />, {

      bootstrapScripts: ['/main.js'],

      onError(error) {

        console.error(error);

        logServerCrashReport(error);

      }

    });

    return new Response(stream, {

      headers: { 'content-type': 'text/html' },

    });

  } catch (error) {

    return new Response('<h1>Something went wrong</h1>', {

      status: 500,

      headers: { 'content-type': 'text/html' },

    });

  }

}
```

If there is an error while generating the shell, both `onError` and your `catch` block will fire. Use `onError` for error reporting and use the `catch` block to send the fallback HTML document. Your fallback HTML does not have to be an error page. Instead, you may include an alternative shell that renders your app on the client only.

***

### Recovering from errors outside the shell[](#recovering-from-errors-outside-the-shell "Link for Recovering from errors outside the shell ")

In this example, the `<Posts />` component is wrapped in `<Suspense>` so it is *not* a part of the shell:

```
function ProfilePage() {

  return (

    <ProfileLayout>

      <ProfileCover />

      <Suspense fallback={<PostsGlimmer />}>

        <Posts />

      </Suspense>

    </ProfileLayout>

  );

}
```

If an error happens in the `Posts` component or somewhere inside it, React will [try to recover from it:](/reference/react/Suspense#providing-a-fallback-for-server-errors-and-client-only-content)

1. It will emit the loading fallback for the closest `<Suspense>` boundary (`PostsGlimmer`) into the HTML.
2. It will “give up” on trying to render the `Posts` content on the server anymore.
3. When the JavaScript code loads on the client, React will *retry* rendering `Posts` on the client.

If retrying rendering `Posts` on the client *also* fails, React will throw the error on the client. As with all the errors thrown during rendering, the [closest parent error boundary](/reference/react/Component#static-getderivedstatefromerror) determines how to present the error to the user. In practice, this means that the user will see a loading indicator until it is certain that the error is not recoverable.

If retrying rendering `Posts` on the client succeeds, the loading fallback from the server will be replaced with the client rendering output. The user will not know that there was a server error. However, the server `onError` callback and the client [`onRecoverableError`](/reference/react-dom/client/hydrateRoot#hydrateroot) callbacks will fire so that you can get notified about the error.

***

### Setting the status code[](#setting-the-status-code "Link for Setting the status code ")

Streaming introduces a tradeoff. You want to start streaming the page as early as possible so that the user can see the content sooner. However, once you start streaming, you can no longer set the response status code.

By [dividing your app](#specifying-what-goes-into-the-shell) into the shell (above all `<Suspense>` boundaries) and the rest of the content, you’ve already solved a part of this problem. If the shell errors, your `catch` block will run which lets you set the error status code. Otherwise, you know that the app may recover on the client, so you can send “OK”.

```
async function handler(request) {

  try {

    const stream = await renderToReadableStream(<App />, {

      bootstrapScripts: ['/main.js'],

      onError(error) {

        console.error(error);

        logServerCrashReport(error);

      }

    });

    return new Response(stream, {

      status: 200,

      headers: { 'content-type': 'text/html' },

    });

  } catch (error) {

    return new Response('<h1>Something went wrong</h1>', {

      status: 500,

      headers: { 'content-type': 'text/html' },

    });

  }

}
```

If a component *outside* the shell (i.e. inside a `<Suspense>` boundary) throws an error, React will not stop rendering. This means that the `onError` callback will fire, but your code will continue running without getting into the `catch` block. This is because React will try to recover from that error on the client, [as described above.](#recovering-from-errors-outside-the-shell)

However, if you’d like, you can use the fact that something has errored to set the status code:

```
async function handler(request) {

  try {

    let didError = false;

    const stream = await renderToReadableStream(<App />, {

      bootstrapScripts: ['/main.js'],

      onError(error) {

        didError = true;

        console.error(error);

        logServerCrashReport(error);

      }

    });

    return new Response(stream, {

      status: didError ? 500 : 200,

      headers: { 'content-type': 'text/html' },

    });

  } catch (error) {

    return new Response('<h1>Something went wrong</h1>', {

      status: 500,

      headers: { 'content-type': 'text/html' },

    });

  }

}
```

This will only catch errors outside the shell that happened while generating the initial shell content, so it’s not exhaustive. If knowing whether an error occurred for some content is critical, you can move it up into the shell.

***

### Handling different errors in different ways[](#handling-different-errors-in-different-ways "Link for Handling different errors in different ways ")

You can [create your own `Error` subclasses](https://javascript.info/custom-errors) and use the [`instanceof`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/instanceof) operator to check which error is thrown. For example, you can define a custom `NotFoundError` and throw it from your component. Then you can save the error in `onError` and do something different before returning the response depending on the error type:

```
async function handler(request) {

  let didError = false;

  let caughtError = null;



  function getStatusCode() {

    if (didError) {

      if (caughtError instanceof NotFoundError) {

        return 404;

      } else {

        return 500;

      }

    } else {

      return 200;

    }

  }



  try {

    const stream = await renderToReadableStream(<App />, {

      bootstrapScripts: ['/main.js'],

      onError(error) {

        didError = true;

        caughtError = error;

        console.error(error);

        logServerCrashReport(error);

      }

    });

    return new Response(stream, {

      status: getStatusCode(),

      headers: { 'content-type': 'text/html' },

    });

  } catch (error) {

    return new Response('<h1>Something went wrong</h1>', {

      status: getStatusCode(),

      headers: { 'content-type': 'text/html' },

    });

  }

}
```

Keep in mind that once you emit the shell and start streaming, you can’t change the status code.

***

### Waiting for all content to load for crawlers and static generation[](#waiting-for-all-content-to-load-for-crawlers-and-static-generation "Link for Waiting for all content to load for crawlers and static generation ")

Streaming offers a better user experience because the user can see the content as it becomes available.

However, when a crawler visits your page, or if you’re generating the pages at the build time, you might want to let all of the content load first and then produce the final HTML output instead of revealing it progressively.

You can wait for all the content to load by awaiting the `stream.allReady` Promise:

```
async function handler(request) {

  try {

    let didError = false;

    const stream = await renderToReadableStream(<App />, {

      bootstrapScripts: ['/main.js'],

      onError(error) {

        didError = true;

        console.error(error);

        logServerCrashReport(error);

      }

    });

    let isCrawler = // ... depends on your bot detection strategy ...

    if (isCrawler) {

      await stream.allReady;

    }

    return new Response(stream, {

      status: didError ? 500 : 200,

      headers: { 'content-type': 'text/html' },

    });

  } catch (error) {

    return new Response('<h1>Something went wrong</h1>', {

      status: 500,

      headers: { 'content-type': 'text/html' },

    });

  }

}
```

A regular visitor will get a stream of progressively loaded content. A crawler will receive the final HTML output after all the data loads. However, this also means that the crawler will have to wait for *all* data, some of which might be slow to load or error. Depending on your app, you could choose to send the shell to the crawlers too.

***

### Aborting server rendering[](#aborting-server-rendering "Link for Aborting server rendering ")

You can force the server rendering to “give up” after a timeout:

```
async function handler(request) {

  try {

    const controller = new AbortController();

    setTimeout(() => {

      controller.abort();

    }, 10000);



    const stream = await renderToReadableStream(<App />, {

      signal: controller.signal,

      bootstrapScripts: ['/main.js'],

      onError(error) {

        didError = true;

        console.error(error);

        logServerCrashReport(error);

      }

    });

    // ...
```

React will flush the remaining loading fallbacks as HTML, and will attempt to render the rest on the client.

[PreviousrenderToPipeableStream](/reference/react-dom/server/renderToPipeableStream)

[NextrenderToStaticMarkup](/reference/react-dom/server/renderToStaticMarkup)

***

----
url: https://18.react.dev/learn/writing-markup-with-jsx
----

```
<h1>Hedy Lamarr's Todos</h1>

<img 

  src="https://i.imgur.com/yXOvdOSs.jpg" 

  alt="Hedy Lamarr" 

  class="photo"

>

<ul>

    <li>Invent new traffic lights

    <li>Rehearse a movie scene

    <li>Improve the spectrum technology

</ul>
```

And you want to put it into your component:

```
export default function TodoList() {

  return (

    // ???

  )

}
```

If you copy and paste it as is, it will not work:

```
export default function TodoList() {
  return (
    // This doesn't quite work!
    <h1>Hedy Lamarr's Todos</h1>
    <img 
      src="https://i.imgur.com/yXOvdOSs.jpg" 
      alt="Hedy Lamarr" 
      class="photo"
    >
    <ul>
      <li>Invent new traffic lights
      <li>Rehearse a movie scene
      <li>Improve the spectrum technology
    </ul>
```

```
<div>

  <h1>Hedy Lamarr's Todos</h1>

  <img 

    src="https://i.imgur.com/yXOvdOSs.jpg" 

    alt="Hedy Lamarr" 

    class="photo"

  >

  <ul>

    ...

  </ul>

</div>
```

If you don’t want to add an extra `<div>` to your markup, you can write `<>` and `</>` instead:

```
<>

  <h1>Hedy Lamarr's Todos</h1>

  <img 

    src="https://i.imgur.com/yXOvdOSs.jpg" 

    alt="Hedy Lamarr" 

    class="photo"

  >

  <ul>

    ...

  </ul>

</>
```

This empty tag is called a *[Fragment.](/reference/react/Fragment)* Fragments let you group things without leaving any trace in the browser HTML tree.

##### Deep Dive#### Why do multiple JSX tags need to be wrapped?[](#why-do-multiple-jsx-tags-need-to-be-wrapped "Link for Why do multiple JSX tags need to be wrapped? ")

JSX looks like HTML, but under the hood it is transformed into plain JavaScript objects. You can’t return two objects from a function without wrapping them into an array. This explains why you also can’t return two JSX tags without wrapping them into another tag or a Fragment.

### 2. Close all the tags[](#2-close-all-the-tags "Link for 2. Close all the tags ")

JSX requires tags to be explicitly closed: self-closing tags like `<img>` must become `<img />`, and wrapping tags like `<li>oranges` must be written as `<li>oranges</li>`.

This is how Hedy Lamarr’s image and list items look closed:

```
<>

  <img 

    src="https://i.imgur.com/yXOvdOSs.jpg" 

    alt="Hedy Lamarr" 

    class="photo"

   />

  <ul>

    <li>Invent new traffic lights</li>

    <li>Rehearse a movie scene</li>

    <li>Improve the spectrum technology</li>

  </ul>

</>
```

### 3. camelCase ~~all~~ most of the things\![](#3-camelcase-salls-most-of-the-things "Link for this heading")

JSX turns into JavaScript and attributes written in JSX become keys of JavaScript objects. In your own components, you will often want to read those attributes into variables. But JavaScript has limitations on variable names. For example, their names can’t contain dashes or be reserved words like `class`.

This is why, in React, many HTML and SVG attributes are written in camelCase. For example, instead of `stroke-width` you use `strokeWidth`. Since `class` is a reserved word, in React you write `className` instead, named after the [corresponding DOM property](https://developer.mozilla.org/en-US/docs/Web/API/Element/className):

```
<img 

  src="https://i.imgur.com/yXOvdOSs.jpg" 

  alt="Hedy Lamarr" 

  className="photo"

/>
```

You can [find all these attributes in the list of DOM component props.](/reference/react-dom/components/common) If you get one wrong, don’t worry—React will print a message with a possible correction to the [browser console.](https://developer.mozilla.org/docs/Tools/Browser_Console)

### Pitfall

For historical reasons, [`aria-*`](https://developer.mozilla.org/docs/Web/Accessibility/ARIA) and [`data-*`](https://developer.mozilla.org/docs/Learn/HTML/Howto/Use_data_attributes) attributes are written as in HTML with dashes.

### Pro-tip: Use a JSX Converter[](#pro-tip-use-a-jsx-converter "Link for Pro-tip: Use a JSX Converter ")

Converting all these attributes in existing markup can be tedious! We recommend using a [converter](https://transform.tools/html-to-jsx) to translate your existing HTML and SVG to JSX. Converters are very useful in practice, but it’s still worth understanding what is going on so that you can comfortably write JSX on your own.

Here is your final result:

```
export default function TodoList() {
  return (
    <>
      <h1>Hedy Lamarr's Todos</h1>
      <img 
        src="https://i.imgur.com/yXOvdOSs.jpg" 
        alt="Hedy Lamarr" 
        className="photo" 
      />
      <ul>
        <li>Invent new traffic lights</li>
        <li>Rehearse a movie scene</li>
        <li>Improve the spectrum technology</li>
      </ul>
    </>
  );
}
```

```
export default function Bio() {
  return (
    <div class="intro">
      <h1>Welcome to my website!</h1>
    </div>
    <p class="summary">
      You can find my thoughts here.
      <br><br>
      <b>And <i>pictures</b></i> of scientists!
    </p>
  );
}
```

Whether to do it by hand or using the converter is up to you!

[PreviousImporting and Exporting Components](/learn/importing-and-exporting-components)

[NextJavaScript in JSX with Curly Braces](/learn/javascript-in-jsx-with-curly-braces)

***

----
url: https://legacy.reactjs.org/blog/2015/08/03/new-react-devtools-beta.html
----

August 03, 2015 by [Jared Forsyth](https://twitter.com/jaredforsyth)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

We’ve made an entirely new version of the devtools, and we want you to try it out!

## [](#why-entirely-new)Why entirely new?

Perhaps the biggest reason was to create a defined API for dealing with internals, so that other tools could benefit as well and not have to depend on implementation details. This gives us more freedom to refactor things internally without worrying about breaking tooling.

The current version of the devtools is a fork of Blink’s “Elements” pane, and is imperative, mutation-driven, and tightly integrated with Chrome-specific APIs. The new devtools are much less coupled to Chrome, and easier to reason about thanks to React.

## [](#what-are-the-benefits)What are the benefits?

* 100% React
* Firefox compatible
* React Native compatible
* more extensible & hackable

## [](#are-there-any-new-features)Are there any new features?

Yeah!

### [](#the-tree-view)The Tree View

[](/static/e6fb2a1f2ea4b574edf85c8fc8c6f571/78958/devtools-tree-view.png)

* Much richer view of your props, including the contents of objects and arrays

* Custom components are emphasized, native components are de-emphasized

* Stateful components have a red collapser

* Improved keyboard navigation (hjkl or arrow keys)

* Selected component is available in the console as `$r`

* Props that change highlight in green

* Right-click menu

  * Scroll node into view
  * Show the source for a component in the “Sources” pane
  * Show the element in the “Elements” pane

### [](#searching)Searching

Select the search bar (or press ”/”), and start searching for a component by name.

### [](#the-side-pane)The Side Pane

* Now shows the `context` for a component
* Right-click to store a prop/state value as a global variable

## [](#how-do-i-install-it)How do I install it?

First, disable the Chrome web store version, or it will break things. Then [download the .crx](https://github.com/facebook/react-devtools/releases) and drag it into your `chrome://extensions` page. If it’s not working to drag it from the downloads bar, try opening your downloads folder and drag it from there.

Once we’ve determined that there aren’t any major regressions, we’ll update the official web store version, and everyone will be automatically upgraded.

### [](#also-firefox)Also Firefox!

We also have an initial version of the devtools for Firefox, which you can download from the same [release page](https://github.com/facebook/react-devtools/releases).

## [](#feedback-welcome)Feedback welcome

Let us know what issues you run into [on GitHub](https://github.com/facebook/react-devtools/issues), and check out [the README](https://github.com/facebook/react-devtools/tree/devtools-next) for more info.

## [](#update)Update

*August 12, 2015*

A second beta is out, with a number of bugfixes. It is also listed on the [releases page](https://github.com/facebook/react-devtools/releases).

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2015-08-03-new-react-devtools-beta.md)

----
url: https://react.dev/reference/react-dom/components/meta
----

[API Reference](/reference/react)

[Components](/reference/react-dom/components)

# \<meta>[](#undefined "Link for this heading")

The [built-in browser `<meta>` component](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta) lets you add metadata to the document.

```
<meta name="keywords" content="React, JavaScript, semantic markup, html" />
```

* [Reference](#reference)
  * [`<meta>`](#meta)

* [Usage](#usage)

  * [Annotating the document with metadata](#annotating-the-document-with-metadata)
  * [Annotating specific items within the document with metadata](#annotating-specific-items-within-the-document-with-metadata)

***

## Reference[](#reference "Link for Reference ")

### `<meta>`[](#meta "Link for this heading")

To add document metadata, render the [built-in browser `<meta>` component](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta). You can render `<meta>` from any component and React will always place the corresponding DOM element in the document head.

```
<meta name="keywords" content="React, JavaScript, semantic markup, html" />
```

[See more examples below.](#usage)

#### Props[](#props "Link for Props ")

`<meta>` supports all [common element props.](/reference/react-dom/components/common#common-props)

***

## Usage[](#usage "Link for Usage ")

### Annotating the document with metadata[](#annotating-the-document-with-metadata "Link for Annotating the document with metadata ")

You can annotate the document with metadata such as keywords, a summary, or the author’s name. React will place this metadata within the document `<head>` regardless of where in the React tree it is rendered.

```
<meta name="author" content="John Smith" />

<meta name="keywords" content="React, JavaScript, semantic markup, html" />

<meta name="description" content="API reference for the <meta> component in React DOM" />
```

You can render the `<meta>` component from any component. React will put a `<meta>` DOM node in the document `<head>`.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import ShowRenderedHTML from './ShowRenderedHTML.js';

export default function SiteMapPage() {
  return (
    <ShowRenderedHTML>
      <meta name="keywords" content="React" />
      <meta name="description" content="A site map for the React website" />
      <h1>Site Map</h1>
      <p>...</p>
    </ShowRenderedHTML>
  );
}
```

### Annotating specific items within the document with metadata[](#annotating-specific-items-within-the-document-with-metadata "Link for Annotating specific items within the document with metadata ")

You can use the `<meta>` component with the `itemProp` prop to annotate specific items within the document with metadata. In this case, React will *not* place these annotations within the document `<head>` but will place them like any other React component.

```
<section itemScope>

  <h3>Annotating specific items</h3>

  <meta itemProp="description" content="API reference for using <meta> with itemProp" />

  <p>...</p>

</section>
```

[Previous\<link>](/reference/react-dom/components/link)

[Next\<script>](/reference/react-dom/components/script)

***

----
url: https://legacy.reactjs.org/blog/2017/05/18/whats-new-in-create-react-app.html
----

May 18, 2017 by [Dan Abramov](https://twitter.com/dan_abramov)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

Less than a year ago, we introduced [Create React App](/blog/2016/07/22/create-apps-with-no-configuration.html) as an officially supported way to create apps with zero configuration. The project has since enjoyed tremendous growth, with over 950 commits by more than 250 contributors.

Today, we are excited to announce that many features that have been in the pipeline for the last few months are finally released.

As usual with Create React App, **you can enjoy these improvements in your existing non-ejected apps by updating a single dependency** and following our [migration instructions](https://github.com/facebookincubator/create-react-app/releases/tag/v1.0.0).

Newly created apps will get these improvements automatically.

### [](#webpack-2)webpack 2

> *This change was contributed by [@Timer](https://github.com/Timer) in [#1291](https://github.com/facebookincubator/create-react-app/pull/1291).*

We have upgraded to webpack 2 which has been [officially released](https://medium.com/webpack/webpack-2-and-beyond-40520af9067f) a few months ago. It is a big upgrade with many bugfixes and general improvements. We have been testing it for a while, and now consider it stable enough to recommend it to everyone.

While the Webpack configuration format has changed, Create React App users who didn’t eject don’t need to worry about it as we have updated the configuration on our side.

If you had to eject your app for one reason or another, Webpack provides a [configuration migration guide](https://webpack.js.org/guides/migrating/) that you can follow to update your apps. Note that with each release of Create React App, we are working to support more use cases out of the box so that you don’t have to eject in the future.

The biggest notable webpack 2 feature is the ability to write and import [ES6 modules](http://2ality.com/2014/09/es6-modules-final.html) directly without compiling them to CommonJS. This shouldn’t affect how you write code since you likely already use `import` and `export` statements, but it will help catch more mistakes like missing named exports at compile time:

In the future, as the ecosystem around ES6 modules matures, you can expect more improvements to your app’s bundle size thanks to [tree shaking](https://webpack.js.org/guides/tree-shaking/).

### [](#error-overlay) Runtime Error Overlay

> *This change was contributed by [@Timer](https://github.com/Timer) and [@nicinabox](https://github.com/nicinabox) in [#1101](https://github.com/facebookincubator/create-react-app/pull/1101), [@bvaughn](https://github.com/bvaughn) in [#2201](https://github.com/facebookincubator/create-react-app/pull/2201).*

Have you ever made a mistake in code and only realized it after the console is flooded with cryptic errors? Or worse, have you ever shipped an app with crashes in production because you accidentally missed an error in development?

To address these issues, we are introducing an overlay that pops up whenever there is an uncaught error in your application. It only appears in development, and you can dismiss it by pressing Escape.

A GIF is worth a thousand words:

(Yes, it integrates with your editor!)

In the future, we plan to teach the runtime error overlay to understand more about your React app. For example, after React 16 we plan to show React component stacks in addition to the JavaScript stacks when an error is thrown.

### [](#progressive-web-apps-by-default)Progressive Web Apps by Default

> *This change was contributed by [@jeffposnick](https://github.com/jeffposnick) in [#1728](https://github.com/facebookincubator/create-react-app/pull/1728).*

Newly created projects are built as [Progressive Web Apps](https://developers.google.com/web/progressive-web-apps/) by default. This means that they employ [service workers](https://developers.google.com/web/fundamentals/getting-started/primers/service-workers) with an [offline-first caching strategy](https://developers.google.com/web/fundamentals/instant-and-offline/offline-cookbook/#cache-falling-back-to-network) to minimize the time it takes to serve the app to the users who visit it again. You can opt out of this behavior, but we recommend it both for new and existing apps, especially if you target mobile devices.

[](/static/cff5fa9b92de804e655ea669a53d4d9c/d74fe/cra-pwa.png)

New apps automatically have these features, but you can easily convert an existing project to a Progressive Web App by following [our migration guide](https://github.com/facebookincubator/create-react-app/releases/tag/v1.0.0).

We will be adding [more documentation](https://github.com/facebookincubator/create-react-app/blob/main/packages/react-scripts/template/README.md#making-a-progressive-web-app) on this topic in the coming weeks. Please feel free to [ask any questions](https://github.com/facebookincubator/create-react-app/issues/new) on the issue tracker!

### [](#jest-20)Jest 20

> *This change was contributed by [@rogeliog](https://github.com/rogeliog) in [#1614](https://github.com/facebookincubator/create-react-app/pull/1614) and [@gaearon](https://github.com/gaearon) in [#2171](https://github.com/facebookincubator/create-react-app/pull/2171).*

We are now using the latest version of Jest that includes numerous bugfixes and improvements. You can read more about the changes in [Jest 19](https://facebook.github.io/jest/blog/2017/02/21/jest-19-immersive-watch-mode-test-platform-improvements.html) and [Jest 20](http://facebook.github.io/jest/blog/2017/05/06/jest-20-delightful-testing-multi-project-runner.html) blog posts.

Highlights include a new [immersive watch mode](https://facebook.github.io/jest/blog/2017/02/21/jest-19-immersive-watch-mode-test-platform-improvements.html#immersive-watch-mode), [a better snapshot format](https://facebook.github.io/jest/blog/2017/02/21/jest-19-immersive-watch-mode-test-platform-improvements.html#snapshot-updates), [improvements to printing skipped tests](https://facebook.github.io/jest/blog/2017/02/21/jest-19-immersive-watch-mode-test-platform-improvements.html#improved-printing-of-skipped-tests), and [new testing APIs](https://facebook.github.io/jest/blog/2017/05/06/jest-20-delightful-testing-multi-project-runner.html#new-improved-testing-apis).

Additionally, Create React App now support configuring a few Jest options related to coverage reporting.

### [](#code-splitting-with-dynamic-import)Code Splitting with Dynamic import()

> *This change was contributed by [@Timer](https://github.com/Timer) in [#1538](https://github.com/facebookincubator/create-react-app/pull/1538) and [@tharakawj](https://github.com/tharakawj) in [#1801](https://github.com/facebookincubator/create-react-app/pull/1801).*

It is important to keep the initial JavaScript payload of web apps down to the minimum, and [load the rest of the code on demand](https://medium.com/@addyosmani/progressive-web-apps-with-react-js-part-2-page-load-performance-33b932d97cf2). Although Create React App supported [code splitting](https://webpack.js.org/guides/code-splitting-async/) using `require.ensure()` since the first release, it used a webpack-specific syntax that did not work in Jest or other environments.

In this release, we are adding support for the [dynamic `import()` proposal](http://2ality.com/2017/01/import-operator.html#loading-code-on-demand) which aligns with the future web standards. Unlike `require.ensure()`, it doesn’t break Jest tests, and should eventually become a part of JavaScript. We encourage you to use `import()` to delay loading the code for non-critical component subtrees until you need to render them.

### [](#better-console-output)Better Console Output

> *This change was contributed by [@gaearon](https://github.com/gaearon) in [#2120](https://github.com/facebookincubator/create-react-app/pull/2120), [#2125](https://github.com/facebookincubator/create-react-app/pull/2125), and [#2161](https://github.com/facebookincubator/create-react-app/pull/2161).*

We have improved the console output across the board.

For example, when you start the development server, we now display the LAN address in additional to the localhost address so that you can quickly access the app from a mobile device on the same network:

[](/static/5d3b4caf2ae115ca4ab1f15e6e19680d/00d43/cra-better-output.png)

When lint errors are reported, we no longer show the warnings so that you can concentrate on more critical issues. Errors and warnings in the production build output are better formatted, and the build error overlay font size now matches the browser font size more closely.

### [](#but-wait-theres-more)But Wait… There’s More!

You can only fit so much in a blog post, but there are other long-requested features in this release, such as [environment-specific and local `.env` files](https://github.com/facebookincubator/create-react-app/pull/1344), [a lint rule against confusingly named globals](https://github.com/facebookincubator/create-react-app/pull/2130), [support for multiple proxies in development](https://github.com/facebookincubator/create-react-app/pull/1790), [a customizable browser launch script](https://github.com/facebookincubator/create-react-app/pull/1590), and many bugfixes.

You can read the full changelog and the migration guide in the [v1.0.0 release notes](https://github.com/facebookincubator/create-react-app/releases/tag/v1.0.0).

### [](#acknowledgements)Acknowledgements

This release is a result of months of work from many people in the React community. It is focused on improving both developer and end user experience, as we believe they are complementary and go hand in hand.

We are grateful to [everyone who has offered their contributions](https://github.com/facebookincubator/create-react-app/graphs/contributors), whether in code, documentation, or by helping other people. We would like to specifically thank [Joe Haddad](https://github.com/timer) for his invaluable help maintaining the project.

We are excited to bring these improvements to everybody using Create React App, and we are looking forward to more of your feedback and contributions.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2017-05-18-whats-new-in-create-react-app.md)

----
url: https://react.dev/reference/react/isValidElement
----

[API Reference](/reference/react)

[Legacy React APIs](/reference/react/legacy)

# isValidElement[](#undefined "Link for this heading")

`isValidElement` checks whether a value is a React element.

```
const isElement = isValidElement(value)
```

* [Reference](#reference)
  * [`isValidElement(value)`](#isvalidelement)
* [Usage](#usage)
  * [Checking if something is a React element](#checking-if-something-is-a-react-element)

***

## Reference[](#reference "Link for Reference ")

### `isValidElement(value)`[](#isvalidelement "Link for this heading")

Call `isValidElement(value)` to check whether `value` is a React element.

```
import { isValidElement, createElement } from 'react';



// ✅ React elements

console.log(isValidElement(<p />)); // true

console.log(isValidElement(createElement('p'))); // true



// ❌ Not React elements

console.log(isValidElement(25)); // false

console.log(isValidElement('Hello')); // false

console.log(isValidElement({ age: 42 })); // false
```

***

```
import { isValidElement, createElement } from 'react';



// ✅ JSX tags are React elements

console.log(isValidElement(<p />)); // true

console.log(isValidElement(<MyComponent />)); // true



// ✅ Values returned by createElement are React elements

console.log(isValidElement(createElement('p'))); // true

console.log(isValidElement(createElement(MyComponent))); // true
```

Any other values, such as strings, numbers, or arbitrary objects and arrays, are not React elements.

For them, `isValidElement` returns `false`:

```
// ❌ These are *not* React elements

console.log(isValidElement(null)); // false

console.log(isValidElement(25)); // false

console.log(isValidElement('Hello')); // false

console.log(isValidElement({ age: 42 })); // false

console.log(isValidElement([<div />, <div />])); // false

console.log(isValidElement(MyComponent)); // false
```

It is very uncommon to need `isValidElement`. It’s mostly useful if you’re calling another API that *only* accepts elements (like [`cloneElement`](/reference/react/cloneElement) does) and you want to avoid an error when your argument is not a React element.

Unless you have some very specific reason to add an `isValidElement` check, you probably don’t need it.

##### Deep Dive#### React elements vs React nodes[](#react-elements-vs-react-nodes "Link for React elements vs React nodes ")

When you write a component, you can return any kind of *React node* from it:

```
function MyComponent() {

  // ... you can return any React node ...

}
```

```
function MyComponent() {

  return 42; // It's ok to return a number from component

}
```

This is why you shouldn’t use `isValidElement` as a way to check whether something can be rendered.

[PreviousforwardRef](/reference/react/forwardRef)

[NextPureComponent](/reference/react/PureComponent)

***

----
url: https://react.dev/learn/keeping-components-pure
----

```
function double(number) {

  return 2 * number;

}
```

In the above example, `double` is a **pure function.** If you pass it `3`, it will return `6`. Always.

React is designed around this concept. **React assumes that every component you write is a pure function.** This means that React components you write must always return the same JSX given the same inputs:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
function Recipe({ drinkers }) {
  return (
    <ol>
      <li>Boil {drinkers} cups of water.</li>
      <li>Add {drinkers} spoons of tea and {0.5 * drinkers} spoons of spice.</li>
      <li>Add {0.5 * drinkers} cups of milk to boil and sugar to taste.</li>
    </ol>
  );
}

export default function App() {
  return (
    <section>
      <h1>Spiced Chai Recipe</h1>
      <h2>For two</h2>
      <Recipe drinkers={2} />
      <h2>For a gathering</h2>
      <Recipe drinkers={4} />
    </section>
  );
}
```

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
let guest = 0;

function Cup() {
  // Bad: changing a preexisting variable!
  guest = guest + 1;
  return <h2>Tea cup for guest #{guest}</h2>;
}

export default function TeaSet() {
  return (
    <>
      <Cup />
      <Cup />
      <Cup />
    </>
  );
}
```

This component is reading and writing a `guest` variable declared outside of it. This means that **calling this component multiple times will produce different JSX!** And what’s more, if *other* components read `guest`, they will produce different JSX, too, depending on when they were rendered! That’s not predictable.

Going back to our formula y = 2x, now even if x = 2, we cannot trust that y = 4. Our tests could fail, our users would be baffled, planes would fall out of the sky—you can see how this would lead to confusing bugs!

You can fix this component by [passing `guest` as a prop instead](/learn/passing-props-to-a-component):

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
function Cup({ guest }) {
  return <h2>Tea cup for guest #{guest}</h2>;
}

export default function TeaSet() {
  return (
    <>
      <Cup guest={1} />
      <Cup guest={2} />
      <Cup guest={3} />
    </>
  );
}
```

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
function Cup({ guest }) {
  return <h2>Tea cup for guest #{guest}</h2>;
}

export default function TeaGathering() {
  const cups = [];
  for (let i = 1; i <= 12; i++) {
    cups.push(<Cup key={i} guest={i} />);
  }
  return cups;
}
```

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
export default function Clock({ time }) {
  const hours = time.getHours();
  if (hours >= 0 && hours <= 6) {
    document.getElementById('time').className = 'night';
  } else {
    document.getElementById('time').className = 'day';
  }
  return (
    <h1 id="time">
      {time.toLocaleTimeString()}
    </h1>
  );
}
```

[PreviousRendering Lists](/learn/rendering-lists)

[NextYour UI as a Tree](/learn/understanding-your-ui-as-a-tree)

***

----
url: https://react.dev/reference/react-dom/hooks
----

[API Reference](/reference/react)

# Built-in React DOM Hooks[](#undefined "Link for this heading")

The `react-dom` package contains Hooks that are only supported for web applications (which run in the browser DOM environment). These Hooks are not supported in non-browser environments like iOS, Android, or Windows applications. If you are looking for Hooks that are supported in web browsers *and other environments* see [the React Hooks page](/reference/react/hooks). This page lists all the Hooks in the `react-dom` package.

***

## Form Hooks[](#form-hooks "Link for Form Hooks ")

*Forms* let you create interactive controls for submitting information. To manage forms in your components, use one of these Hooks:

* [`useFormStatus`](/reference/react-dom/hooks/useFormStatus) allows you to make updates to the UI based on the status of a form.

```
function Form({ action }) {

  async function increment(n) {

    return n + 1;

  }

  const [count, incrementFormAction] = useActionState(increment, 0);

  return (

    <form action={action}>

      <button formAction={incrementFormAction}>Count: {count}</button>

      <Button />

    </form>

  );

}



function Button() {

  const { pending } = useFormStatus();

  return (

    <button disabled={pending} type="submit">

      Submit

    </button>

  );

}
```

[NextuseFormStatus](/reference/react-dom/hooks/useFormStatus)

***

----
url: https://react.dev/reference/react/createRef
----

[API Reference](/reference/react)

[Legacy React APIs](/reference/react/legacy)

# createRef[](#undefined "Link for this heading")

### Pitfall

`createRef` is mostly used for [class components.](/reference/react/Component) Function components typically rely on [`useRef`](/reference/react/useRef) instead.

`createRef` creates a [ref](/learn/referencing-values-with-refs) object which can contain arbitrary value.

```
class MyInput extends Component {

  inputRef = createRef();

  // ...

}
```

* [Reference](#reference)
  * [`createRef()`](#createref)
* [Usage](#usage)
  * [Declaring a ref in a class component](#declaring-a-ref-in-a-class-component)
* [Alternatives](#alternatives)
  * [Migrating from a class with `createRef` to a function with `useRef`](#migrating-from-a-class-with-createref-to-a-function-with-useref)

***

## Reference[](#reference "Link for Reference ")

### `createRef()`[](#createref "Link for this heading")

Call `createRef` to declare a [ref](/learn/referencing-values-with-refs) inside a [class component.](/reference/react/Component)

```
import { createRef, Component } from 'react';



class MyComponent extends Component {

  intervalRef = createRef();

  inputRef = createRef();

  // ...
```

***

## Usage[](#usage "Link for Usage ")

### Declaring a ref in a class component[](#declaring-a-ref-in-a-class-component "Link for Declaring a ref in a class component ")

To declare a ref inside a [class component,](/reference/react/Component) call `createRef` and assign its result to a class field:

```
import { Component, createRef } from 'react';



class Form extends Component {

  inputRef = createRef();



  // ...

}
```

If you now pass `ref={this.inputRef}` to an `<input>` in your JSX, React will populate `this.inputRef.current` with the input DOM node. For example, here is how you make a button that focuses the input:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { Component, createRef } from 'react';

export default class Form extends Component {
  inputRef = createRef();

  handleClick = () => {
    this.inputRef.current.focus();
  }

  render() {
    return (
      <>
        <input ref={this.inputRef} />
        <button onClick={this.handleClick}>
          Focus the input
        </button>
      </>
    );
  }
}
```

### Pitfall

`createRef` is mostly used for [class components.](/reference/react/Component) Function components typically rely on [`useRef`](/reference/react/useRef) instead.

***

## Alternatives[](#alternatives "Link for Alternatives ")

### Migrating from a class with `createRef` to a function with `useRef`[](#migrating-from-a-class-with-createref-to-a-function-with-useref "Link for this heading")

We recommend using function components instead of [class components](/reference/react/Component) in new code. If you have some existing class components using `createRef`, here is how you can convert them. This is the original code:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { Component, createRef } from 'react';

export default class Form extends Component {
  inputRef = createRef();

  handleClick = () => {
    this.inputRef.current.focus();
  }

  render() {
    return (
      <>
        <input ref={this.inputRef} />
        <button onClick={this.handleClick}>
          Focus the input
        </button>
      </>
    );
  }
}
```

When you [convert this component from a class to a function,](/reference/react/Component#alternatives) replace calls to `createRef` with calls to [`useRef`:](/reference/react/useRef)

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useRef } from 'react';

export default function Form() {
  const inputRef = useRef(null);

  function handleClick() {
    inputRef.current.focus();
  }

  return (
    <>
      <input ref={inputRef} />
      <button onClick={handleClick}>
        Focus the input
      </button>
    </>
  );
}
```

[PreviouscreateElement](/reference/react/createElement)

[NextforwardRef](/reference/react/forwardRef)

***

----
url: https://react.dev/blog/2024/10/21/react-compiler-beta-release
----

[Blog](/blog)

# React Compiler Beta Release[](#undefined "Link for this heading")

October 21, 2024 by [Lauren Tan](https://twitter.com/potetotes).

***

### Note

### React Compiler is now stable\![](#react-compiler-is-now-in-rc "Link for React Compiler is now stable! ")

Please see the [stable release blog post](/blog/2025/10/07/react-compiler-1) for details.

The React team is excited to share new updates:

1. We’re publishing React Compiler Beta today, so that early adopters and library maintainers can try it and provide feedback.
2. We’re officially supporting React Compiler for apps on React 17+, through an optional `react-compiler-runtime` package.
3. We’re opening up public membership of the [React Compiler Working Group](https://github.com/reactwg/react-compiler) to prepare the community for gradual adoption of the compiler.

***

At [React Conf 2024](/blog/2024/05/22/react-conf-2024-recap), we announced the experimental release of React Compiler, a build-time tool that optimizes your React app through automatic memoization. [You can find an introduction to React Compiler here](/learn/react-compiler).

Since the first release, we’ve fixed numerous bugs reported by the React community, received several high quality bug fixes and contributions[1](#user-content-fn-1) to the compiler, made the compiler more resilient to the broad diversity of JavaScript patterns, and have continued to roll out the compiler more widely at Meta.

In this post, we want to share what’s next for React Compiler.

## Try React Compiler Beta today[](#try-react-compiler-beta-today "Link for Try React Compiler Beta today ")

At [React India 2024](https://www.youtube.com/watch?v=qd5yk2gxbtg), we shared an update on React Compiler. Today, we are excited to announce a new Beta release of React Compiler and ESLint plugin. New betas are published to npm using the `@beta` tag.

To install React Compiler Beta:

Terminal

```
npm install -D babel-plugin-react-compiler@beta eslint-plugin-react-compiler@beta
```

Or, if you’re using Yarn:

Terminal

```
yarn add -D babel-plugin-react-compiler@beta eslint-plugin-react-compiler@beta
```

You can watch [Sathya Gunasekaran’s](https://twitter.com/_gsathya) talk at React India here:

## We recommend everyone use the React Compiler linter today[](#we-recommend-everyone-use-the-react-compiler-linter-today "Link for We recommend everyone use the React Compiler linter today ")

React Compiler’s ESLint plugin helps developers proactively identify and correct [Rules of React](/reference/rules) violations. **We strongly recommend everyone use the linter today**. The linter does not require that you have the compiler installed, so you can use it independently, even if you are not ready to try out the compiler.

To install the linter only:

Terminal

```
npm install -D eslint-plugin-react-compiler@beta
```

Or, if you’re using Yarn:

Terminal

```
yarn add -D eslint-plugin-react-compiler@beta
```

After installation you can enable the linter by [adding it to your ESLint config](/learn/react-compiler/installation#eslint-integration). Using the linter helps identify Rules of React breakages, making it easier to adopt the compiler when it’s fully released.

## Backwards Compatibility[](#backwards-compatibility "Link for Backwards Compatibility ")

React Compiler produces code that depends on runtime APIs added in React 19, but we’ve since added support for the compiler to also work with React 17 and 18. If you are not on React 19 yet, in the Beta release you can now try out React Compiler by specifying a minimum `target` in your compiler config, and adding `react-compiler-runtime` as a dependency. [You can find docs on this here](/reference/react-compiler/configuration#react-17-18).

## Using React Compiler in libraries[](#using-react-compiler-in-libraries "Link for Using React Compiler in libraries ")

Our initial release was focused on identifying major issues with using the compiler in applications. We’ve gotten great feedback and have substantially improved the compiler since then. We’re now ready for broad feedback from the community, and for library authors to try out the compiler to improve performance and the developer experience of maintaining your library.

React Compiler can also be used to compile libraries. Because React Compiler needs to run on the original source code prior to any code transformations, it is not possible for an application’s build pipeline to compile the libraries they use. Hence, our recommendation is for library maintainers to independently compile and test their libraries with the compiler, and ship compiled code to npm.

Because your code is pre-compiled, users of your library will not need to have the compiler enabled in order to benefit from the automatic memoization applied to your library. If your library targets apps not yet on React 19, specify a minimum `target` and add `react-compiler-runtime` as a direct dependency. The runtime package will use the correct implementation of APIs depending on the application’s version, and polyfill the missing APIs if necessary.

[You can find more docs on this here.](/reference/react-compiler/compiling-libraries)

## Opening up React Compiler Working Group to everyone[](#opening-up-react-compiler-working-group-to-everyone "Link for Opening up React Compiler Working Group to everyone ")

We previously announced the invite-only [React Compiler Working Group](https://github.com/reactwg/react-compiler) at React Conf to provide feedback, ask questions, and collaborate on the compiler’s experimental release.

From today, together with the Beta release of React Compiler, we are opening up Working Group membership to everyone. The goal of the React Compiler Working Group is to prepare the ecosystem for a smooth, gradual adoption of React Compiler by existing applications and libraries. Please continue to file bug reports in the [React repo](https://github.com/facebook/react), but please leave feedback, ask questions, or share ideas in the [Working Group discussion forum](https://github.com/reactwg/react-compiler/discussions).

The core team will also use the discussions repo to share our research findings. As the Stable Release gets closer, any important information will also be posted on this forum.

## React Compiler at Meta[](#react-compiler-at-meta "Link for React Compiler at Meta ")

At [React Conf](/blog/2024/05/22/react-conf-2024-recap), we shared that our rollout of the compiler on Quest Store and Instagram were successful. Since then, we’ve deployed React Compiler across several more major web apps at Meta, including [Facebook](https://www.facebook.com) and [Threads](https://www.threads.net). That means if you’ve used any of these apps recently, you may have had your experience powered by the compiler. We were able to onboard these apps onto the compiler with few code changes required, in a monorepo with more than 100,000 React components.

We’ve seen notable performance improvements across all of these apps. As we’ve rolled out, we’re continuing to see results on the order of [the wins we shared previously at ReactConf](https://youtu.be/lyEKhv8-3n0?t=3223). These apps have already been heavily hand tuned and optimized by Meta engineers and React experts over the years, so even improvements on the order of a few percent are a huge win for us.

We also expected developer productivity wins from React Compiler. To measure this, we collaborated with our data science partners at Meta[2](#user-content-fn-2) to conduct a thorough statistical analysis of the impact of manual memoization on productivity. Before rolling out the compiler at Meta, we discovered that only about 8% of React pull requests used manual memoization and that these pull requests took 31-46% longer to author[3](#user-content-fn-3). This confirmed our intuition that manual memoization introduces cognitive overhead, and we anticipate that React Compiler will lead to more efficient code authoring and review. Notably, React Compiler also ensures that *all* code is memoized by default, not just the (in our case) 8% where developers explicitly apply memoization.

## Roadmap to Stable[](#roadmap-to-stable "Link for Roadmap to Stable ")

*This is not a final roadmap, and is subject to change.*

We intend to ship a Release Candidate of the compiler in the near future following the Beta release, when the majority of apps and libraries that follow the Rules of React have been proven to work well with the compiler. After a period of final feedback from the community, we plan on a Stable Release for the compiler. The Stable Release will mark the beginning of a new foundation for React, and all apps and libraries will be strongly recommended to use the compiler and ESLint plugin.

* ✅ Experimental: Released at React Conf 2024, primarily for feedback from early adopters.
* ✅ Public Beta: Available today, for feedback from the wider community.
* 🚧 Release Candidate (RC): React Compiler works for the majority of rule-following apps and libraries without issue.
* 🚧 General Availability: After final feedback period from the community.

These releases also include the compiler’s ESLint plugin, which surfaces diagnostics statically analyzed by the compiler. We plan to combine the existing eslint-plugin-react-hooks plugin with the compiler’s ESLint plugin, so only one plugin needs to be installed.

Post-Stable, we plan to add more compiler optimizations and improvements. This includes both continual improvements to automatic memoization, and new optimizations altogether, with minimal to no change of product code. Upgrading to each new release of the compiler is aimed to be straightforward, and each upgrade will continue to improve performance and add better handling of diverse JavaScript and React patterns.

Throughout this process, we also plan to prototype an IDE extension for React. It is still very early in research, so we expect to be able to share more of our findings with you in a future React Labs blog post.

***

Thanks to [Sathya Gunasekaran](https://twitter.com/_gsathya), [Joe Savona](https://twitter.com/en_JS), [Ricky Hanlon](https://twitter.com/rickhanlonii), [Alex Taylor](https://github.com/alexmckenley), [Jason Bonta](https://twitter.com/someextent), and [Eli White](https://twitter.com/Eli_White) for reviewing and editing this post.

***

## Footnotes[](#footnote-label "Link for Footnotes")

1. Thanks [@nikeee](https://github.com/facebook/react/pulls?q=is%3Apr+author%3Anikeee), [@henryqdineen](https://github.com/facebook/react/pulls?q=is%3Apr+author%3Ahenryqdineen), [@TrickyPi](https://github.com/facebook/react/pulls?q=is%3Apr+author%3ATrickyPi), and several others for their contributions to the compiler. [↩](#user-content-fnref-1)

2. Thanks [Vaishali Garg](https://www.linkedin.com/in/vaishaligarg09) for leading this study on React Compiler at Meta, and for reviewing this post. [↩](#user-content-fnref-2)

3. After controlling on author tenure, diff length/complexity, and other potential confounding factors. [↩](#user-content-fnref-3)

[PreviousReact 19](/blog/2024/12/05/react-19)

[NextReact Conf 2024 Recap](/blog/2024/05/22/react-conf-2024-recap)

***

----
url: https://react.dev/reference/react/useDeferredValue
----

[API Reference](/reference/react)

[Hooks](/reference/react/hooks)

# useDeferredValue[](#undefined "Link for this heading")

`useDeferredValue` is a React Hook that lets you defer updating a part of the UI.

```
const deferredValue = useDeferredValue(value)
```

* [Reference](#reference)
  * [`useDeferredValue(value, initialValue?)`](#usedeferredvalue)

* [Usage](#usage)

  * [Showing stale content while fresh content is loading](#showing-stale-content-while-fresh-content-is-loading)
  * [Indicating that the content is stale](#indicating-that-the-content-is-stale)
  * [Deferring re-rendering for a part of the UI](#deferring-re-rendering-for-a-part-of-the-ui)

***

## Reference[](#reference "Link for Reference ")

### `useDeferredValue(value, initialValue?)`[](#usedeferredvalue "Link for this heading")

Call `useDeferredValue` at the top level of your component to get a deferred version of that value.

```
import { useState, useDeferredValue } from 'react';



function SearchPage() {

  const [query, setQuery] = useState('');

  const deferredQuery = useDeferredValue(query);

  // ...

}
```

[See more examples below.](#usage)

#### Parameters[](#parameters "Link for Parameters ")

* `value`: The value you want to defer. It can have any type.
* **optional** `initialValue`: A value to use during the initial render of a component. If this option is omitted, `useDeferredValue` will not defer during the initial render, because there’s no previous version of `value` that it can render instead.

#### Returns[](#returns "Link for Returns ")

* `currentValue`: During the initial render, the returned deferred value will be the `initialValue`, or the same as the value you provided. During updates, React will first attempt a re-render with the old value (so it will return the old value), and then try another re-render in the background with the new value (so it will return the updated value).

***

## Usage[](#usage "Link for Usage ")

### Showing stale content while fresh content is loading[](#showing-stale-content-while-fresh-content-is-loading "Link for Showing stale content while fresh content is loading ")

Call `useDeferredValue` at the top level of your component to defer updating some part of your UI.

```
import { useState, useDeferredValue } from 'react';



function SearchPage() {

  const [query, setQuery] = useState('');

  const deferredQuery = useDeferredValue(query);

  // ...

}
```

During the initial render, the deferred value will be the same as the value you provided.

During updates, the deferred value will “lag behind” the latest value. In particular, React will first re-render *without* updating the deferred value, and then try to re-render with the newly received value in the background.

**Let’s walk through an example to see when this is useful.**

### Note

This example assumes you use a Suspense-enabled data source:

* Data fetching with Suspense-enabled frameworks like [Relay](https://relay.dev/docs/guided-tour/rendering/loading-states/) and [Next.js](https://nextjs.org/docs/app/getting-started/fetching-data#with-suspense)
* Lazy-loading component code with [`lazy`](/reference/react/lazy)
* Reading the value of a Promise with [`use`](/reference/react/use)

[Learn more about Suspense and its limitations.](/reference/react/Suspense)

In this example, the `SearchResults` component [suspends](/reference/react/Suspense#displaying-a-fallback-while-content-is-loading) while fetching the search results. Try typing `"a"`, waiting for the results, and then editing it to `"ab"`. The results for `"a"` get replaced by the loading fallback.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { Suspense, useState } from 'react';
import SearchResults from './SearchResults.js';

export default function App() {
  const [query, setQuery] = useState('');
  return (
    <>
      <label>
        Search albums:
        <input value={query} onChange={e => setQuery(e.target.value)} />
      </label>
      <Suspense fallback={<h2>Loading...</h2>}>
        <SearchResults query={query} />
      </Suspense>
    </>
  );
}
```

A common alternative UI pattern is to *defer* updating the list of results and to keep showing the previous results until the new results are ready. Call `useDeferredValue` to pass a deferred version of the query down:

```
export default function App() {

  const [query, setQuery] = useState('');

  const deferredQuery = useDeferredValue(query);

  return (

    <>

      <label>

        Search albums:

        <input value={query} onChange={e => setQuery(e.target.value)} />

      </label>

      <Suspense fallback={<h2>Loading...</h2>}>

        <SearchResults query={deferredQuery} />

      </Suspense>

    </>

  );

}
```

The `query` will update immediately, so the input will display the new value. However, the `deferredQuery` will keep its previous value until the data has loaded, so `SearchResults` will show the stale results for a bit.

Enter `"a"` in the example below, wait for the results to load, and then edit the input to `"ab"`. Notice how instead of the Suspense fallback, you now see the stale result list until the new results have loaded:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { Suspense, useState, useDeferredValue } from 'react';
import SearchResults from './SearchResults.js';

export default function App() {
  const [query, setQuery] = useState('');
  const deferredQuery = useDeferredValue(query);
  return (
    <>
      <label>
        Search albums:
        <input value={query} onChange={e => setQuery(e.target.value)} />
      </label>
      <Suspense fallback={<h2>Loading...</h2>}>
        <SearchResults query={deferredQuery} />
      </Suspense>
    </>
  );
}
```

##### Deep Dive#### How does deferring a value work under the hood?[](#how-does-deferring-a-value-work-under-the-hood "Link for How does deferring a value work under the hood? ")

You can think of it as happening in two steps:

1. **First, React re-renders with the new `query` (`"ab"`) but with the old `deferredQuery` (still `"a"`).** The `deferredQuery` value, which you pass to the result list, is *deferred:* it “lags behind” the `query` value.

2. **In the background, React tries to re-render with *both* `query` and `deferredQuery` updated to `"ab"`.** If this re-render completes, React will show it on the screen. However, if it suspends (the results for `"ab"` have not loaded yet), React will abandon this rendering attempt, and retry this re-render again after the data has loaded. The user will keep seeing the stale deferred value until the data is ready.

The deferred “background” rendering is interruptible. For example, if you type into the input again, React will abandon it and restart with the new value. React will always use the latest provided value.

Note that there is still a network request per each keystroke. What’s being deferred here is displaying results (until they’re ready), not the network requests themselves. Even if the user continues typing, responses for each keystroke get cached, so pressing Backspace is instant and doesn’t fetch again.

***

### Indicating that the content is stale[](#indicating-that-the-content-is-stale "Link for Indicating that the content is stale ")

In the example above, there is no indication that the result list for the latest query is still loading. This can be confusing to the user if the new results take a while to load. To make it more obvious to the user that the result list does not match the latest query, you can add a visual indication when the stale result list is displayed:

```
<div style={{

  opacity: query !== deferredQuery ? 0.5 : 1,

}}>

  <SearchResults query={deferredQuery} />

</div>
```

With this change, as soon as you start typing, the stale result list gets slightly dimmed until the new result list loads. You can also add a CSS transition to delay dimming so that it feels gradual, like in the example below:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { Suspense, useState, useDeferredValue } from 'react';
import SearchResults from './SearchResults.js';

export default function App() {
  const [query, setQuery] = useState('');
  const deferredQuery = useDeferredValue(query);
  const isStale = query !== deferredQuery;
  return (
    <>
      <label>
        Search albums:
        <input value={query} onChange={e => setQuery(e.target.value)} />
      </label>
      <Suspense fallback={<h2>Loading...</h2>}>
        <div style={{
          opacity: isStale ? 0.5 : 1,
          transition: isStale ? 'opacity 0.2s 0.2s linear' : 'opacity 0s 0s linear'
        }}>
          <SearchResults query={deferredQuery} />
        </div>
      </Suspense>
    </>
  );
}
```

***

### Deferring re-rendering for a part of the UI[](#deferring-re-rendering-for-a-part-of-the-ui "Link for Deferring re-rendering for a part of the UI ")

You can also apply `useDeferredValue` as a performance optimization. It is useful when a part of your UI is slow to re-render, there’s no easy way to optimize it, and you want to prevent it from blocking the rest of the UI.

Imagine you have a text field and a component (like a chart or a long list) that re-renders on every keystroke:

```
function App() {

  const [text, setText] = useState('');

  return (

    <>

      <input value={text} onChange={e => setText(e.target.value)} />

      <SlowList text={text} />

    </>

  );

}
```

First, optimize `SlowList` to skip re-rendering when its props are the same. To do this, [wrap it in `memo`:](/reference/react/memo#skipping-re-rendering-when-props-are-unchanged)

```
const SlowList = memo(function SlowList({ text }) {

  // ...

});
```

However, this only helps if the `SlowList` props are *the same* as during the previous render. The problem you’re facing now is that it’s slow when they’re *different,* and when you actually need to show different visual output.

Concretely, the main performance problem is that whenever you type into the input, the `SlowList` receives new props, and re-rendering its entire tree makes the typing feel janky. In this case, `useDeferredValue` lets you prioritize updating the input (which must be fast) over updating the result list (which is allowed to be slower):

```
function App() {

  const [text, setText] = useState('');

  const deferredText = useDeferredValue(text);

  return (

    <>

      <input value={text} onChange={e => setText(e.target.value)} />

      <SlowList text={deferredText} />

    </>

  );

}
```

This does not make re-rendering of the `SlowList` faster. However, it tells React that re-rendering the list can be deprioritized so that it doesn’t block the keystrokes. The list will “lag behind” the input and then “catch up”. Like before, React will attempt to update the list as soon as possible, but will not block the user from typing.

#### The difference between useDeferredValue and unoptimized re-rendering[](#examples "Link for The difference between useDeferredValue and unoptimized re-rendering")

#### Example 1 of 2:Deferred re-rendering of the list[](#deferred-re-rendering-of-the-list "Link for this heading")

In this example, each item in the `SlowList` component is **artificially slowed down** so that you can see how `useDeferredValue` lets you keep the input responsive. Type into the input and notice that typing feels snappy while the list “lags behind” it.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useDeferredValue } from 'react';
import SlowList from './SlowList.js';

export default function App() {
  const [text, setText] = useState('');
  const deferredText = useDeferredValue(text);
  return (
    <>
      <input value={text} onChange={e => setText(e.target.value)} />
      <SlowList text={deferredText} />
    </>
  );
}
```

***

----
url: https://react.dev/blog/2023/05/03/react-canaries
----

[Blog](/blog)

# React Canaries: Enabling Incremental Feature Rollout Outside Meta[](#undefined "Link for this heading")

May 3, 2023 by [Dan Abramov](https://bsky.app/profile/danabra.mov), [Sophie Alpert](https://twitter.com/sophiebits), [Rick Hanlon](https://twitter.com/rickhanlonii), [Sebastian Markbåge](https://twitter.com/sebmarkbage), and [Andrew Clark](https://twitter.com/acdlite)

***

We’d like to offer the React community an option to adopt individual new features as soon as their design is close to final, before they’re released in a stable version—similar to how Meta has long used bleeding-edge versions of React internally. We are introducing a new officially supported [Canary release channel](/community/versioning-policy#canary-channel). It lets curated setups like frameworks decouple adoption of individual React features from the React release schedule.

***

## tl;dr[](#tldr "Link for tl;dr ")

* We’re introducing an officially supported [Canary release channel](/community/versioning-policy#canary-channel) for React. Since it’s officially supported, if any regressions land, we’ll treat them with a similar urgency to bugs in stable releases.
* Canaries let you start using individual new React features before they land in the semver-stable releases.
* Unlike the [Experimental](/community/versioning-policy#experimental-channel) channel, React Canaries only include features that we reasonably believe to be ready for adoption. We encourage frameworks to consider bundling pinned Canary React releases.
* We will announce breaking changes and new features on our blog as they land in Canary releases.
* **As always, React continues to follow semver for every Stable release.**

## How React features are usually developed[](#how-react-features-are-usually-developed "Link for How React features are usually developed ")

Typically, every React feature has gone through the same stages:

1. We develop an initial version and prefix it with `experimental_` or `unstable_`. The feature is only available in the `experimental` release channel. At this point, the feature is expected to change significantly.
2. We find a team at Meta willing to help us test this feature and provide feedback on it. This leads to a round of changes. As the feature becomes more stable, we work with more teams at Meta to try it out.
3. Eventually, we feel confident in the design. We remove the prefix from the API name, and make the feature available on the `main` branch by default, which most Meta products use. At this point, any team at Meta can use this feature.
4. As we build confidence in the direction, we also post an RFC for the new feature. At this point we know the design works for a broad set of cases, but we might make some last minute adjustments.
5. When we are close to cutting an open source release, we write documentation for the feature and finally release the feature in a stable React release.

This playbook works well for most features we’ve released so far. However, there can be a significant gap between when the feature is generally ready to use (step 3) and when it is released in open source (step 5).

**We’d like to offer the React community an option to follow the same approach as Meta, and adopt individual new features earlier (as they become available) without having to wait for the next release cycle of React.**

As always, all React features will eventually make it into a Stable release.

## Can we just do more minor releases?[](#can-we-just-do-more-minor-releases "Link for Can we just do more minor releases? ")

Generally, we *do* use minor releases for introducing new features.

However, this isn’t always possible. Sometimes, new features are interconnected with *other* new features which have not yet been fully completed and that we’re still actively iterating on. We can’t release them separately because their implementations are related. We can’t version them separately because they affect the same packages (for example, `react` and `react-dom`). And we need to keep the ability to iterate on the pieces that aren’t ready without a flurry of major version releases, which semver would require us to do.

At Meta, we’ve solved this problem by building React from the `main` branch, and manually updating it to a specific pinned commit every week. This is also the approach that React Native releases have been following for the last several years. Every *stable* release of React Native is pinned to a specific commit from the `main` branch of the React repository. This lets React Native include important bugfixes and incrementally adopt new React features at the framework level without getting coupled to the global React release schedule.

We would like to make this workflow available to other frameworks and curated setups. For example, it lets a framework *on top of* React include a React-related breaking change *before* this breaking change gets included into a stable React release. This is particularly useful because some breaking changes only affect framework integrations. This lets a framework release such a change in its own minor version without breaking semver.

Rolling releases with the Canaries channel will allow us to have a tighter feedback loop and ensure that new features get comprehensive testing in the community. This workflow is closer to how TC39, the JavaScript standards committee, [handles changes in numbered stages](https://tc39.es/process-document/). New React features may be available in frameworks built on React before they are in a React stable release, just as new JavaScript features ship in browsers before they are officially ratified as part of the specification.

## Why not use experimental releases instead?[](#why-not-use-experimental-releases-instead "Link for Why not use experimental releases instead? ")

Although you *can* technically use [Experimental releases](/community/versioning-policy#canary-channel), we recommend against using them in production because experimental APIs can undergo significant breaking changes on their way to stabilization (or can even be removed entirely). While Canaries can also contain mistakes (as with any release), going forward we plan to announce any significant breaking changes in Canaries on our blog. Canaries are the closest to the code Meta runs internally, so you can generally expect them to be relatively stable. However, you *do* need to keep the version pinned and manually scan the GitHub commit log when updating between the pinned commits.

**We expect that most people using React outside a curated setup (like a framework) will want to continue using the Stable releases.** However, if you’re building a framework, you might want to consider bundling a Canary version of React pinned to a particular commit, and update it at your own pace. The benefit of that is that it lets you ship individual completed React features and bugfixes earlier for your users and at your own release schedule, similar to how React Native has been doing it for the last few years. The downside is that you would take on additional responsibility to review which React commits are being pulled in and communicate to your users which React changes are included with your releases.

If you’re a framework author and want to try this approach, please get in touch with us.

## Announcing breaking changes and new features early[](#announcing-breaking-changes-and-new-features-early "Link for Announcing breaking changes and new features early ")

Canary releases represent our best guess of what will go into the next stable React release at any given time.

Traditionally, we’ve only announced breaking changes at the *end* of the release cycle (when doing a major release). Now that Canary releases are an officially supported way to consume React, we plan to shift towards announcing breaking changes and significant new features *as they land* in Canaries. For example, if we merge a breaking change that will go out in a Canary, we will write a post about it on the React blog, including codemods and migration instructions if necessary. Then, if you’re a framework author cutting a major release that updates the pinned React canary to include that change, you can link to our blog post from your release notes. Finally, when a stable major version of React is ready, we will link to those already published blog posts, which we hope will help our team make progress faster.

We plan to document APIs as they land in Canaries—even if these APIs are not yet available outside of them. APIs that are only available in Canaries will be marked with a special note on the corresponding pages. This will include APIs like [`use`](https://github.com/reactjs/rfcs/pull/229), and some others (like `cache` and `createServerContext`) which we’ll send RFCs for.

## Canaries must be pinned[](#canaries-must-be-pinned "Link for Canaries must be pinned ")

If you decide to adopt the Canary workflow for your app or framework, make sure you always pin the *exact* version of the Canary you’re using. Since Canaries are pre-releases, they may still include breaking changes.

## Example: React Server Components[](#example-react-server-components "Link for Example: React Server Components ")

As we [announced in March](/blog/2023/03/22/react-labs-what-we-have-been-working-on-march-2023#react-server-components), the React Server Components conventions have been finalized, and we do not expect significant breaking changes related to their user-facing API contract. However, we can’t release support for React Server Components in a stable version of React yet because we are still working on several intertwined framework-only features (such as [asset loading](/blog/2023/03/22/react-labs-what-we-have-been-working-on-march-2023#asset-loading)) and expect more breaking changes there.

This means that React Server Components are ready to be adopted by frameworks. However, until the next major React release, the only way for a framework to adopt them is to ship a pinned Canary version of React. (To avoid bundling two copies of React, frameworks that wish to do this would need to enforce resolution of `react` and `react-dom` to the pinned Canary they ship with their framework, and explain that to their users. As an example, this is what Next.js App Router does.)

## Testing libraries against both Stable and Canary versions[](#testing-libraries-against-both-stable-and-canary-versions "Link for Testing libraries against both Stable and Canary versions ")

We do not expect library authors to test every single Canary release since it would be prohibitively difficult. However, just as when we [originally introduced the different React pre-release channels three years ago](https://legacy.reactjs.org/blog/2019/10/22/react-release-channels.html), we encourage libraries to run tests against *both* the latest Stable and latest Canary versions. If you see a change in behavior that wasn’t announced, please file a bug in the React repository so that we can help diagnose it. We expect that as this practice becomes widely adopted, it will reduce the amount of effort necessary to upgrade libraries to new major versions of React, since accidental regressions would be found as they land.

### Note

Strictly speaking, Canary is not a *new* release channel—it used to be called Next. However, we’ve decided to rename it to avoid confusion with Next.js. We’re announcing it as a *new* release channel to communicate the new expectations, such as Canaries being an officially supported way to use React.

## Stable releases work like before[](#stable-releases-work-like-before "Link for Stable releases work like before ")

We are not introducing any changes to stable React releases.

[PreviousReact Labs: What We've Been Working On – February 2024](/blog/2024/02/15/react-labs-what-we-have-been-working-on-february-2024)

[NextReact Labs: What We've Been Working On – March 2023](/blog/2023/03/22/react-labs-what-we-have-been-working-on-march-2023)

***

----
url: https://react.dev/learn/preserving-and-resetting-state
----

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function App() {
  const counter = <Counter />;
  return (
    <div>
      {counter}
      {counter}
    </div>
  );
}

function Counter() {
  const [score, setScore] = useState(0);
  const [hover, setHover] = useState(false);

  let className = 'counter';
  if (hover) {
    className += ' hover';
  }

  return (
    <div
      className={className}
      onPointerEnter={() => setHover(true)}
      onPointerLeave={() => setHover(false)}
    >
      <h1>{score}</h1>
      <button onClick={() => setScore(score + 1)}>
        Add one
      </button>
    </div>
  );
}
```

Here’s how these look as a tree:

React tree

**These are two separate counters because each is rendered at its own position in the tree.** You don’t usually have to think about these positions to use React, but it can be useful to understand how it works.

In React, each component on the screen has fully isolated state. For example, if you render two `Counter` components side by side, each of them will get its own, independent, `score` and `hover` states.

Try clicking both counters and notice they don’t affect each other:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function App() {
  return (
    <div>
      <Counter />
      <Counter />
    </div>
  );
}

function Counter() {
  const [score, setScore] = useState(0);
  const [hover, setHover] = useState(false);

  let className = 'counter';
  if (hover) {
    className += ' hover';
  }

  return (
    <div
      className={className}
      onPointerEnter={() => setHover(true)}
      onPointerLeave={() => setHover(false)}
    >
      <h1>{score}</h1>
      <button onClick={() => setScore(score + 1)}>
        Add one
      </button>
    </div>
  );
}
```

As you can see, when one counter is updated, only the state for that component is updated:

Updating state

React will keep the state around for as long as you render the same component at the same position in the tree. To see this, increment both counters, then remove the second component by unchecking “Render the second counter” checkbox, and then add it back by ticking it again:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function App() {
  const [showB, setShowB] = useState(true);
  return (
    <div>
      <Counter />
      {showB && <Counter />}
      <label>
        <input
          type="checkbox"
          checked={showB}
          onChange={e => {
            setShowB(e.target.checked)
          }}
        />
        Render the second counter
      </label>
    </div>
  );
}

function Counter() {
  const [score, setScore] = useState(0);
  const [hover, setHover] = useState(false);

  let className = 'counter';
  if (hover) {
    className += ' hover';
  }

  return (
    <div
      className={className}
      onPointerEnter={() => setHover(true)}
      onPointerLeave={() => setHover(false)}
    >
      <h1>{score}</h1>
      <button onClick={() => setScore(score + 1)}>
        Add one
      </button>
    </div>
  );
}
```

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function App() {
  const [isFancy, setIsFancy] = useState(false);
  return (
    <div>
      {isFancy ? (
        <Counter isFancy={true} />
      ) : (
        <Counter isFancy={false} />
      )}
      <label>
        <input
          type="checkbox"
          checked={isFancy}
          onChange={e => {
            setIsFancy(e.target.checked)
          }}
        />
        Use fancy styling
      </label>
    </div>
  );
}

function Counter({ isFancy }) {
  const [score, setScore] = useState(0);
  const [hover, setHover] = useState(false);

  let className = 'counter';
  if (hover) {
    className += ' hover';
  }
  if (isFancy) {
    className += ' fancy';
  }

  return (
    <div
      className={className}
      onPointerEnter={() => setHover(true)}
      onPointerLeave={() => setHover(false)}
    >
      <h1>{score}</h1>
      <button onClick={() => setScore(score + 1)}>
        Add one
      </button>
    </div>
  );
}
```

When you tick or clear the checkbox, the counter state does not get reset. Whether `isFancy` is `true` or `false`, you always have a `<Counter />` as the first child of the `div` returned from the root `App` component:

Updating the `App` state does not reset the `Counter` because `Counter` stays in the same position

It’s the same component at the same position, so from React’s perspective, it’s the same counter.

### Pitfall

Remember that **it’s the position in the UI tree—not in the JSX markup—that matters to React!** This component has two `return` clauses with different `<Counter />` JSX tags inside and outside the `if`:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function App() {
  const [isFancy, setIsFancy] = useState(false);
  if (isFancy) {
    return (
      <div>
        <Counter isFancy={true} />
        <label>
          <input
            type="checkbox"
            checked={isFancy}
            onChange={e => {
              setIsFancy(e.target.checked)
            }}
          />
          Use fancy styling
        </label>
      </div>
    );
  }
  return (
    <div>
      <Counter isFancy={false} />
      <label>
        <input
          type="checkbox"
          checked={isFancy}
          onChange={e => {
            setIsFancy(e.target.checked)
          }}
        />
        Use fancy styling
      </label>
    </div>
  );
}

function Counter({ isFancy }) {
  const [score, setScore] = useState(0);
  const [hover, setHover] = useState(false);

  let className = 'counter';
  if (hover) {
    className += ' hover';
  }
  if (isFancy) {
    className += ' fancy';
  }

  return (
    <div
      className={className}
      onPointerEnter={() => setHover(true)}
      onPointerLeave={() => setHover(false)}
    >
      <h1>{score}</h1>
      <button onClick={() => setScore(score + 1)}>
        Add one
      </button>
    </div>
  );
}
```

You might expect the state to reset when you tick checkbox, but it doesn’t! This is because **both of these `<Counter />` tags are rendered at the same position.** React doesn’t know where you place the conditions in your function. All it “sees” is the tree you return.

In both cases, the `App` component returns a `<div>` with `<Counter />` as a first child. To React, these two counters have the same “address”: the first child of the first child of the root. This is how React matches them up between the previous and next renders, regardless of how you structure your logic.

## Different components at the same position reset state[](#different-components-at-the-same-position-reset-state "Link for Different components at the same position reset state ")

In this example, ticking the checkbox will replace `<Counter>` with a `<p>`:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function App() {
  const [isPaused, setIsPaused] = useState(false);
  return (
    <div>
      {isPaused ? (
        <p>See you later!</p>
      ) : (
        <Counter />
      )}
      <label>
        <input
          type="checkbox"
          checked={isPaused}
          onChange={e => {
            setIsPaused(e.target.checked)
          }}
        />
        Take a break
      </label>
    </div>
  );
}

function Counter() {
  const [score, setScore] = useState(0);
  const [hover, setHover] = useState(false);

  let className = 'counter';
  if (hover) {
    className += ' hover';
  }

  return (
    <div
      className={className}
      onPointerEnter={() => setHover(true)}
      onPointerLeave={() => setHover(false)}
    >
      <h1>{score}</h1>
      <button onClick={() => setScore(score + 1)}>
        Add one
      </button>
    </div>
  );
}
```

Here, you switch between *different* component types at the same position. Initially, the first child of the `<div>` contained a `Counter`. But when you swapped in a `p`, React removed the `Counter` from the UI tree and destroyed its state.

When `Counter` changes to `p`, the `Counter` is deleted and the `p` is added

When switching back, the `p` is deleted and the `Counter` is added

Also, **when you render a different component in the same position, it resets the state of its entire subtree.** To see how this works, increment the counter and then tick the checkbox:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function App() {
  const [isFancy, setIsFancy] = useState(false);
  return (
    <div>
      {isFancy ? (
        <div>
          <Counter isFancy={true} />
        </div>
      ) : (
        <section>
          <Counter isFancy={false} />
        </section>
      )}
      <label>
        <input
          type="checkbox"
          checked={isFancy}
          onChange={e => {
            setIsFancy(e.target.checked)
          }}
        />
        Use fancy styling
      </label>
    </div>
  );
}

function Counter({ isFancy }) {
  const [score, setScore] = useState(0);
  const [hover, setHover] = useState(false);

  let className = 'counter';
  if (hover) {
    className += ' hover';
  }
  if (isFancy) {
    className += ' fancy';
  }

  return (
    <div
      className={className}
      onPointerEnter={() => setHover(true)}
      onPointerLeave={() => setHover(false)}
    >
      <h1>{score}</h1>
      <button onClick={() => setScore(score + 1)}>
        Add one
      </button>
    </div>
  );
}
```

The counter state gets reset when you click the checkbox. Although you render a `Counter`, the first child of the `div` changes from a `section` to a `div`. When the child `section` was removed from the DOM, the whole tree below it (including the `Counter` and its state) was destroyed as well.

When `section` changes to `div`, the `section` is deleted and the new `div` is added

When switching back, the `div` is deleted and the new `section` is added

As a rule of thumb, **if you want to preserve the state between re-renders, the structure of your tree needs to “match up”** from one render to another. If the structure is different, the state gets destroyed because React destroys state when it removes a component from the tree.

### Pitfall

This is why you should not nest component function definitions.

Here, the `MyTextField` component function is defined *inside* `MyComponent`:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function MyComponent() {
  const [counter, setCounter] = useState(0);

  function MyTextField() {
    const [text, setText] = useState('');

    return (
      <input
        value={text}
        onChange={e => setText(e.target.value)}
      />
    );
  }

  return (
    <>
      <MyTextField />
      <button onClick={() => {
        setCounter(counter + 1)
      }}>Clicked {counter} times</button>
    </>
  );
}
```

Every time you click the button, the input state disappears! This is because a *different* `MyTextField` function is created for every render of `MyComponent`. You’re rendering a *different* component in the same position, so React resets all state below. This leads to bugs and performance problems. To avoid this problem, **always declare component functions at the top level, and don’t nest their definitions.**

## Resetting state at the same position[](#resetting-state-at-the-same-position "Link for Resetting state at the same position ")

By default, React preserves state of a component while it stays at the same position. Usually, this is exactly what you want, so it makes sense as the default behavior. But sometimes, you may want to reset a component’s state. Consider this app that lets two players keep track of their scores during each turn:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function Scoreboard() {
  const [isPlayerA, setIsPlayerA] = useState(true);
  return (
    <div>
      {isPlayerA ? (
        <Counter person="Taylor" />
      ) : (
        <Counter person="Sarah" />
      )}
      <button onClick={() => {
        setIsPlayerA(!isPlayerA);
      }}>
        Next player!
      </button>
    </div>
  );
}

function Counter({ person }) {
  const [score, setScore] = useState(0);
  const [hover, setHover] = useState(false);

  let className = 'counter';
  if (hover) {
    className += ' hover';
  }

  return (
    <div
      className={className}
      onPointerEnter={() => setHover(true)}
      onPointerLeave={() => setHover(false)}
    >
      <h1>{person}'s score: {score}</h1>
      <button onClick={() => setScore(score + 1)}>
        Add one
      </button>
    </div>
  );
}
```

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function Scoreboard() {
  const [isPlayerA, setIsPlayerA] = useState(true);
  return (
    <div>
      {isPlayerA &&
        <Counter person="Taylor" />
      }
      {!isPlayerA &&
        <Counter person="Sarah" />
      }
      <button onClick={() => {
        setIsPlayerA(!isPlayerA);
      }}>
        Next player!
      </button>
    </div>
  );
}

function Counter({ person }) {
  const [score, setScore] = useState(0);
  const [hover, setHover] = useState(false);

  let className = 'counter';
  if (hover) {
    className += ' hover';
  }

  return (
    <div
      className={className}
      onPointerEnter={() => setHover(true)}
      onPointerLeave={() => setHover(false)}
    >
      <h1>{person}'s score: {score}</h1>
      <button onClick={() => setScore(score + 1)}>
        Add one
      </button>
    </div>
  );
}
```

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function Scoreboard() {
  const [isPlayerA, setIsPlayerA] = useState(true);
  return (
    <div>
      {isPlayerA ? (
        <Counter key="Taylor" person="Taylor" />
      ) : (
        <Counter key="Sarah" person="Sarah" />
      )}
      <button onClick={() => {
        setIsPlayerA(!isPlayerA);
      }}>
        Next player!
      </button>
    </div>
  );
}

function Counter({ person }) {
  const [score, setScore] = useState(0);
  const [hover, setHover] = useState(false);

  let className = 'counter';
  if (hover) {
    className += ' hover';
  }

  return (
    <div
      className={className}
      onPointerEnter={() => setHover(true)}
      onPointerLeave={() => setHover(false)}
    >
      <h1>{person}'s score: {score}</h1>
      <button onClick={() => setScore(score + 1)}>
        Add one
      </button>
    </div>
  );
}
```

Switching between Taylor and Sarah does not preserve the state. This is because **you gave them different `key`s:**

```
{isPlayerA ? (

  <Counter key="Taylor" person="Taylor" />

) : (

  <Counter key="Sarah" person="Sarah" />

)}
```

Specifying a `key` tells React to use the `key` itself as part of the position, instead of their order within the parent. This is why, even though you render them in the same place in JSX, React sees them as two different counters, and so they will never share state. Every time a counter appears on the screen, its state is created. Every time it is removed, its state is destroyed. Toggling between them resets their state over and over.

### Note

Remember that keys are not globally unique. They only specify the position *within the parent*.

### Resetting a form with a key[](#resetting-a-form-with-a-key "Link for Resetting a form with a key ")

Resetting state with a key is particularly useful when dealing with forms.

In this chat app, the `<Chat>` component contains the text input state:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';
import Chat from './Chat.js';
import ContactList from './ContactList.js';

export default function Messenger() {
  const [to, setTo] = useState(contacts[0]);
  return (
    <div>
      <ContactList
        contacts={contacts}
        selectedContact={to}
        onSelect={contact => setTo(contact)}
      />
      <Chat contact={to} />
    </div>
  )
}

const contacts = [
  { id: 0, name: 'Taylor', email: 'taylor@mail.com' },
  { id: 1, name: 'Alice', email: 'alice@mail.com' },
  { id: 2, name: 'Bob', email: 'bob@mail.com' }
];
```

Try entering something into the input, and then press “Alice” or “Bob” to choose a different recipient. You will notice that the input state is preserved because the `<Chat>` is rendered at the same position in the tree.

**In many apps, this may be the desired behavior, but not in a chat app!** You don’t want to let the user send a message they already typed to a wrong person due to an accidental click. To fix it, add a `key`:

```
<Chat key={to.id} contact={to} />
```

This ensures that when you select a different recipient, the `Chat` component will be recreated from scratch, including any state in the tree below it. React will also re-create the DOM elements instead of reusing them.

Now switching the recipient always clears the text field:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';
import Chat from './Chat.js';
import ContactList from './ContactList.js';

export default function Messenger() {
  const [to, setTo] = useState(contacts[0]);
  return (
    <div>
      <ContactList
        contacts={contacts}
        selectedContact={to}
        onSelect={contact => setTo(contact)}
      />
      <Chat key={to.id} contact={to} />
    </div>
  )
}

const contacts = [
  { id: 0, name: 'Taylor', email: 'taylor@mail.com' },
  { id: 1, name: 'Alice', email: 'alice@mail.com' },
  { id: 2, name: 'Bob', email: 'bob@mail.com' }
];
```

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function App() {
  const [showHint, setShowHint] = useState(false);
  if (showHint) {
    return (
      <div>
        <p><i>Hint: Your favorite city?</i></p>
        <Form />
        <button onClick={() => {
          setShowHint(false);
        }}>Hide hint</button>
      </div>
    );
  }
  return (
    <div>
      <Form />
      <button onClick={() => {
        setShowHint(true);
      }}>Show hint</button>
    </div>
  );
}

function Form() {
  const [text, setText] = useState('');
  return (
    <textarea
      value={text}
      onChange={e => setText(e.target.value)}
    />
  );
}
```

[PreviousSharing State Between Components](/learn/sharing-state-between-components)

[NextExtracting State Logic into a Reducer](/learn/extracting-state-logic-into-a-reducer)

***

----
url: https://18.react.dev/learn/state-as-a-snapshot
----

```
import { useState } from 'react';

export default function Form() {
  const [isSent, setIsSent] = useState(false);
  const [message, setMessage] = useState('Hi!');
  if (isSent) {
    return <h1>Your message is on its way!</h1>
  }
  return (
    <form onSubmit={(e) => {
      e.preventDefault();
      setIsSent(true);
      sendMessage(message);
    }}>
      <textarea
        placeholder="Message"
        value={message}
        onChange={e => setMessage(e.target.value)}
      />
      <button type="submit">Send</button>
    </form>
  );
}

function sendMessage(message) {
  // ...
}
```

```
import { useState } from 'react';

export default function Counter() {
  const [number, setNumber] = useState(0);

  return (
    <>
      <h1>{number}</h1>
      <button onClick={() => {
        setNumber(number + 1);
        setNumber(number + 1);
        setNumber(number + 1);
      }}>+3</button>
    </>
  )
}
```

Notice that `number` only increments once per click!

**Setting state only changes it for the *next* render.** During the first render, `number` was `0`. This is why, in *that render’s* `onClick` handler, the value of `number` is still `0` even after `setNumber(number + 1)` was called:

```
<button onClick={() => {

  setNumber(number + 1);

  setNumber(number + 1);

  setNumber(number + 1);

}}>+3</button>
```

```
<button onClick={() => {

  setNumber(0 + 1);

  setNumber(0 + 1);

  setNumber(0 + 1);

}}>+3</button>
```

For the next render, `number` is `1`, so *that render’s* click handler looks like this:

```
<button onClick={() => {

  setNumber(1 + 1);

  setNumber(1 + 1);

  setNumber(1 + 1);

}}>+3</button>
```

This is why clicking the button again will set the counter to `2`, then to `3` on the next click, and so on.

## State over time[](#state-over-time "Link for State over time ")

Well, that was fun. Try to guess what clicking this button will alert:

```
import { useState } from 'react';

export default function Counter() {
  const [number, setNumber] = useState(0);

  return (
    <>
      <h1>{number}</h1>
      <button onClick={() => {
        setNumber(number + 5);
        alert(number);
      }}>+5</button>
    </>
  )
}
```

If you use the substitution method from before, you can guess that the alert shows “0”:

```
setNumber(0 + 5);

alert(0);
```

But what if you put a timer on the alert, so it only fires *after* the component re-rendered? Would it say “0” or “5”? Have a guess!

```
import { useState } from 'react';

export default function Counter() {
  const [number, setNumber] = useState(0);

  return (
    <>
      <h1>{number}</h1>
      <button onClick={() => {
        setNumber(number + 5);
        setTimeout(() => {
          alert(number);
        }, 3000);
      }}>+5</button>
    </>
  )
}
```

Surprised? If you use the substitution method, you can see the “snapshot” of the state passed to the alert.

```
setNumber(0 + 5);

setTimeout(() => {

  alert(0);

}, 3000);
```

The state stored in React may have changed by the time the alert runs, but it was scheduled using a snapshot of the state at the time the user interacted with it!

**A state variable’s value never changes within a render,** even if its event handler’s code is asynchronous. Inside *that render’s* `onClick`, the value of `number` continues to be `0` even after `setNumber(number + 5)` was called. Its value was “fixed” when React “took the snapshot” of the UI by calling your component.

Here is an example of how that makes your event handlers less prone to timing mistakes. Below is a form that sends a message with a five-second delay. Imagine this scenario:

1. You press the “Send” button, sending “Hello” to Alice.
2. Before the five-second delay ends, you change the value of the “To” field to “Bob”.

What do you expect the `alert` to display? Would it display, “You said Hello to Alice”? Or would it display, “You said Hello to Bob”? Make a guess based on what you know, and then try it:

```
import { useState } from 'react';

export default function Form() {
  const [to, setTo] = useState('Alice');
  const [message, setMessage] = useState('Hello');

  function handleSubmit(e) {
    e.preventDefault();
    setTimeout(() => {
      alert(`You said ${message} to ${to}`);
    }, 5000);
  }

  return (
    <form onSubmit={handleSubmit}>
      <label>
        To:{' '}
        <select
          value={to}
          onChange={e => setTo(e.target.value)}>
          <option value="Alice">Alice</option>
          <option value="Bob">Bob</option>
        </select>
      </label>
      <textarea
        placeholder="Message"
        value={message}
        onChange={e => setMessage(e.target.value)}
      />
      <button type="submit">Send</button>
    </form>
  );
}
```

```
import { useState } from 'react';

export default function TrafficLight() {
  const [walk, setWalk] = useState(true);

  function handleClick() {
    setWalk(!walk);
  }

  return (
    <>
      <button onClick={handleClick}>
        Change to {walk ? 'Stop' : 'Walk'}
      </button>
      <h1 style={{
        color: walk ? 'darkgreen' : 'darkred'
      }}>
        {walk ? 'Walk' : 'Stop'}
      </h1>
    </>
  );
}
```

Add an `alert` to the click handler. When the light is green and says “Walk”, clicking the button should say “Stop is next”. When the light is red and says “Stop”, clicking the button should say “Walk is next”.

Does it make a difference whether you put the `alert` before or after the `setWalk` call?

[PreviousRender and Commit](/learn/render-and-commit)

[NextQueueing a Series of State Updates](/learn/queueing-a-series-of-state-updates)

***

----
url: https://legacy.reactjs.org/blog/2016/02/19/new-versioning-scheme.html
----

February 19, 2016 by [Sebastian Markbåge](https://twitter.com/sebmarkbage)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

Today we’re announcing that we’re switching to major revisions for React. The current version is 0.14.7. The next release will be: **15.0.0**

This change shouldn’t materially affect most of you. Moving to major semver versions simply helps indicate our commitment to stability and gives us the flexibility to add new backwards-compatible features in minor releases. This means we can have fewer major releases and you won’t have to wait as long to take advantage of improvements to React. Plus, if you’re a component author, this versioning scheme gives you the flexibility to support two major versions of React at the same time so you don’t need to leave anyone behind.

The core of the React API has been stable for years. Our business as well as many of yours all depend heavily on the use of React as a core piece of our infrastructure. We’re committed to the stability as well as the progress of React going forward.

## [](#bring-everyone-along)Bring Everyone Along

React isn’t just a library but an ecosystem. We know that your applications and ours are not just isolated islands of code. It is a network of your own application code, your own open source components and third party libraries that all depend on React.

[](/static/899ef384f039caa51a9f58b621828d7e/764be/versioning-1.png)

Therefore it is important that we don’t just upgrade our own codebases but that we bring our whole community with us. We take the upgrade path very seriously - for everyone.

[](/static/b770014ccb13dbca11ddd0bbb5353319/f213e/versioning-poll.png)

## [](#introducing-minor-releases)Introducing Minor Releases

Ideally everyone could just depend on the latest version of React all the time.

[](/static/90b0bb4245cfdf42bff9db6f496b75bd/69476/versioning-2.png)

We know that in practice that is not possible. In the future, we expect more new additive APIs rather than breakage of existing ones. By moving to major revisions in the semver scheme, we can release new versions without breaking existing ones.

[](/static/7575ed187d0a8ec68ec68169720d0f27/2c5fd/versioning-3.png)

That means that if one component needs a new API, there is no need for any of the other components to do any further work. They remain compatible.

## [](#what-happened-to-100)What Happened to 1.0.0?

Part of React’s growth and popularity is that it is stable and performant in production. People have long asked what React v1.0 will look. Technically some breaking changes are important to avoid stagnating, but we still achieve stability by making it easy to upgrade. If major version numbers indicate API stability and engender trust that it can be used in production, then we got there a long time ago. There are too many preconceived notions of what v1.0 is. We’re still following semver. We’re just communicating stability by moving the 0 from the beginning to the end.

## [](#breaking-changes)Breaking Changes

Minor revision releases will include deprecation warnings and tips for how to upgrade an API or pattern that will be removed or changed in the future.

We will continue to release [codemods](https://www.youtube.com/watch?v=d0pOgY8__JM) for common patterns to make automatic upgrades of your codebase easier.

Once we’ve reached the end of life for a particular major version, we’ll release a new major version where all deprecated APIs have been removed.

## [](#avoiding-the-major-cliff)Avoiding The Major Cliff

If you try to upgrade your component to 16.0.0 you might find that your application no longer works if you still have other dependencies. E.g. if Ryan’s and Jed’s components are only compatible with 15.x.x.

[](/static/d8dd49a51f663d1b96c8b3ac27749f78/5caea/versioning-4.png)

Worst case, you revert back to 15.1.0 for your application. Since you’ll want to use your component, you might also revert that one.

[](/static/b7e3bc7d2d111e92cfeb45ec0b361faa/0a867/versioning-5.png)

Of course, Ryan and Jed think the same way. If we’re not careful, we can hit a cliff where nobody upgrades. This has happened to many software project ecosystems in the past.

Therefore, we’re committed to making it easy for most components and libraries built on top of React to be compatible with two major versions at the same time. We will do this by introducing new APIs before completely removing the old ones, thereby avoiding those cliffs.

[](/static/ec08ea1a53fcb540a5930a3f1f231bf8/0a867/versioning-6.png)

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2016-02-19-new-versioning-scheme.md)

----
url: https://legacy.reactjs.org/blog/2015/04/18/react-v0.13.2.html
----

April 18, 2015 by [Paul O’Shannessy](https://twitter.com/zpao)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

Yesterday the [React Native team shipped v0.4](/blog/2015/04/17/react-native-v0.4.html). Those of us working on the web team just a few feet away couldn’t just be shown up like that so we’re shipping v0.13.2 today as well! This is a bug fix release to address a few things while we continue to work towards v0.14.

The release is now available for download:

* **React**\
  Dev build with warnings: <https://fb.me/react-0.13.2.js>\
  Minified build for production: <https://fb.me/react-0.13.2.min.js>
* **React with Add-Ons**\
  Dev build with warnings: <https://fb.me/react-with-addons-0.13.2.js>\
  Minified build for production: <https://fb.me/react-with-addons-0.13.2.min.js>
* **In-Browser JSX transformer**\
  <https://fb.me/JSXTransformer-0.13.2.js>

We’ve also published version `0.13.2` of the `react` and `react-tools` packages on npm and the `react` package on bower.

***

## [](#changelog)Changelog

### [](#react-core)React Core

#### [](#new-features)New Features

* Added `strokeDashoffset`, `flexPositive`, `flexNegative` to the list of unitless CSS properties

* Added support for more DOM properties:

  * `scoped` - for `<style>` elements
  * `high`, `low`, `optimum` - for `<meter>` elements
  * `unselectable` - IE-specific property to prevent user selection

#### [](#bug-fixes)Bug Fixes

* Fixed a case where re-rendering after rendering null didn’t properly pass context
* Fixed a case where re-rendering after rendering with `style={null}` didn’t properly update `style`
* Update `uglify` dependency to prevent a bug in IE8
* Improved warnings

### [](#react-with-add-ons)React with Add-Ons

#### [](#bug-fixes-1)Bug Fixes

* Immutabilty Helpers: Ensure it supports `hasOwnProperty` as an object key

### [](#react-tools)React Tools

* Improve documentation for new options

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2015-04-18-react-v0.13.2.md)

----
url: https://react.dev/reference/rsc/use-client
----

[API Reference](/reference/react)

[Directives](/reference/rsc/directives)

# 'use client'[](#undefined "Link for this heading")

### React Server Components

`'use client'` is for use with [React Server Components](/reference/rsc/server-components).

***

## Reference[](#reference "Link for Reference ")

### `'use client'`[](#use-client "Link for this heading")

Add `'use client'` at the top of a file to mark the module and its transitive dependencies as client code.

```
'use client';



import { useState } from 'react';

import { formatDate } from './formatters';

import Button from './button';



export default function RichTextEditor({ timestamp, text }) {

  const date = formatDate(timestamp);

  // ...

  const editButton = <Button />;

  // ...

}
```

When a file marked with `'use client'` is imported from a Server Component, [compatible bundlers](/learn/creating-a-react-app#full-stack-frameworks) will treat the module import as a boundary between server-run and client-run code.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import FancyText from './FancyText';
import InspirationGenerator from './InspirationGenerator';
import Copyright from './Copyright';

export default function App() {
  return (
    <>
      <FancyText title text="Get Inspired App" />
      <InspirationGenerator>
        <Copyright year={2004} />
      </InspirationGenerator>
    </>
  );
}
```

```
// This is a definition of a component

function MyComponent() {

  return <p>My Component</p>

}
```

2. A “component” can also refer to a **component usage** of its definition.

```
import MyComponent from './MyComponent';



function App() {

  // This is a usage of a component

  return <MyComponent />;

}
```

* Functions that are [Server Functions](/reference/rsc/server-functions)

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
'use client';

import { useState } from 'react';

export default function Counter({initialValue = 0}) {
  const [countValue, setCountValue] = useState(initialValue);
  const increment = () => setCountValue(countValue + 1);
  const decrement = () => setCountValue(countValue - 1);
  return (
    <>
      <h2>Count Value: {countValue}</h2>
      <button onClick={increment}>+1</button>
      <button onClick={decrement}>-1</button>
    </>
  );
}
```

As `Counter` requires both the `useState` Hook and event handlers to increment or decrement the value, this component must be a Client Component and will require a `'use client'` directive at the top.

In contrast, a component that renders UI without interaction will not need to be a Client Component.

```
import { readFile } from 'node:fs/promises';

import Counter from './Counter';



export default async function CounterContainer() {

  const initialValue = await readFile('/path/to/counter_value');

  return <Counter initialValue={initialValue} />

}
```

For example, `Counter`’s parent component, `CounterContainer`, does not require `'use client'` as it is not interactive and does not use state. In addition, `CounterContainer` must be a Server Component as it reads from the local file system on the server, which is possible only in a Server Component.

There are also components that don’t use any server or client-only features and can be agnostic to where they render. In our earlier example, `FancyText` is one such component.

```
export default function FancyText({title, text}) {

  return title

    ? <h1 className='fancy title'>{text}</h1>

    : <h3 className='fancy cursive'>{text}</h3>

}
```

In this case, we don’t add the `'use client'` directive, resulting in `FancyText`’s *output* (rather than its source code) to be sent to the browser when referenced from a Server Component. As demonstrated in the earlier Inspirations app example, `FancyText` is used as both a Server or Client Component, depending on where it is imported and used.

But if `FancyText`’s HTML output was large relative to its source code (including dependencies), it might be more efficient to force it to always be a Client Component. Components that return a long SVG path string are one case where it may be more efficient to force a component to be a Client Component.

### Using client APIs[](#using-client-apis "Link for Using client APIs ")

Your React app may use client-specific APIs, such as the browser’s APIs for web storage, audio and video manipulation, and device hardware, among [others](https://developer.mozilla.org/en-US/docs/Web/API).

In this example, the component uses [DOM APIs](https://developer.mozilla.org/en-US/docs/Glossary/DOM) to manipulate a [`canvas`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas) element. Since those APIs are only available in the browser, it must be marked as a Client Component.

```
'use client';



import {useRef, useEffect} from 'react';



export default function Circle() {

  const ref = useRef(null);

  useLayoutEffect(() => {

    const canvas = ref.current;

    const context = canvas.getContext('2d');

    context.reset();

    context.beginPath();

    context.arc(100, 75, 50, 0, 2 * Math.PI);

    context.stroke();

  });

  return <canvas ref={ref} />;

}
```

***

----
url: https://18.react.dev/reference/react/Suspense
----

[API Reference](/reference/react)

[Components](/reference/react/components)

# \<Suspense>[](#undefined "Link for this heading")

`<Suspense>` lets you display a fallback until its children have finished loading.

```
<Suspense fallback={<Loading />}>

  <SomeComponent />

</Suspense>
```

***

***

## Usage[](#usage "Link for Usage ")

### Displaying a fallback while content is loading[](#displaying-a-fallback-while-content-is-loading "Link for Displaying a fallback while content is loading ")

You can wrap any part of your application with a Suspense boundary:

```
<Suspense fallback={<Loading />}>

  <Albums />

</Suspense>
```

React will display your loading fallback until all the code and data needed by the children has been loaded.

In the example below, the `Albums` component *suspends* while fetching the list of albums. Until it’s ready to render, React switches the closest Suspense boundary above to show the fallback—your `Loading` component. Then, when the data loads, React hides the `Loading` fallback and renders the `Albums` component with data.

```
import { Suspense } from 'react';
import Albums from './Albums.js';

export default function ArtistPage({ artist }) {
  return (
    <>
      <h1>{artist.name}</h1>
      <Suspense fallback={<Loading />}>
        <Albums artistId={artist.id} />
      </Suspense>
    </>
  );
}

function Loading() {
  return <h2>🌀 Loading...</h2>;
}
```

### Note

**Only Suspense-enabled data sources will activate the Suspense component.** They include:

* Data fetching with Suspense-enabled frameworks like [Relay](https://relay.dev/docs/guided-tour/rendering/loading-states/) and [Next.js](https://nextjs.org/docs/getting-started/react-essentials)
* Lazy-loading component code with [`lazy`](/reference/react/lazy)
* Reading the value of a Promise with [`use`](/reference/react/use)

Suspense **does not** detect when data is fetched inside an Effect or event handler.

The exact way you would load data in the `Albums` component above depends on your framework. If you use a Suspense-enabled framework, you’ll find the details in its data fetching documentation.

Suspense-enabled data fetching without the use of an opinionated framework is not yet supported. The requirements for implementing a Suspense-enabled data source are unstable and undocumented. An official API for integrating data sources with Suspense will be released in a future version of React.

***

### Revealing content together at once[](#revealing-content-together-at-once "Link for Revealing content together at once ")

By default, the whole tree inside Suspense is treated as a single unit. For example, even if *only one* of these components suspends waiting for some data, *all* of them together will be replaced by the loading indicator:

```
<Suspense fallback={<Loading />}>

  <Biography />

  <Panel>

    <Albums />

  </Panel>

</Suspense>
```

Then, after all of them are ready to be displayed, they will all appear together at once.

In the example below, both `Biography` and `Albums` fetch some data. However, because they are grouped under a single Suspense boundary, these components always “pop in” together at the same time.

```
import { Suspense } from 'react';
import Albums from './Albums.js';
import Biography from './Biography.js';
import Panel from './Panel.js';

export default function ArtistPage({ artist }) {
  return (
    <>
      <h1>{artist.name}</h1>
      <Suspense fallback={<Loading />}>
        <Biography artistId={artist.id} />
        <Panel>
          <Albums artistId={artist.id} />
        </Panel>
      </Suspense>
    </>
  );
}

function Loading() {
  return <h2>🌀 Loading...</h2>;
}
```

Components that load data don’t have to be direct children of the Suspense boundary. For example, you can move `Biography` and `Albums` into a new `Details` component. This doesn’t change the behavior. `Biography` and `Albums` share the same closest parent Suspense boundary, so their reveal is coordinated together.

```
<Suspense fallback={<Loading />}>

  <Details artistId={artist.id} />

</Suspense>



function Details({ artistId }) {

  return (

    <>

      <Biography artistId={artistId} />

      <Panel>

        <Albums artistId={artistId} />

      </Panel>

    </>

  );

}
```

***

### Revealing nested content as it loads[](#revealing-nested-content-as-it-loads "Link for Revealing nested content as it loads ")

When a component suspends, the closest parent Suspense component shows the fallback. This lets you nest multiple Suspense components to create a loading sequence. Each Suspense boundary’s fallback will be filled in as the next level of content becomes available. For example, you can give the album list its own fallback:

```
<Suspense fallback={<BigSpinner />}>

  <Biography />

  <Suspense fallback={<AlbumsGlimmer />}>

    <Panel>

      <Albums />

    </Panel>

  </Suspense>

</Suspense>
```

With this change, displaying the `Biography` doesn’t need to “wait” for the `Albums` to load.

The sequence will be:

1. If `Biography` hasn’t loaded yet, `BigSpinner` is shown in place of the entire content area.
2. Once `Biography` finishes loading, `BigSpinner` is replaced by the content.
3. If `Albums` hasn’t loaded yet, `AlbumsGlimmer` is shown in place of `Albums` and its parent `Panel`.
4. Finally, once `Albums` finishes loading, it replaces `AlbumsGlimmer`.

```
import { Suspense } from 'react';
import Albums from './Albums.js';
import Biography from './Biography.js';
import Panel from './Panel.js';

export default function ArtistPage({ artist }) {
  return (
    <>
      <h1>{artist.name}</h1>
      <Suspense fallback={<BigSpinner />}>
        <Biography artistId={artist.id} />
        <Suspense fallback={<AlbumsGlimmer />}>
          <Panel>
            <Albums artistId={artist.id} />
          </Panel>
        </Suspense>
      </Suspense>
    </>
  );
}

function BigSpinner() {
  return <h2>🌀 Loading...</h2>;
}

function AlbumsGlimmer() {
  return (
    <div className="glimmer-panel">
      <div className="glimmer-line" />
      <div className="glimmer-line" />
      <div className="glimmer-line" />
    </div>
  );
}
```

Suspense boundaries let you coordinate which parts of your UI should always “pop in” together at the same time, and which parts should progressively reveal more content in a sequence of loading states. You can add, move, or delete Suspense boundaries in any place in the tree without affecting the rest of your app’s behavior.

Don’t put a Suspense boundary around every component. Suspense boundaries should not be more granular than the loading sequence that you want the user to experience. If you work with a designer, ask them where the loading states should be placed—it’s likely that they’ve already included them in their design wireframes.

***

### Showing stale content while fresh content is loading[](#showing-stale-content-while-fresh-content-is-loading "Link for Showing stale content while fresh content is loading ")

In this example, the `SearchResults` component suspends while fetching the search results. Type `"a"`, wait for the results, and then edit it to `"ab"`. The results for `"a"` will get replaced by the loading fallback.

```
import { Suspense, useState } from 'react';
import SearchResults from './SearchResults.js';

export default function App() {
  const [query, setQuery] = useState('');
  return (
    <>
      <label>
        Search albums:
        <input value={query} onChange={e => setQuery(e.target.value)} />
      </label>
      <Suspense fallback={<h2>Loading...</h2>}>
        <SearchResults query={query} />
      </Suspense>
    </>
  );
}
```

A common alternative UI pattern is to *defer* updating the list and to keep showing the previous results until the new results are ready. The [`useDeferredValue`](/reference/react/useDeferredValue) Hook lets you pass a deferred version of the query down:

```
export default function App() {

  const [query, setQuery] = useState('');

  const deferredQuery = useDeferredValue(query);

  return (

    <>

      <label>

        Search albums:

        <input value={query} onChange={e => setQuery(e.target.value)} />

      </label>

      <Suspense fallback={<h2>Loading...</h2>}>

        <SearchResults query={deferredQuery} />

      </Suspense>

    </>

  );

}
```

The `query` will update immediately, so the input will display the new value. However, the `deferredQuery` will keep its previous value until the data has loaded, so `SearchResults` will show the stale results for a bit.

To make it more obvious to the user, you can add a visual indication when the stale result list is displayed:

```
<div style={{

  opacity: query !== deferredQuery ? 0.5 : 1 

}}>

  <SearchResults query={deferredQuery} />

</div>
```

Enter `"a"` in the example below, wait for the results to load, and then edit the input to `"ab"`. Notice how instead of the Suspense fallback, you now see the dimmed stale result list until the new results have loaded:

```
import { Suspense, useState, useDeferredValue } from 'react';
import SearchResults from './SearchResults.js';

export default function App() {
  const [query, setQuery] = useState('');
  const deferredQuery = useDeferredValue(query);
  const isStale = query !== deferredQuery;
  return (
    <>
      <label>
        Search albums:
        <input value={query} onChange={e => setQuery(e.target.value)} />
      </label>
      <Suspense fallback={<h2>Loading...</h2>}>
        <div style={{ opacity: isStale ? 0.5 : 1 }}>
          <SearchResults query={deferredQuery} />
        </div>
      </Suspense>
    </>
  );
}
```

### Note

Both deferred values and [Transitions](#preventing-already-revealed-content-from-hiding) let you avoid showing Suspense fallback in favor of inline indicators. Transitions mark the whole update as non-urgent so they are typically used by frameworks and router libraries for navigation. Deferred values, on the other hand, are mostly useful in application code where you want to mark a part of UI as non-urgent and let it “lag behind” the rest of the UI.

***

### Preventing already revealed content from hiding[](#preventing-already-revealed-content-from-hiding "Link for Preventing already revealed content from hiding ")

When a component suspends, the closest parent Suspense boundary switches to showing the fallback. This can lead to a jarring user experience if it was already displaying some content. Try pressing this button:

```
import { Suspense, useState } from 'react';
import IndexPage from './IndexPage.js';
import ArtistPage from './ArtistPage.js';
import Layout from './Layout.js';

export default function App() {
  return (
    <Suspense fallback={<BigSpinner />}>
      <Router />
    </Suspense>
  );
}

function Router() {
  const [page, setPage] = useState('/');

  function navigate(url) {
    setPage(url);
  }

  let content;
  if (page === '/') {
    content = (
      <IndexPage navigate={navigate} />
    );
  } else if (page === '/the-beatles') {
    content = (
      <ArtistPage
        artist={{
          id: 'the-beatles',
          name: 'The Beatles',
        }}
      />
    );
  }
  return (
    <Layout>
      {content}
    </Layout>
  );
}

function BigSpinner() {
  return <h2>🌀 Loading...</h2>;
}
```

When you pressed the button, the `Router` component rendered `ArtistPage` instead of `IndexPage`. A component inside `ArtistPage` suspended, so the closest Suspense boundary started showing the fallback. The closest Suspense boundary was near the root, so the whole site layout got replaced by `BigSpinner`.

To prevent this, you can mark the navigation state update as a *Transition* with [`startTransition`:](/reference/react/startTransition)

```
function Router() {

  const [page, setPage] = useState('/');



  function navigate(url) {

    startTransition(() => {

      setPage(url);      

    });

  }

  // ...
```

This tells React that the state transition is not urgent, and it’s better to keep showing the previous page instead of hiding any already revealed content. Now clicking the button “waits” for the `Biography` to load:

```
import { Suspense, startTransition, useState } from 'react';
import IndexPage from './IndexPage.js';
import ArtistPage from './ArtistPage.js';
import Layout from './Layout.js';

export default function App() {
  return (
    <Suspense fallback={<BigSpinner />}>
      <Router />
    </Suspense>
  );
}

function Router() {
  const [page, setPage] = useState('/');

  function navigate(url) {
    startTransition(() => {
      setPage(url);
    });
  }

  let content;
  if (page === '/') {
    content = (
      <IndexPage navigate={navigate} />
    );
  } else if (page === '/the-beatles') {
    content = (
      <ArtistPage
        artist={{
          id: 'the-beatles',
          name: 'The Beatles',
        }}
      />
    );
  }
  return (
    <Layout>
      {content}
    </Layout>
  );
}

function BigSpinner() {
  return <h2>🌀 Loading...</h2>;
}
```

A Transition doesn’t wait for *all* content to load. It only waits long enough to avoid hiding already revealed content. For example, the website `Layout` was already revealed, so it would be bad to hide it behind a loading spinner. However, the nested `Suspense` boundary around `Albums` is new, so the Transition doesn’t wait for it.

### Note

Suspense-enabled routers are expected to wrap the navigation updates into Transitions by default.

***

### Indicating that a Transition is happening[](#indicating-that-a-transition-is-happening "Link for Indicating that a Transition is happening ")

In the above example, once you click the button, there is no visual indication that a navigation is in progress. To add an indicator, you can replace [`startTransition`](/reference/react/startTransition) with [`useTransition`](/reference/react/useTransition) which gives you a boolean `isPending` value. In the example below, it’s used to change the website header styling while a Transition is happening:

```
import { Suspense, useState, useTransition } from 'react';
import IndexPage from './IndexPage.js';
import ArtistPage from './ArtistPage.js';
import Layout from './Layout.js';

export default function App() {
  return (
    <Suspense fallback={<BigSpinner />}>
      <Router />
    </Suspense>
  );
}

function Router() {
  const [page, setPage] = useState('/');
  const [isPending, startTransition] = useTransition();

  function navigate(url) {
    startTransition(() => {
      setPage(url);
    });
  }

  let content;
  if (page === '/') {
    content = (
      <IndexPage navigate={navigate} />
    );
  } else if (page === '/the-beatles') {
    content = (
      <ArtistPage
        artist={{
          id: 'the-beatles',
          name: 'The Beatles',
        }}
      />
    );
  }
  return (
    <Layout isPending={isPending}>
      {content}
    </Layout>
  );
}

function BigSpinner() {
  return <h2>🌀 Loading...</h2>;
}
```

***

### Resetting Suspense boundaries on navigation[](#resetting-suspense-boundaries-on-navigation "Link for Resetting Suspense boundaries on navigation ")

During a Transition, React will avoid hiding already revealed content. However, if you navigate to a route with different parameters, you might want to tell React it is *different* content. You can express this with a `key`:

```
<ProfilePage key={queryParams.id} />
```

Imagine you’re navigating within a user’s profile page, and something suspends. If that update is wrapped in a Transition, it will not trigger the fallback for already visible content. That’s the expected behavior.

However, now imagine you’re navigating between two different user profiles. In that case, it makes sense to show the fallback. For example, one user’s timeline is *different content* from another user’s timeline. By specifying a `key`, you ensure that React treats different users’ profiles as different components, and resets the Suspense boundaries during navigation. Suspense-integrated routers should do this automatically.

***

### Providing a fallback for server errors and client-only content[](#providing-a-fallback-for-server-errors-and-client-only-content "Link for Providing a fallback for server errors and client-only content ")

If you use one of the [streaming server rendering APIs](/reference/react-dom/server) (or a framework that relies on them), React will also use your `<Suspense>` boundaries to handle errors on the server. If a component throws an error on the server, React will not abort the server render. Instead, it will find the closest `<Suspense>` component above it and include its fallback (such as a spinner) into the generated server HTML. The user will see a spinner at first.

On the client, React will attempt to render the same component again. If it errors on the client too, React will throw the error and display the closest [error boundary.](/reference/react/Component#static-getderivedstatefromerror) However, if it does not error on the client, React will not display the error to the user since the content was eventually displayed successfully.

You can use this to opt out some components from rendering on the server. To do this, throw an error in the server environment and then wrap them in a `<Suspense>` boundary to replace their HTML with fallbacks:

```
<Suspense fallback={<Loading />}>

  <Chat />

</Suspense>



function Chat() {

  if (typeof window === 'undefined') {

    throw Error('Chat should only render on the client.');

  }

  // ...

}
```

The server HTML will include the loading indicator. It will be replaced by the `Chat` component on the client.

***

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### How do I prevent the UI from being replaced by a fallback during an update?[](#preventing-unwanted-fallbacks "Link for How do I prevent the UI from being replaced by a fallback during an update? ")

Replacing visible UI with a fallback creates a jarring user experience. This can happen when an update causes a component to suspend, and the nearest Suspense boundary is already showing content to the user.

To prevent this from happening, [mark the update as non-urgent using `startTransition`](#preventing-already-revealed-content-from-hiding). During a Transition, React will wait until enough data has loaded to prevent an unwanted fallback from appearing:

```
function handleNextPageClick() {

  // If this update suspends, don't hide the already displayed content

  startTransition(() => {

    setCurrentPage(currentPage + 1);

  });

}
```

This will avoid hiding existing content. However, any newly rendered `Suspense` boundaries will still immediately display fallbacks to avoid blocking the UI and let the user see the content as it becomes available.

**React will only prevent unwanted fallbacks during non-urgent updates**. It will not delay a render if it’s the result of an urgent update. You must opt in with an API like [`startTransition`](/reference/react/startTransition) or [`useDeferredValue`](/reference/react/useDeferredValue).

If your router is integrated with Suspense, it should wrap its updates into [`startTransition`](/reference/react/startTransition) automatically.

[Previous\<StrictMode>](/reference/react/StrictMode)

[NextAPIs](/reference/react/apis)

***

----
url: https://legacy.reactjs.org/docs/integrating-with-other-libraries.html
----

> These docs are old and won’t be updated. Go to [react.dev](https://react.dev/) for the new React docs.
>
> These new documentation pages teach modern React:
>
> * [`useSyncExternalStore`: Subscribing to an external store](https://react.dev/reference/react/useSyncExternalStore#subscribing-to-an-external-store)
> * [`createPortal`: Rendering React components into non-React DOM nodes](https://react.dev/reference/react-dom/createPortal#rendering-react-components-into-non-react-dom-nodes)

React can be used in any web application. It can be embedded in other applications and, with a little care, other applications can be embedded in React. This guide will examine some of the more common use cases, focusing on integration with [jQuery](https://jquery.com/) and [Backbone](https://backbonejs.org/), but the same ideas can be applied to integrating components with any existing code.

## [](#integrating-with-dom-manipulation-plugins)Integrating with DOM Manipulation Plugins

React is unaware of changes made to the DOM outside of React. It determines updates based on its own internal representation, and if the same DOM nodes are manipulated by another library, React gets confused and has no way to recover.

This does not mean it is impossible or even necessarily difficult to combine React with other ways of affecting the DOM, you just have to be mindful of what each is doing.

The easiest way to avoid conflicts is to prevent the React component from updating. You can do this by rendering elements that React has no reason to update, like an empty `<div />`.

### [](#how-to-approach-the-problem)How to Approach the Problem

To demonstrate this, let’s sketch out a wrapper for a generic jQuery plugin.

We will attach a [ref](/docs/refs-and-the-dom.html) to the root DOM element. Inside `componentDidMount`, we will get a reference to it so we can pass it to the jQuery plugin.

To prevent React from touching the DOM after mounting, we will return an empty `<div />` from the `render()` method. The `<div />` element has no properties or children, so React has no reason to update it, leaving the jQuery plugin free to manage that part of the DOM:

```
class SomePlugin extends React.Component {
  componentDidMount() {
    this.$el = $(this.el);    this.$el.somePlugin();  }

  componentWillUnmount() {
    this.$el.somePlugin('destroy');  }

  render() {
    return <div ref={el => this.el = el} />;  }
}
```

Note that we defined both `componentDidMount` and `componentWillUnmount` [lifecycle methods](/docs/react-component.html#the-component-lifecycle). Many jQuery plugins attach event listeners to the DOM so it’s important to detach them in `componentWillUnmount`. If the plugin does not provide a method for cleanup, you will probably have to provide your own, remembering to remove any event listeners the plugin registered to prevent memory leaks.

### [](#integrating-with-jquery-chosen-plugin)Integrating with jQuery Chosen Plugin

For a more concrete example of these concepts, let’s write a minimal wrapper for the plugin [Chosen](https://harvesthq.github.io/chosen/), which augments `<select>` inputs.

> **Note:**
>
> Just because it’s possible, doesn’t mean that it’s the best approach for React apps. We encourage you to use React components when you can. React components are easier to reuse in React applications, and often provide more control over their behavior and appearance.

First, let’s look at what Chosen does to the DOM.

If you call it on a `<select>` DOM node, it reads the attributes off of the original DOM node, hides it with an inline style, and then appends a separate DOM node with its own visual representation right after the `<select>`. Then it fires jQuery events to notify us about the changes.

Let’s say that this is the API we’re striving for with our `<Chosen>` wrapper React component:

```
function Example() {
  return (
    <Chosen onChange={value => console.log(value)}>
      <option>vanilla</option>
      <option>chocolate</option>
      <option>strawberry</option>
    </Chosen>
  );
}
```

We will implement it as an [uncontrolled component](/docs/uncontrolled-components.html) for simplicity.

First, we will create an empty component with a `render()` method where we return `<select>` wrapped in a `<div>`:

```
class Chosen extends React.Component {
  render() {
    return (
      <div>        <select className="Chosen-select" ref={el => this.el = el}>          {this.props.children}
        </select>
      </div>
    );
  }
}
```

Notice how we wrapped `<select>` in an extra `<div>`. This is necessary because Chosen will append another DOM element right after the `<select>` node we passed to it. However, as far as React is concerned, `<div>` always only has a single child. This is how we ensure that React updates won’t conflict with the extra DOM node appended by Chosen. It is important that if you modify the DOM outside of React flow, you must ensure React doesn’t have a reason to touch those DOM nodes.

Next, we will implement the lifecycle methods. We need to initialize Chosen with the ref to the `<select>` node in `componentDidMount`, and tear it down in `componentWillUnmount`:

```
componentDidMount() {
  this.$el = $(this.el);  this.$el.chosen();}

componentWillUnmount() {
  this.$el.chosen('destroy');}
```

[**Try it on CodePen**](https://codepen.io/gaearon/pen/qmqeQx?editors=0010)

Note that React assigns no special meaning to the `this.el` field. It only works because we have previously assigned this field from a `ref` in the `render()` method:

```
<select className="Chosen-select" ref={el => this.el = el}>
```

This is enough to get our component to render, but we also want to be notified about the value changes. To do this, we will subscribe to the jQuery `change` event on the `<select>` managed by Chosen.

We won’t pass `this.props.onChange` directly to Chosen because component’s props might change over time, and that includes event handlers. Instead, we will declare a `handleChange()` method that calls `this.props.onChange`, and subscribe it to the jQuery `change` event:

```
componentDidMount() {
  this.$el = $(this.el);
  this.$el.chosen();

  this.handleChange = this.handleChange.bind(this);  this.$el.on('change', this.handleChange);}

componentWillUnmount() {
  this.$el.off('change', this.handleChange);  this.$el.chosen('destroy');
}

handleChange(e) {  this.props.onChange(e.target.value);}
```

[**Try it on CodePen**](https://codepen.io/gaearon/pen/bWgbeE?editors=0010)

Finally, there is one more thing left to do. In React, props can change over time. For example, the `<Chosen>` component can get different children if parent component’s state changes. This means that at integration points it is important that we manually update the DOM in response to prop updates, since we no longer let React manage the DOM for us.

Chosen’s documentation suggests that we can use jQuery `trigger()` API to notify it about changes to the original DOM element. We will let React take care of updating `this.props.children` inside `<select>`, but we will also add a `componentDidUpdate()` lifecycle method that notifies Chosen about changes in the children list:

```
componentDidUpdate(prevProps) {
  if (prevProps.children !== this.props.children) {    this.$el.trigger("chosen:updated");  }
}
```

This way, Chosen will know to update its DOM element when the `<select>` children managed by React change.

The complete implementation of the `Chosen` component looks like this:

```
class Chosen extends React.Component {
  componentDidMount() {
    this.$el = $(this.el);
    this.$el.chosen();

    this.handleChange = this.handleChange.bind(this);
    this.$el.on('change', this.handleChange);
  }
  
  componentDidUpdate(prevProps) {
    if (prevProps.children !== this.props.children) {
      this.$el.trigger("chosen:updated");
    }
  }

  componentWillUnmount() {
    this.$el.off('change', this.handleChange);
    this.$el.chosen('destroy');
  }
  
  handleChange(e) {
    this.props.onChange(e.target.value);
  }

  render() {
    return (
      <div>
        <select className="Chosen-select" ref={el => this.el = el}>
          {this.props.children}
        </select>
      </div>
    );
  }
}
```

[**Try it on CodePen**](https://codepen.io/gaearon/pen/xdgKOz?editors=0010)

## [](#integrating-with-other-view-libraries)Integrating with Other View Libraries

React can be embedded into other applications thanks to the flexibility of [`createRoot()`](/docs/react-dom-client.html#createRoot).

Although React is commonly used at startup to load a single root React component into the DOM, `createRoot()` can also be called multiple times for independent parts of the UI which can be as small as a button, or as large as an app.

In fact, this is exactly how React is used at Facebook. This lets us write applications in React piece by piece, and combine them with our existing server-generated templates and other client-side code.

### [](#replacing-string-based-rendering-with-react)Replacing String-Based Rendering with React

A common pattern in older web applications is to describe chunks of the DOM as a string and insert it into the DOM like so: `$el.html(htmlString)`. These points in a codebase are perfect for introducing React. Just rewrite the string based rendering as a React component.

So the following jQuery implementation…

```
$('#container').html('<button id="btn">Say Hello</button>');
$('#btn').click(function() {
  alert('Hello!');
});
```

…could be rewritten using a React component:

```
function Button() {
  return <button id="btn">Say Hello</button>;
}

$('#btn').click(function() {
  alert('Hello!');
});
```

From here you could start moving more logic into the component and begin adopting more common React practices. For example, in components it is best not to rely on IDs because the same component can be rendered multiple times. Instead, we will use the [React event system](/docs/handling-events.html) and register the click handler directly on the React `<button>` element:

```
function Button(props) {
  return <button onClick={props.onClick}>Say Hello</button>;}

function HelloButton() {
  function handleClick() {    alert('Hello!');
  }
  return <Button onClick={handleClick} />;}
```

[**Try it on CodePen**](https://codepen.io/gaearon/pen/RVKbvW?editors=1010)

You can have as many such isolated components as you like, and use `ReactDOM.createRoot()` to render them to different DOM containers. Gradually, as you convert more of your app to React, you will be able to combine them into larger components, and move some of the `ReactDOM.createRoot()` calls up the hierarchy.

### [](#embedding-react-in-a-backbone-view)Embedding React in a Backbone View

[Backbone](https://backbonejs.org/) views typically use HTML strings, or string-producing template functions, to create the content for their DOM elements. This process, too, can be replaced with rendering a React component.

Below, we will create a Backbone view called `ParagraphView`. It will override Backbone’s `render()` function to render a React `<Paragraph>` component into the DOM element provided by Backbone (`this.el`). Here, too, we are using [`ReactDOM.createRoot()`](/docs/react-dom-client.html#createroot):

```
function Paragraph(props) {
  return <p>{props.text}</p>;
}

const ParagraphView = Backbone.View.extend({
  initialize(options) {
    this.reactRoot = ReactDOM.createRoot(this.el);  },
  render() {
    const text = this.model.get('text');
    this.reactRoot.render(<Paragraph text={text} />);    return this;
  },
  remove() {
    this.reactRoot.unmount();    Backbone.View.prototype.remove.call(this);
  }
});
```

[**Try it on CodePen**](https://codepen.io/gaearon/pen/gWgOYL?editors=0010)

It is important that we also call `root.unmount()` in the `remove` method so that React unregisters event handlers and other resources associated with the component tree when it is detached.

When a component is removed *from within* a React tree, the cleanup is performed automatically, but because we are removing the entire tree by hand, we must call this method.

## [](#integrating-with-model-layers)Integrating with Model Layers

While it is generally recommended to use unidirectional data flow such as [React state](/docs/lifting-state-up.html), [Flux](https://facebook.github.io/flux/), or [Redux](https://redux.js.org/), React components can use a model layer from other frameworks and libraries.

### [](#using-backbone-models-in-react-components)Using Backbone Models in React Components

The simplest way to consume [Backbone](https://backbonejs.org/) models and collections from a React component is to listen to the various change events and manually force an update.

Components responsible for rendering models would listen to `'change'` events, while components responsible for rendering collections would listen for `'add'` and `'remove'` events. In both cases, call [`this.forceUpdate()`](/docs/react-component.html#forceupdate) to rerender the component with the new data.

In the example below, the `List` component renders a Backbone collection, using the `Item` component to render individual items.

```
class Item extends React.Component {  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
  }

  handleChange() {    this.forceUpdate();  }
  componentDidMount() {
    this.props.model.on('change', this.handleChange);  }

  componentWillUnmount() {
    this.props.model.off('change', this.handleChange);  }

  render() {
    return <li>{this.props.model.get('text')}</li>;
  }
}

class List extends React.Component {  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
  }

  handleChange() {    this.forceUpdate();  }
  componentDidMount() {
    this.props.collection.on('add', 'remove', this.handleChange);  }

  componentWillUnmount() {
    this.props.collection.off('add', 'remove', this.handleChange);  }

  render() {
    return (
      <ul>
        {this.props.collection.map(model => (
          <Item key={model.cid} model={model} />        ))}
      </ul>
    );
  }
}
```

[**Try it on CodePen**](https://codepen.io/gaearon/pen/GmrREm?editors=0010)

### [](#extracting-data-from-backbone-models)Extracting Data from Backbone Models

The approach above requires your React components to be aware of the Backbone models and collections. If you later plan to migrate to another data management solution, you might want to concentrate the knowledge about Backbone in as few parts of the code as possible.

One solution to this is to extract the model’s attributes as plain data whenever it changes, and keep this logic in a single place. The following is [a higher-order component](/docs/higher-order-components.html) that extracts all attributes of a Backbone model into state, passing the data to the wrapped component.

This way, only the higher-order component needs to know about Backbone model internals, and most components in the app can stay agnostic of Backbone.

In the example below, we will make a copy of the model’s attributes to form the initial state. We subscribe to the `change` event (and unsubscribe on unmounting), and when it happens, we update the state with the model’s current attributes. Finally, we make sure that if the `model` prop itself changes, we don’t forget to unsubscribe from the old model, and subscribe to the new one.

Note that this example is not meant to be exhaustive with regards to working with Backbone, but it should give you an idea for how to approach this in a generic way:

```
function connectToBackboneModel(WrappedComponent) {  return class BackboneComponent extends React.Component {
    constructor(props) {
      super(props);
      this.state = Object.assign({}, props.model.attributes);      this.handleChange = this.handleChange.bind(this);
    }

    componentDidMount() {
      this.props.model.on('change', this.handleChange);    }

    componentWillReceiveProps(nextProps) {
      this.setState(Object.assign({}, nextProps.model.attributes));      if (nextProps.model !== this.props.model) {
        this.props.model.off('change', this.handleChange);        nextProps.model.on('change', this.handleChange);      }
    }

    componentWillUnmount() {
      this.props.model.off('change', this.handleChange);    }

    handleChange(model) {
      this.setState(model.changedAttributes());    }

    render() {
      const propsExceptModel = Object.assign({}, this.props);
      delete propsExceptModel.model;
      return <WrappedComponent {...propsExceptModel} {...this.state} />;    }
  }
}
```

To demonstrate how to use it, we will connect a `NameInput` React component to a Backbone model, and update its `firstName` attribute every time the input changes:

```
function NameInput(props) {
  return (
    <p>
      <input value={props.firstName} onChange={props.handleChange} />      <br />
      My name is {props.firstName}.    </p>
  );
}

const BackboneNameInput = connectToBackboneModel(NameInput);
function Example(props) {
  function handleChange(e) {
    props.model.set('firstName', e.target.value);  }

  return (
    <BackboneNameInput      model={props.model}      handleChange={handleChange}    />
  );
}

const model = new Backbone.Model({ firstName: 'Frodo' });
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Example model={model} />);
```

[**Try it on CodePen**](https://codepen.io/gaearon/pen/PmWwwa?editors=0010)

This technique is not limited to Backbone. You can use React with any model library by subscribing to its changes in the lifecycle methods and, optionally, copying the data into the local React state.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/integrating-with-other-libraries.md)

----
url: https://legacy.reactjs.org/blog/2015/01/27/react-v0.13.0-beta-1.html
----

January 27, 2015 by [Sebastian Markbåge](https://twitter.com/sebmarkbage)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

React 0.13 has a lot of nice features but there is one particular feature that I’m really excited about. I couldn’t wait for React.js Conf to start tomorrow morning.

Maybe you’re like me and staying up late excited about the conference, or maybe you weren’t one of the lucky ones to get a ticket. Either way I figured I’d give you all something to play with until then.

We just published a beta version of React v0.13.0 to [npm](https://www.npmjs.com/package/react)! You can install it with `npm install react@0.13.0-beta.1`. Since this is a pre-release, we don’t have proper release notes ready.

So what is that one feature I’m so excited about that I just couldn’t wait to share?

## [](#plain-javascript-classes)Plain JavaScript Classes!!

JavaScript originally didn’t have a built-in class system. Every popular framework built their own, and so did we. This means that you have a learn slightly different semantics for each framework.

We figured that we’re not in the business of designing a class system. We just want to use whatever is the idiomatic JavaScript way of creating classes.

In React 0.13.0 you no longer need to use `React.createClass` to create React components. If you have a transpiler you can use ES6 classes today. You can use the transpiler we ship with `react-tools` by making use of the harmony option: `jsx --harmony`.

### [](#es6-classes)ES6 Classes

```
class HelloMessage extends React.Component {
  render() {
    return <div>Hello {this.props.name}</div>;
  }
}

React.render(<HelloMessage name="Sebastian" />, mountNode);
```

The API is mostly what you would expect, with the exception of `getInitialState`. We figured that the idiomatic way to specify class state is to just use a simple instance property. Likewise `getDefaultProps` and `propTypes` are really just properties on the constructor.

```
export class Counter extends React.Component {
  constructor(props) {
    super(props);
    this.state = {count: props.initialCount};
  }
  tick() {
    this.setState({count: this.state.count + 1});
  }
  render() {
    return (
      <div onClick={this.tick.bind(this)}>
        Clicks: {this.state.count}
      </div>
    );
  }
}
Counter.propTypes = { initialCount: React.PropTypes.number };
Counter.defaultProps = { initialCount: 0 };
```

### [](#es7-property-initializers)ES7+ Property Initializers

Wait, assigning to properties seems like a very imperative way of defining classes! You’re right, however, we designed it this way because it’s idiomatic. We fully expect a more declarative syntax for property initialization to arrive in future version of JavaScript. It might look something like this:

```
// Future Version
export class Counter extends React.Component {
  static propTypes = { initialCount: React.PropTypes.number };
  static defaultProps = { initialCount: 0 };
  state = { count: this.props.initialCount };
  tick() {
    this.setState({ count: this.state.count + 1 });
  }
  render() {
    return (
      <div onClick={this.tick.bind(this)}>
        Clicks: {this.state.count}
      </div>
    );
  }
}
```

This was inspired by TypeScript’s property initializers.

### [](#autobinding)Autobinding

`React.createClass` has a built-in magic feature that bound all methods to `this` automatically for you. This can be a little confusing for JavaScript developers that are not used to this feature in other classes, or it can be confusing when they move from React to other classes.

Therefore we decided not to have this built-in into React’s class model. You can still explicitly prebind methods in your constructor if you want.

```
class Counter extends React.Component {
  constructor(props) {
    super(props);
    this.tick = this.tick.bind(this);
  }
  tick() {
    ...
  }
  ...
}
```

However, when we have the future property initializers, there is a neat trick that you can use to accomplish this syntactically:

```
class Counter extends React.Component {
  tick = () => {
    ...
  }
  ...
}
```

### [](#mixins)Mixins

Unfortunately, we will not launch any mixin support for ES6 classes in React. That would defeat the purpose of only using idiomatic JavaScript concepts.

There is no standard and universal way to define mixins in JavaScript. In fact, several features to support mixins were dropped from ES6 today. There are a lot of libraries with different semantics. We think that there should be one way of defining mixins that you can use for any JavaScript class. React just making another doesn’t help that effort.

Therefore, we will keep working with the larger JS community to create a standard for mixins. We will also start designing a new compositional API that will help make common tasks easier to do without mixins. E.g. first-class subscriptions to any kind of Flux store.

Luckily, if you want to keep using mixins, you can just keep using `React.createClass`.

> **Note:**
>
> The classic `React.createClass` style of creating classes will continue to work just fine.

## [](#other-languages)Other Languages!

Since these classes are just plain old JavaScript classes, you can use other languages that compile to JavaScript classes, such as TypeScript.

You can also use CoffeeScript classes:

```
div = React.createFactory 'div'

class Counter extends React.Component
  @propTypes = initialCount: React.PropTypes.number
  @defaultProps = initialCount: 0

  constructor: (props) ->
    super props
    @state = count: props.initialCount

  tick: =>
    @setState count: @state.count + 1

  render: ->
    div onClick: @tick,
      'Clicks: '
      @state.count
```

You can even use the old ES3 module pattern if you want:

```
function MyComponent(initialProps) {
  return {
    state: { value: initialProps.initialValue },
    render: function() {
      return <span className={this.state.value} />
    }
  };
}
```

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2015-01-27-react-v0.13.0-beta-1.md)

----
url: https://legacy.reactjs.org/docs/hooks-reference.html
----

> These docs are old and won’t be updated. Go to [react.dev](https://react.dev/) for the new React docs.
>
> These new documentation pages teach modern React:
>
> * [`react`: Hooks](https://react.dev/reference/react)

*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`

> This content is out of date.
>
> Read the new React documentation for [`useState`](https://react.dev/reference/react/useState).

```
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.

```
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`:

```
function Counter({initialCount}) {
  const [count, setCount] = useState(initialCount);
  return (
    <>
      Count: {count}
      <button onClick={() => setCount(initialCount)}>Reset</button>
      <button onClick={() => setCount(prevCount => prevCount - 1)}>-</button>
      <button onClick={() => setCount(prevCount => prevCount + 1)}>+</button>
    </>
  );
}
```

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:
>
> ```
> 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:

```
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`

> This content is out of date.
>
> Read the new React documentation for [`useEffect`](https://react.dev/reference/react/useEffect).

```
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:

```
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:

```
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`

> This content is out of date.
>
> Read the new React documentation for [`useContext`](https://react.dev/reference/react/useContext).

```
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 `<MyContext.Provider>` above the calling component in the tree.

When the nearest `<MyContext.Provider>` 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 `<MyContext.Consumer>`.
>
> `useContext(MyContext)` only lets you *read* the context and subscribe to its changes. You still need a `<MyContext.Provider>` above in the tree to *provide* the value for this context.

**Putting it together with Context.Provider**

```
const themes = {
  light: {
    foreground: "#000000",
    background: "#eeeeee"
  },
  dark: {
    foreground: "#ffffff",
    background: "#222222"
  }
};

const ThemeContext = React.createContext(themes.light);

function App() {
  return (
    <ThemeContext.Provider value={themes.dark}>
      <Toolbar />
    </ThemeContext.Provider>
  );
}

function Toolbar(props) {
  return (
    <div>
      <ThemedButton />
    </div>
  );
}

function ThemedButton() {
  const theme = useContext(ThemeContext);  return (    <button style={{ background: theme.background, color: theme.foreground }}>      I am styled by theme context!    </button>  );
}
```

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`

> This content is out of date.
>
> Read the new React documentation for [`useReducer`](https://react.dev/reference/react/useReducer).

```
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:

```
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}
      <button onClick={() => dispatch({type: 'decrement'})}>-</button>
      <button onClick={() => dispatch({type: 'increment'})}>+</button>
    </>
  );
}
```

> 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:

```
  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:

```
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}
      <button
        onClick={() => dispatch({type: 'reset', payload: initialCount})}>        Reset
      </button>
      <button onClick={() => dispatch({type: 'decrement'})}>-</button>
      <button onClick={() => dispatch({type: 'increment'})}>+</button>
    </>
  );
}
```

#### [](#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`

> This content is out of date.
>
> Read the new React documentation for [`useCallback`](https://react.dev/reference/react/useCallback).

```
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`

> This content is out of date.
>
> Read the new React documentation for [`useMemo`](https://react.dev/reference/react/useMemo).

```
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`

> This content is out of date.
>
> Read the new React documentation for [`useRef`](https://react.dev/reference/react/useRef).

```
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:

```
function TextInputWithFocusButton() {
  const inputEl = useRef(null);
  const onButtonClick = () => {
    // `current` points to the mounted text input element
    inputEl.current.focus();
  };
  return (
    <>
      <input ref={inputEl} type="text" />
      <button onClick={onButtonClick}>Focus the input</button>
    </>
  );
}
```

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 `<div ref={myRef} />`, 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`

> This content is out of date.
>
> Read the new React documentation for [`useImperativeHandle`](https://react.dev/reference/react/useImperativeHandle).

```
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):

```
function FancyInput(props, ref) {
  const inputRef = useRef();
  useImperativeHandle(ref, () => ({
    focus: () => {
      inputRef.current.focus();
    }
  }));
  return <input ref={inputRef} ... />;
}
FancyInput = forwardRef(FancyInput);
```

In this example, a parent component that renders `<FancyInput ref={inputRef} />` would be able to call `inputRef.current.focus()`.

### [](#uselayouteffect)`useLayoutEffect`

> This content is out of date.
>
> Read the new React documentation for [`useLayoutEffect`](https://react.dev/reference/react/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 && <Child />` and defer showing it with `useEffect(() => { setShowChild(true); }, [])`. This way, the UI doesn’t appear broken before hydration.

### [](#usedebugvalue)`useDebugValue`

> This content is out of date.
>
> Read the new React documentation for [`useDebugValue`](https://react.dev/reference/react/useDebugValue).

```
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):

```
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:

```
useDebugValue(date, date => date.toDateString());
```

### [](#usedeferredvalue)`useDeferredValue`

> This content is out of date.
>
> Read the new React documentation for [`useDeferredValue`](https://react.dev/reference/react/useDeferredValue).

```
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):

```
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(() =>
    <SearchSuggestions query={deferredQuery} />,
    [deferredQuery]
  );

  return (
    <>
      <SearchInput query={query} />
      <Suspense fallback="Loading results...">
        {suggestions}
      </Suspense>
    </>
  );
}
```

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`

> This content is out of date.
>
> Read the new React documentation for [`useTransition`](https://react.dev/reference/react/useTransition).

```
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:

```
startTransition(() => {
  setCount(count + 1);
});
```

`isPending` indicates when a transition is active to show a pending state:

```
function App() {
  const [isPending, startTransition] = useTransition();
  const [count, setCount] = useState(0);
  
  function handleClick() {
    startTransition(() => {
      setCount(c => c + 1);
    });
  }

  return (
    <div>
      {isPending && <Spinner />}
      <button onClick={handleClick}>{count}</button>
    </div>
  );
}
```

> 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`

> This content is out of date.
>
> Read the new React documentation for [`useId`](https://react.dev/reference/react/useId).

```
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:

```
function Checkbox() {
  const id = useId();
  return (
    <>
      <label htmlFor={id}>Do you like React?</label>
      <input id={id} type="checkbox" name="react"/>
    </>
  );
};
```

For multiple IDs in the same component, append a suffix using the same `id`:

```
function NameFields() {
  const id = useId();
  return (
    <div>
      <label htmlFor={id + '-firstName'}>First Name</label>
      <div>
        <input id={id + '-firstName'} type="text" />
      </div>
      <label htmlFor={id + '-lastName'}>Last Name</label>
      <div>
        <input id={id + '-lastName'} type="text" />
      </div>
    </div>
  );
}
```

> 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`

> This content is out of date.
>
> Read the new React documentation for [`useSyncExternalStore`](https://react.dev/reference/react/useSyncExternalStore).

```
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:

```
const state = useSyncExternalStore(store.subscribe, store.getSnapshot);
```

However, you can also subscribe to a specific field:

```
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:

```
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`

> This content is out of date.
>
> Read the new React documentation for [`useInsertionEffect`](https://react.dev/reference/react/useInsertionEffect).

```
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.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/hooks-reference.md)

* Previous article

  [Building Your Own Hooks](/docs/hooks-custom.html)

* Next article

  [Hooks FAQ](/docs/hooks-faq.html)

----
url: https://legacy.reactjs.org/blog/2014/05/29/one-year-of-open-source-react.html
----

May 29, 2014 by [Cheng Lou](https://twitter.com/_chenglou)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

Today marks the one-year open-source anniversary of React.

It’s been a crazy ride. 2.3k commits and 1.5k issues and pull requests later, we’re approaching version 1.0 and nearing 7k GitHub stars, with big names such as Khan Academy, New York Times, and Airbnb (and naturally, Facebook and Instagram) using React in production, and many more developers blogging their success stories with it. The [roadmap](/blog/2014/03/28/the-road-to-1.0.html) gives a glimpse into the future of the library; exciting stuff lies ahead!

Every success has its story. React was born out of our frustration at existing solutions for building UIs. When it was first suggested at Facebook, few people thought that functionally re-rendering everything and diffing the results could ever perform well. However, support grew after we built the first implementation and people wrote their first components. When we open-sourced React, the initial reception was [similarly skeptical](https://www.reddit.com/r/programming/comments/1fak87/react_facebooks_latest_javascript_client_library/). It challenges many pre-established conventions and received mostly disapproving first-impressions, intermingled with positive ones that often were votes of confidence in Facebook’s engineering capabilities. On an open, competitive platform such as the web, it’s been hard to convince people to try React. [JSX](/docs/jsx-in-depth.html), in particular, filtered out a huge chunk of potential early adopters.

Fast forward one year, React has strongly [grown in popularity](https://news.ycombinator.com/item?id=7489959). Special acknowledgments go to Khan Academy, the ClojureScript community, and established frameworks such as Ember and Angular for contributing to and debating on our work. We’d also like to thank all the [individual contributors](https://github.com/facebook/react/graphs/contributors) who have taken the time to help out over the past year. React, as a library and as a new paradigm on the web, wouldn’t have gained as much traction without them. In the future, we will continue to try to set an example of what’s possible to achieve when we rethink about current “best practices”.

Here’s to another year!

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2014-05-29-one-year-of-open-source-react.md)

----
url: https://legacy.reactjs.org/docs/update.html
----

> Note:
>
> `update` is a legacy add-on. Use [`immutability-helper`](https://github.com/kolodny/immutability-helper) instead.

**Importing**

```
import update from 'react-addons-update'; // ES6
var update = require('react-addons-update'); // ES5 with npm
```

## [](#overview)Overview

React lets you use whatever style of data management you want, including mutation. However, if you can use immutable data in performance-critical parts of your application it’s easy to implement a fast [`shouldComponentUpdate()`](/docs/react-component.html#shouldcomponentupdate) method to significantly speed up your app.

Dealing with immutable data in JavaScript is more difficult than in languages designed for it, like [Clojure](https://clojure.org/). However, we’ve provided a simple immutability helper, `update()`, that makes dealing with this type of data much easier, *without* fundamentally changing how your data is represented. You can also take a look at Facebook’s [Immutable-js](https://immutable-js.com/docs/latest@main/) and the [Advanced Performance](/docs/advanced-performance.html) section for more detail on Immutable-js.

### [](#the-main-idea)The Main Idea

If you mutate data like this:

```
myData.x.y.z = 7;
// or...
myData.a.b.push(9);
```

You have no way of determining which data has changed since the previous copy has been overwritten. Instead, you need to create a new copy of `myData` and change only the parts of it that need to be changed. Then you can compare the old copy of `myData` with the new one in `shouldComponentUpdate()` using triple-equals:

```
const newData = deepCopy(myData);
newData.x.y.z = 7;
newData.a.b.push(9);
```

Unfortunately, deep copies are expensive, and sometimes impossible. You can alleviate this by only copying objects that need to be changed and by reusing the objects that haven’t changed. Unfortunately, in today’s JavaScript this can be cumbersome:

```
const newData = extend(myData, {
  x: extend(myData.x, {
    y: extend(myData.x.y, {z: 7}),
  }),
  a: extend(myData.a, {b: myData.a.b.concat(9)})
});
```

While this is fairly performant (since it only makes a shallow copy of `log n` objects and reuses the rest), it’s a big pain to write. Look at all the repetition! This is not only annoying, but also provides a large surface area for bugs.

## [](#update)`update()`

`update()` provides simple syntactic sugar around this pattern to make writing this code easier. This code becomes:

```
import update from 'react-addons-update';

const newData = update(myData, {
  x: {y: {z: {$set: 7}}},
  a: {b: {$push: [9]}}
});
```

While the syntax takes a little getting used to (though it’s inspired by [MongoDB’s query language](https://docs.mongodb.com/manual/crud/#query)) there’s no redundancy, it’s statically analyzable and it’s not much more typing than the mutative version.

The `$`-prefixed keys are called *commands*. The data structure they are “mutating” is called the *target*.

## [](#available-commands)Available Commands

* `{$push: array}` `push()` all the items in `array` on the target.
* `{$unshift: array}` `unshift()` all the items in `array` on the target.
* `{$splice: array of arrays}` for each item in `arrays` call `splice()` on the target with the parameters provided by the item.
* `{$set: any}` replace the target entirely.
* `{$merge: object}` merge the keys of `object` with the target.
* `{$apply: function}` passes in the current value to the function and updates it with the new returned value.

## [](#examples)Examples

### [](#simple-push)Simple push

```
const initialArray = [1, 2, 3];
const newArray = update(initialArray, {$push: [4]}); // => [1, 2, 3, 4]
```

`initialArray` is still `[1, 2, 3]`.

### [](#nested-collections)Nested collections

```
const collection = [1, 2, {a: [12, 17, 15]}];
const newCollection = update(collection, {2: {a: {$splice: [[1, 1, 13, 14]]}}});
// => [1, 2, {a: [12, 13, 14, 15]}]
```

This accesses `collection`’s index `2`, key `a`, and does a splice of one item starting from index `1` (to remove `17`) while inserting `13` and `14`.

### [](#updating-a-value-based-on-its-current-one)Updating a value based on its current one

```
const obj = {a: 5, b: 3};
const newObj = update(obj, {b: {$apply: function(x) {return x * 2;}}});
// => {a: 5, b: 6}
// This is equivalent, but gets verbose for deeply nested collections:
const newObj2 = update(obj, {b: {$set: obj.b * 2}});
```

### [](#shallow-merge)(Shallow) Merge

```
const obj = {a: 5, b: 3};
const newObj = update(obj, {$merge: {b: 6, c: 7}}); // => {a: 5, b: 6, c: 7}
```

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/addons-update.md)

----
url: https://18.react.dev/learn/updating-objects-in-state
----

```
const [x, setX] = useState(0);
```

So far you’ve been working with numbers, strings, and booleans. These kinds of JavaScript values are “immutable”, meaning unchangeable or “read-only”. You can trigger a re-render to *replace* a value:

```
setX(5);
```

The `x` state changed from `0` to `5`, but the *number `0` itself* did not change. It’s not possible to make any changes to the built-in primitive values like numbers, strings, and booleans in JavaScript.

Now consider an object in state:

```
const [position, setPosition] = useState({ x: 0, y: 0 });
```

Technically, it is possible to change the contents of *the object itself*. **This is called a mutation:**

```
position.x = 5;
```

However, although objects in React state are technically mutable, you should treat them **as if** they were immutable—like numbers, booleans, and strings. Instead of mutating them, you should always replace them.

## Treat state as read-only[](#treat-state-as-read-only "Link for Treat state as read-only ")

In other words, you should **treat any JavaScript object that you put into state as read-only.**

This example holds an object in state to represent the current pointer position. The red dot is supposed to move when you touch or move the cursor over the preview area. But the dot stays in the initial position:

```
import { useState } from 'react';

export default function MovingDot() {
  const [position, setPosition] = useState({
    x: 0,
    y: 0
  });
  return (
    <div
      onPointerMove={e => {
        position.x = e.clientX;
        position.y = e.clientY;
      }}
      style={{
        position: 'relative',
        width: '100vw',
        height: '100vh',
      }}>
      <div style={{
        position: 'absolute',
        backgroundColor: 'red',
        borderRadius: '50%',
        transform: `translate(${position.x}px, ${position.y}px)`,
        left: -10,
        top: -10,
        width: 20,
        height: 20,
      }} />
    </div>
  );
}
```

The problem is with this bit of code.

```
onPointerMove={e => {

  position.x = e.clientX;

  position.y = e.clientY;

}}
```

This code modifies the object assigned to `position` from [the previous render.](/learn/state-as-a-snapshot#rendering-takes-a-snapshot-in-time) But without using the state setting function, React has no idea that object has changed. So React does not do anything in response. It’s like trying to change the order after you’ve already eaten the meal. While mutating state can work in some cases, we don’t recommend it. You should treat the state value you have access to in a render as read-only.

To actually [trigger a re-render](/learn/state-as-a-snapshot#setting-state-triggers-renders) in this case, **create a *new* object and pass it to the state setting function:**

```
onPointerMove={e => {

  setPosition({

    x: e.clientX,

    y: e.clientY

  });

}}
```

With `setPosition`, you’re telling React:

* Replace `position` with this new object
* And render this component again

Notice how the red dot now follows your pointer when you touch or hover over the preview area:

```
import { useState } from 'react';

export default function MovingDot() {
  const [position, setPosition] = useState({
    x: 0,
    y: 0
  });
  return (
    <div
      onPointerMove={e => {
        setPosition({
          x: e.clientX,
          y: e.clientY
        });
      }}
      style={{
        position: 'relative',
        width: '100vw',
        height: '100vh',
      }}>
      <div style={{
        position: 'absolute',
        backgroundColor: 'red',
        borderRadius: '50%',
        transform: `translate(${position.x}px, ${position.y}px)`,
        left: -10,
        top: -10,
        width: 20,
        height: 20,
      }} />
    </div>
  );
}
```

##### Deep Dive#### Local mutation is fine[](#local-mutation-is-fine "Link for Local mutation is fine ")

Code like this is a problem because it modifies an *existing* object in state:

```
position.x = e.clientX;

position.y = e.clientY;
```

But code like this is **absolutely fine** because you’re mutating a fresh object you have *just created*:

```
const nextPosition = {};

nextPosition.x = e.clientX;

nextPosition.y = e.clientY;

setPosition(nextPosition);
```

In fact, it is completely equivalent to writing this:

```
setPosition({

  x: e.clientX,

  y: e.clientY

});
```

Mutation is only a problem when you change *existing* objects that are already in state. Mutating an object you’ve just created is okay because *no other code references it yet.* Changing it isn’t going to accidentally impact something that depends on it. This is called a “local mutation”. You can even do local mutation [while rendering.](/learn/keeping-components-pure#local-mutation-your-components-little-secret) Very convenient and completely okay!

## Copying objects with the spread syntax[](#copying-objects-with-the-spread-syntax "Link for Copying objects with the spread syntax ")

In the previous example, the `position` object is always created fresh from the current cursor position. But often, you will want to include *existing* data as a part of the new object you’re creating. For example, you may want to update *only one* field in a form, but keep the previous values for all other fields.

These input fields don’t work because the `onChange` handlers mutate the state:

```
import { useState } from 'react';

export default function Form() {
  const [person, setPerson] = useState({
    firstName: 'Barbara',
    lastName: 'Hepworth',
    email: 'bhepworth@sculpture.com'
  });

  function handleFirstNameChange(e) {
    person.firstName = e.target.value;
  }

  function handleLastNameChange(e) {
    person.lastName = e.target.value;
  }

  function handleEmailChange(e) {
    person.email = e.target.value;
  }

  return (
    <>
      <label>
        First name:
        <input
          value={person.firstName}
          onChange={handleFirstNameChange}
        />
      </label>
      <label>
        Last name:
        <input
          value={person.lastName}
          onChange={handleLastNameChange}
        />
      </label>
      <label>
        Email:
        <input
          value={person.email}
          onChange={handleEmailChange}
        />
      </label>
      <p>
        {person.firstName}{' '}
        {person.lastName}{' '}
        ({person.email})
      </p>
    </>
  );
}
```

For example, this line mutates the state from a past render:

```
person.firstName = e.target.value;
```

The reliable way to get the behavior you’re looking for is to create a new object and pass it to `setPerson`. But here, you want to also **copy the existing data into it** because only one of the fields has changed:

```
setPerson({

  firstName: e.target.value, // New first name from the input

  lastName: person.lastName,

  email: person.email

});
```

You can use the `...` [object spread](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax#spread_in_object_literals) syntax so that you don’t need to copy every property separately.

```
setPerson({

  ...person, // Copy the old fields

  firstName: e.target.value // But override this one

});
```

Now the form works!

Notice how you didn’t declare a separate state variable for each input field. For large forms, keeping all data grouped in an object is very convenient—as long as you update it correctly!

```
import { useState } from 'react';

export default function Form() {
  const [person, setPerson] = useState({
    firstName: 'Barbara',
    lastName: 'Hepworth',
    email: 'bhepworth@sculpture.com'
  });

  function handleFirstNameChange(e) {
    setPerson({
      ...person,
      firstName: e.target.value
    });
  }

  function handleLastNameChange(e) {
    setPerson({
      ...person,
      lastName: e.target.value
    });
  }

  function handleEmailChange(e) {
    setPerson({
      ...person,
      email: e.target.value
    });
  }

  return (
    <>
      <label>
        First name:
        <input
          value={person.firstName}
          onChange={handleFirstNameChange}
        />
      </label>
      <label>
        Last name:
        <input
          value={person.lastName}
          onChange={handleLastNameChange}
        />
      </label>
      <label>
        Email:
        <input
          value={person.email}
          onChange={handleEmailChange}
        />
      </label>
      <p>
        {person.firstName}{' '}
        {person.lastName}{' '}
        ({person.email})
      </p>
    </>
  );
}
```

Note that the `...` spread syntax is “shallow”—it only copies things one level deep. This makes it fast, but it also means that if you want to update a nested property, you’ll have to use it more than once.

##### Deep Dive#### Using a single event handler for multiple fields[](#using-a-single-event-handler-for-multiple-fields "Link for Using a single event handler for multiple fields ")

You can also use the `[` and `]` braces inside your object definition to specify a property with a dynamic name. Here is the same example, but with a single event handler instead of three different ones:

```
import { useState } from 'react';

export default function Form() {
  const [person, setPerson] = useState({
    firstName: 'Barbara',
    lastName: 'Hepworth',
    email: 'bhepworth@sculpture.com'
  });

  function handleChange(e) {
    setPerson({
      ...person,
      [e.target.name]: e.target.value
    });
  }

  return (
    <>
      <label>
        First name:
        <input
          name="firstName"
          value={person.firstName}
          onChange={handleChange}
        />
      </label>
      <label>
        Last name:
        <input
          name="lastName"
          value={person.lastName}
          onChange={handleChange}
        />
      </label>
      <label>
        Email:
        <input
          name="email"
          value={person.email}
          onChange={handleChange}
        />
      </label>
      <p>
        {person.firstName}{' '}
        {person.lastName}{' '}
        ({person.email})
      </p>
    </>
  );
}
```

Here, `e.target.name` refers to the `name` property given to the `<input>` DOM element.

## Updating a nested object[](#updating-a-nested-object "Link for Updating a nested object ")

Consider a nested object structure like this:

```
const [person, setPerson] = useState({

  name: 'Niki de Saint Phalle',

  artwork: {

    title: 'Blue Nana',

    city: 'Hamburg',

    image: 'https://i.imgur.com/Sd1AgUOm.jpg',

  }

});
```

If you wanted to update `person.artwork.city`, it’s clear how to do it with mutation:

```
person.artwork.city = 'New Delhi';
```

But in React, you treat state as immutable! In order to change `city`, you would first need to produce the new `artwork` object (pre-populated with data from the previous one), and then produce the new `person` object which points at the new `artwork`:

```
const nextArtwork = { ...person.artwork, city: 'New Delhi' };

const nextPerson = { ...person, artwork: nextArtwork };

setPerson(nextPerson);
```

Or, written as a single function call:

```
setPerson({

  ...person, // Copy other fields

  artwork: { // but replace the artwork

    ...person.artwork, // with the same one

    city: 'New Delhi' // but in New Delhi!

  }

});
```

This gets a bit wordy, but it works fine for many cases:

```
import { useState } from 'react';

export default function Form() {
  const [person, setPerson] = useState({
    name: 'Niki de Saint Phalle',
    artwork: {
      title: 'Blue Nana',
      city: 'Hamburg',
      image: 'https://i.imgur.com/Sd1AgUOm.jpg',
    }
  });

  function handleNameChange(e) {
    setPerson({
      ...person,
      name: e.target.value
    });
  }

  function handleTitleChange(e) {
    setPerson({
      ...person,
      artwork: {
        ...person.artwork,
        title: e.target.value
      }
    });
  }

  function handleCityChange(e) {
    setPerson({
      ...person,
      artwork: {
        ...person.artwork,
        city: e.target.value
      }
    });
  }

  function handleImageChange(e) {
    setPerson({
      ...person,
      artwork: {
        ...person.artwork,
        image: e.target.value
      }
    });
  }

  return (
    <>
      <label>
        Name:
        <input
          value={person.name}
          onChange={handleNameChange}
        />
      </label>
      <label>
        Title:
        <input
          value={person.artwork.title}
          onChange={handleTitleChange}
        />
      </label>
      <label>
        City:
        <input
          value={person.artwork.city}
          onChange={handleCityChange}
        />
      </label>
      <label>
        Image:
        <input
          value={person.artwork.image}
          onChange={handleImageChange}
        />
      </label>
      <p>
        <i>{person.artwork.title}</i>
        {' by '}
        {person.name}
        <br />
        (located in {person.artwork.city})
      </p>
      <img 
        src={person.artwork.image} 
        alt={person.artwork.title}
      />
    </>
  );
}
```

##### Deep Dive#### Objects are not really nested[](#objects-are-not-really-nested "Link for Objects are not really nested ")

An object like this appears “nested” in code:

```
let obj = {

  name: 'Niki de Saint Phalle',

  artwork: {

    title: 'Blue Nana',

    city: 'Hamburg',

    image: 'https://i.imgur.com/Sd1AgUOm.jpg',

  }

};
```

However, “nesting” is an inaccurate way to think about how objects behave. When the code executes, there is no such thing as a “nested” object. You are really looking at two different objects:

```
let obj1 = {

  title: 'Blue Nana',

  city: 'Hamburg',

  image: 'https://i.imgur.com/Sd1AgUOm.jpg',

};



let obj2 = {

  name: 'Niki de Saint Phalle',

  artwork: obj1

};
```

The `obj1` object is not “inside” `obj2`. For example, `obj3` could “point” at `obj1` too:

```
let obj1 = {

  title: 'Blue Nana',

  city: 'Hamburg',

  image: 'https://i.imgur.com/Sd1AgUOm.jpg',

};



let obj2 = {

  name: 'Niki de Saint Phalle',

  artwork: obj1

};



let obj3 = {

  name: 'Copycat',

  artwork: obj1

};
```

If you were to mutate `obj3.artwork.city`, it would affect both `obj2.artwork.city` and `obj1.city`. This is because `obj3.artwork`, `obj2.artwork`, and `obj1` are the same object. This is difficult to see when you think of objects as “nested”. Instead, they are separate objects “pointing” at each other with properties.

### Write concise update logic with Immer[](#write-concise-update-logic-with-immer "Link for Write concise update logic with Immer ")

If your state is deeply nested, you might want to consider [flattening it.](/learn/choosing-the-state-structure#avoid-deeply-nested-state) But, if you don’t want to change your state structure, you might prefer a shortcut to nested spreads. [Immer](https://github.com/immerjs/use-immer) is a popular library that lets you write using the convenient but mutating syntax and takes care of producing the copies for you. With Immer, the code you write looks like you are “breaking the rules” and mutating an object:

```
updatePerson(draft => {

  draft.artwork.city = 'Lagos';

});
```

```
{
  "dependencies": {
    "immer": "1.7.3",
    "react": "latest",
    "react-dom": "latest",
    "react-scripts": "latest",
    "use-immer": "0.5.1"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject"
  },
  "devDependencies": {}
}
```

```
import { useState } from 'react';

export default function Scoreboard() {
  const [player, setPlayer] = useState({
    firstName: 'Ranjani',
    lastName: 'Shettar',
    score: 10,
  });

  function handlePlusClick() {
    player.score++;
  }

  function handleFirstNameChange(e) {
    setPlayer({
      ...player,
      firstName: e.target.value,
    });
  }

  function handleLastNameChange(e) {
    setPlayer({
      lastName: e.target.value
    });
  }

  return (
    <>
      <label>
        Score: <b>{player.score}</b>
        {' '}
        <button onClick={handlePlusClick}>
          +1
        </button>
      </label>
      <label>
        First name:
        <input
          value={player.firstName}
          onChange={handleFirstNameChange}
        />
      </label>
      <label>
        Last name:
        <input
          value={player.lastName}
          onChange={handleLastNameChange}
        />
      </label>
    </>
  );
}
```

[PreviousQueueing a Series of State Updates](/learn/queueing-a-series-of-state-updates)

[NextUpdating Arrays in State](/learn/updating-arrays-in-state)

***

----
url: https://react.dev/reference/react-dom/components/input
----

[API Reference](/reference/react)

[Components](/reference/react-dom/components)

# \<input>[](#undefined "Link for this heading")

The [built-in browser `<input>` component](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input) lets you render different kinds of form inputs.

```
<input />
```

***

## Reference[](#reference "Link for Reference ")

### `<input>`[](#input "Link for this heading")

To display an input, render the [built-in browser `<input>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input) component.

```
<input name="myInput" />
```

***

## Usage[](#usage "Link for Usage ")

### Displaying inputs of different types[](#displaying-inputs-of-different-types "Link for Displaying inputs of different types ")

To display an input, render an `<input>` component. By default, it will be a text input. You can pass `type="checkbox"` for a checkbox, `type="radio"` for a radio button, [or one of the other input types.](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#input_types)

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
export default function MyForm() {
  return (
    <>
      <label>
        Text input: <input name="myInput" />
      </label>
      <hr />
      <label>
        Checkbox: <input type="checkbox" name="myCheckbox" />
      </label>
      <hr />
      <p>
        Radio buttons:
        <label>
          <input type="radio" name="myRadio" value="option1" />
          Option 1
        </label>
        <label>
          <input type="radio" name="myRadio" value="option2" />
          Option 2
        </label>
        <label>
          <input type="radio" name="myRadio" value="option3" />
          Option 3
        </label>
      </p>
    </>
  );
}
```

***

### Providing a label for an input[](#providing-a-label-for-an-input "Link for Providing a label for an input ")

Typically, you will place every `<input>` inside a [`<label>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/label) tag. This tells the browser that this label is associated with that input. When the user clicks the label, the browser will automatically focus the input. It’s also essential for accessibility: a screen reader will announce the label caption when the user focuses the associated input.

If you can’t nest `<input>` into a `<label>`, associate them by passing the same ID to `<input id>` and [`<label htmlFor>`.](https://developer.mozilla.org/en-US/docs/Web/API/HTMLLabelElement/htmlFor) To avoid conflicts between multiple instances of one component, generate such an ID with [`useId`.](/reference/react/useId)

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useId } from 'react';

export default function Form() {
  const ageInputId = useId();
  return (
    <>
      <label>
        Your first name:
        <input name="firstName" />
      </label>
      <hr />
      <label htmlFor={ageInputId}>Your age:</label>
      <input id={ageInputId} name="age" type="number" />
    </>
  );
}
```

***

### Providing an initial value for an input[](#providing-an-initial-value-for-an-input "Link for Providing an initial value for an input ")

You can optionally specify the initial value for any input. Pass it as the `defaultValue` string for text inputs. Checkboxes and radio buttons should specify the initial value with the `defaultChecked` boolean instead.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
export default function MyForm() {
  return (
    <>
      <label>
        Text input: <input name="myInput" defaultValue="Some initial value" />
      </label>
      <hr />
      <label>
        Checkbox: <input type="checkbox" name="myCheckbox" defaultChecked={true} />
      </label>
      <hr />
      <p>
        Radio buttons:
        <label>
          <input type="radio" name="myRadio" value="option1" />
          Option 1
        </label>
        <label>
          <input
            type="radio"
            name="myRadio"
            value="option2"
            defaultChecked={true}
          />
          Option 2
        </label>
        <label>
          <input type="radio" name="myRadio" value="option3" />
          Option 3
        </label>
      </p>
    </>
  );
}
```

***

### Reading the input values when submitting a form[](#reading-the-input-values-when-submitting-a-form "Link for Reading the input values when submitting a form ")

Add a [`<form>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form) around your inputs with a [`<button type="submit">`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button) inside. It will call your `<form onSubmit>` event handler. By default, the browser will send the form data to the current URL and refresh the page. You can override that behavior by calling `e.preventDefault()`. Read the form data with [`new FormData(e.target)`](https://developer.mozilla.org/en-US/docs/Web/API/FormData).

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
export default function MyForm() {
  function handleSubmit(e) {
    // Prevent the browser from reloading the page
    e.preventDefault();

    // Read the form data
    const form = e.target;
    const formData = new FormData(form);

    // You can pass formData as a fetch body directly:
    fetch('/some-api', { method: form.method, body: formData });

    // Or you can work with it as a plain object:
    const formJson = Object.fromEntries(formData.entries());
    console.log(formJson);
  }

  return (
    <form method="post" onSubmit={handleSubmit}>
      <label>
        Text input: <input name="myInput" defaultValue="Some initial value" />
      </label>
      <hr />
      <label>
        Checkbox: <input type="checkbox" name="myCheckbox" defaultChecked={true} />
      </label>
      <hr />
      <p>
        Radio buttons:
        <label><input type="radio" name="myRadio" value="option1" /> Option 1</label>
        <label><input type="radio" name="myRadio" value="option2" defaultChecked={true} /> Option 2</label>
        <label><input type="radio" name="myRadio" value="option3" /> Option 3</label>
      </p>
      <hr />
      <button type="reset">Reset form</button>
      <button type="submit">Submit form</button>
    </form>
  );
}
```

### Note

Give a `name` to every `<input>`, for example `<input name="firstName" defaultValue="Taylor" />`. The `name` you specified will be used as a key in the form data, for example `{ firstName: "Taylor" }`.

### Pitfall

By default, a `<button>` inside a `<form>` without a `type` attribute will submit it. This can be surprising! If you have your own custom `Button` React component, consider using [`<button type="button">`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button) instead of `<button>` (with no type). Then, to be explicit, use `<button type="submit">` for buttons that *are* supposed to submit the form.

***

### Controlling an input with a state variable[](#controlling-an-input-with-a-state-variable "Link for Controlling an input with a state variable ")

An input like `<input />` is *uncontrolled.* Even if you [pass an initial value](#providing-an-initial-value-for-an-input) like `<input defaultValue="Initial text" />`, your JSX only specifies the initial value. It does not control what the value should be right now.

**To render a *controlled* input, pass the `value` prop to it (or `checked` for checkboxes and radios).** React will force the input to always have the `value` you passed. Usually, you would do this by declaring a [state variable:](/reference/react/useState)

```
function Form() {

  const [firstName, setFirstName] = useState(''); // Declare a state variable...

  // ...

  return (

    <input

      value={firstName} // ...force the input's value to match the state variable...

      onChange={e => setFirstName(e.target.value)} // ... and update the state variable on any edits!

    />

  );

}
```

A controlled input makes sense if you needed state anyway—for example, to re-render your UI on every edit:

```
function Form() {

  const [firstName, setFirstName] = useState('');

  return (

    <>

      <label>

        First name:

        <input value={firstName} onChange={e => setFirstName(e.target.value)} />

      </label>

      {firstName !== '' && <p>Your name is {firstName}.</p>}

      ...
```

It’s also useful if you want to offer multiple ways to adjust the input state (for example, by clicking a button):

```
function Form() {

  // ...

  const [age, setAge] = useState('');

  const ageAsNumber = Number(age);

  return (

    <>

      <label>

        Age:

        <input

          value={age}

          onChange={e => setAge(e.target.value)}

          type="number"

        />

        <button onClick={() => setAge(ageAsNumber + 10)}>

          Add 10 years

        </button>
```

The `value` you pass to controlled components should not be `undefined` or `null`. If you need the initial value to be empty (such as with the `firstName` field below), initialize your state variable to an empty string (`''`).

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function Form() {
  const [firstName, setFirstName] = useState('');
  const [age, setAge] = useState('20');
  const ageAsNumber = Number(age);
  return (
    <>
      <label>
        First name:
        <input
          value={firstName}
          onChange={e => setFirstName(e.target.value)}
        />
      </label>
      <label>
        Age:
        <input
          value={age}
          onChange={e => setAge(e.target.value)}
          type="number"
        />
        <button onClick={() => setAge(ageAsNumber + 10)}>
          Add 10 years
        </button>
      </label>
      {firstName !== '' &&
        <p>Your name is {firstName}.</p>
      }
      {ageAsNumber > 0 &&
        <p>Your age is {ageAsNumber}.</p>
      }
    </>
  );
}
```

### Pitfall

**If you pass `value` without `onChange`, it will be impossible to type into the input.** When you control an input by passing some `value` to it, you *force* it to always have the value you passed. So if you pass a state variable as a `value` but forget to update that state variable synchronously during the `onChange` event handler, React will revert the input after every keystroke back to the `value` that you specified.

***

### Optimizing re-rendering on every keystroke[](#optimizing-re-rendering-on-every-keystroke "Link for Optimizing re-rendering on every keystroke ")

When you use a controlled input, you set the state on every keystroke. If the component containing your state re-renders a large tree, this can get slow. There’s a few ways you can optimize re-rendering performance.

For example, suppose you start with a form that re-renders all page content on every keystroke:

```
function App() {

  const [firstName, setFirstName] = useState('');

  return (

    <>

      <form>

        <input value={firstName} onChange={e => setFirstName(e.target.value)} />

      </form>

      <PageContent />

    </>

  );

}
```

Since `<PageContent />` doesn’t rely on the input state, you can move the input state into its own component:

```
function App() {

  return (

    <>

      <SignupForm />

      <PageContent />

    </>

  );

}



function SignupForm() {

  const [firstName, setFirstName] = useState('');

  return (

    <form>

      <input value={firstName} onChange={e => setFirstName(e.target.value)} />

    </form>

  );

}
```

This significantly improves performance because now only `SignupForm` re-renders on every keystroke.

If there is no way to avoid re-rendering (for example, if `PageContent` depends on the search input’s value), [`useDeferredValue`](/reference/react/useDeferredValue#deferring-re-rendering-for-a-part-of-the-ui) lets you keep the controlled input responsive even in the middle of a large re-render.

***

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### My text input doesn’t update when I type into it[](#my-text-input-doesnt-update-when-i-type-into-it "Link for My text input doesn’t update when I type into it ")

If you render an input with `value` but no `onChange`, you will see an error in the console:

```
// 🔴 Bug: controlled text input with no onChange handler

<input value={something} />
```

Console

You provided a `value` prop to a form field without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultValue`. Otherwise, set either `onChange` or `readOnly`.

As the error message suggests, if you only wanted to [specify the *initial* value,](#providing-an-initial-value-for-an-input) pass `defaultValue` instead:

```
// ✅ Good: uncontrolled input with an initial value

<input defaultValue={something} />
```

If you want [to control this input with a state variable,](#controlling-an-input-with-a-state-variable) specify an `onChange` handler:

```
// ✅ Good: controlled input with onChange

<input value={something} onChange={e => setSomething(e.target.value)} />
```

If the value is intentionally read-only, add a `readOnly` prop to suppress the error:

```
// ✅ Good: readonly controlled input without on change

<input value={something} readOnly={true} />
```

***

### My checkbox doesn’t update when I click on it[](#my-checkbox-doesnt-update-when-i-click-on-it "Link for My checkbox doesn’t update when I click on it ")

If you render a checkbox with `checked` but no `onChange`, you will see an error in the console:

```
// 🔴 Bug: controlled checkbox with no onChange handler

<input type="checkbox" checked={something} />
```

Console

You provided a `checked` prop to a form field without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultChecked`. Otherwise, set either `onChange` or `readOnly`.

As the error message suggests, if you only wanted to [specify the *initial* value,](#providing-an-initial-value-for-an-input) pass `defaultChecked` instead:

```
// ✅ Good: uncontrolled checkbox with an initial value

<input type="checkbox" defaultChecked={something} />
```

If you want [to control this checkbox with a state variable,](#controlling-an-input-with-a-state-variable) specify an `onChange` handler:

```
// ✅ Good: controlled checkbox with onChange

<input type="checkbox" checked={something} onChange={e => setSomething(e.target.checked)} />
```

### Pitfall

You need to read `e.target.checked` rather than `e.target.value` for checkboxes.

If the checkbox is intentionally read-only, add a `readOnly` prop to suppress the error:

```
// ✅ Good: readonly controlled input without on change

<input type="checkbox" checked={something} readOnly={true} />
```

***

### My input caret jumps to the beginning on every keystroke[](#my-input-caret-jumps-to-the-beginning-on-every-keystroke "Link for My input caret jumps to the beginning on every keystroke ")

If you [control an input,](#controlling-an-input-with-a-state-variable) you must update its state variable to the input’s value from the DOM during `onChange`.

You can’t update it to something other than `e.target.value` (or `e.target.checked` for checkboxes):

```
function handleChange(e) {

  // 🔴 Bug: updating an input to something other than e.target.value

  setFirstName(e.target.value.toUpperCase());

}
```

You also can’t update it asynchronously:

```
function handleChange(e) {

  // 🔴 Bug: updating an input asynchronously

  setTimeout(() => {

    setFirstName(e.target.value);

  }, 100);

}
```

To fix your code, update it synchronously to `e.target.value`:

```
function handleChange(e) {

  // ✅ Updating a controlled input to e.target.value synchronously

  setFirstName(e.target.value);

}
```

If this doesn’t fix the problem, it’s possible that the input gets removed and re-added from the DOM on every keystroke. This can happen if you’re accidentally [resetting state](/learn/preserving-and-resetting-state) on every re-render, for example if the input or one of its parents always receives a different `key` attribute, or if you nest component function definitions (which is not supported and causes the “inner” component to always be considered a different tree).

***

***

----
url: https://react.dev/blog/2024/02/15/react-labs-what-we-have-been-working-on-february-2024
----

[Blog](/blog)

# React Labs: What We've Been Working On – February 2024[](#undefined "Link for this heading")

February 15, 2024 by [Joseph Savona](https://twitter.com/en_JS), [Ricky Hanlon](https://twitter.com/rickhanlonii), [Andrew Clark](https://twitter.com/acdlite), [Matt Carroll](https://twitter.com/mattcarrollcode), and [Dan Abramov](https://bsky.app/profile/danabra.mov).

***

In React Labs posts, we write about projects in active research and development. We’ve made significant progress since our [last update](/blog/2023/03/22/react-labs-what-we-have-been-working-on-march-2023), and we’d like to share our progress.

***

## React Compiler[](#react-compiler "Link for React Compiler ")

React Compiler is no longer a research project: the compiler now powers instagram.com in production, and we are working to ship the compiler across additional surfaces at Meta and to prepare the first open source release.

As discussed in our [previous post](/blog/2023/03/22/react-labs-what-we-have-been-working-on-march-2023#react-optimizing-compiler), React can *sometimes* re-render too much when state changes. Since the early days of React our solution for such cases has been manual memoization. In our current APIs, this means applying the [`useMemo`](/reference/react/useMemo), [`useCallback`](/reference/react/useCallback), and [`memo`](/reference/react/memo) APIs to manually tune how much React re-renders on state changes. But manual memoization is a compromise. It clutters up our code, is easy to get wrong, and requires extra work to keep up to date.

Manual memoization is a reasonable compromise, but we weren’t satisfied. Our vision is for React to *automatically* re-render just the right parts of the UI when state changes, *without compromising on React’s core mental model*. We believe that React’s approach — UI as a simple function of state, with standard JavaScript values and idioms — is a key part of why React has been approachable for so many developers. That’s why we’ve invested in building an optimizing compiler for React.

JavaScript is a notoriously challenging language to optimize, thanks to its loose rules and dynamic nature. React Compiler is able to compile code safely by modeling both the rules of JavaScript *and* the “rules of React”. For example, React components must be idempotent — returning the same value given the same inputs — and can’t mutate props or state values. These rules limit what developers can do and help to carve out a safe space for the compiler to optimize.

Of course, we understand that developers sometimes bend the rules a bit, and our goal is to make React Compiler work out of the box on as much code as possible. The compiler attempts to detect when code doesn’t strictly follow React’s rules and will either compile the code where safe or skip compilation if it isn’t safe. We’re testing against Meta’s large and varied codebase in order to help validate this approach.

For developers who are curious about making sure their code follows React’s rules, we recommend [enabling Strict Mode](/reference/react/StrictMode) and [configuring React’s ESLint plugin](/learn/editor-setup#linting). These tools can help to catch subtle bugs in your React code, improving the quality of your applications today, and future-proofs your applications for upcoming features such as React Compiler. We are also working on consolidated documentation of the rules of React and updates to our ESLint plugin to help teams understand and apply these rules to create more robust apps.

To see the compiler in action, you can check out our [talk from last fall](https://www.youtube.com/watch?v=qOQClO3g8-Y). At the time of the talk, we had early experimental data from trying React Compiler on one page of instagram.com. Since then, we shipped the compiler to production across instagram.com. We’ve also expanded our team to accelerate the rollout to additional surfaces at Meta and to open source. We’re excited about the path ahead and will have more to share in the coming months.

## Actions[](#actions "Link for Actions ")

We [previously shared](/blog/2023/03/22/react-labs-what-we-have-been-working-on-march-2023#react-server-components) that we were exploring solutions for sending data from the client to the server with Server Actions, so that you can execute database mutations and implement forms. During development of Server Actions, we extended these APIs to support data handling in client-only applications as well.

We refer to this broader collection of features as simply “Actions”. Actions allow you to pass a function to DOM elements such as [`<form/>`](/reference/react-dom/components/form):

```
<form action={search}>

  <input name="query" />

  <button type="submit">Search</button>

</form>
```

The `action` function can operate synchronously or asynchronously. You can define them on the client side using standard JavaScript or on the server with the [`'use server'`](/reference/rsc/use-server) directive. When using an action, React will manage the life cycle of the data submission for you, providing hooks like [`useFormStatus`](/reference/react-dom/hooks/useFormStatus), and [`useActionState`](/reference/react/useActionState) to access the current state and response of the form action.

By default, Actions are submitted within a [transition](/reference/react/useTransition), keeping the current page interactive while the action is processing. Since Actions support async functions, we’ve also added the ability to use `async/await` in transitions. This allows you to show pending UI with the `isPending` state of a transition when an async request like `fetch` starts, and show the pending UI all the way through the update being applied.

Alongside Actions, we’re introducing a feature named [`useOptimistic`](/reference/react/useOptimistic) for managing optimistic state updates. With this hook, you can apply temporary updates that are automatically reverted once the final state commits. For Actions, this allows you to optimistically set the final state of the data on the client, assuming the submission is successful, and revert to the value for data received from the server. It works using regular `async`/`await`, so it works the same whether you’re using `fetch` on the client, or a Server Action from the server.

Library authors can implement custom `action={fn}` props in their own components with `useTransition`. Our intent is for libraries to adopt the Actions pattern when designing their component APIs, to provide a consistent experience for React developers. For example, if your library provides a `<Calendar onSelect={eventHandler}>` component, consider also exposing a `<Calendar selectAction={action}>` API, too.

While we initially focused on Server Actions for client-server data transfer, our philosophy for React is to provide the same programming model across all platforms and environments. When possible, if we introduce a feature on the client, we aim to make it also work on the server, and vice versa. This philosophy allows us to create a single set of APIs that work no matter where your app runs, making it easier to upgrade to different environments later.

Actions are now available in the Canary channel and will ship in the next release of React.

## New Features in React Canary[](#new-features-in-react-canary "Link for New Features in React Canary ")

We introduced [React Canaries](/blog/2023/05/03/react-canaries) as an option to adopt individual new stable features as soon as their design is close to final, before they’re released in a stable semver version.

Canaries are a change to the way we develop React. Previously, features would be researched and built privately inside of Meta, so users would only see the final polished product when released to Stable. With Canaries, we’re building in public with the help of the community to finalize features we share in the React Labs blog series. This means you hear about new features sooner, as they’re being finalized instead of after they’re complete.

React Server Components, Asset Loading, Document Metadata, and Actions have all landed in the React Canary, and we’ve added docs for these features on react.dev:

* **Directives**: [`"use client"`](/reference/rsc/use-client) and [`"use server"`](/reference/rsc/use-server) are bundler features designed for full-stack React frameworks. They mark the “split points” between the two environments: `"use client"` instructs the bundler to generate a `<script>` tag (like [Astro Islands](https://docs.astro.build/en/concepts/islands/#creating-an-island)), while `"use server"` tells the bundler to generate a POST endpoint (like [tRPC Mutations](https://trpc.io/docs/concepts)). Together, they let you write reusable components that compose client-side interactivity with the related server-side logic.

* **Document Metadata**: we added built-in support for rendering [`<title>`](/reference/react-dom/components/title), [`<meta>`](/reference/react-dom/components/meta), and metadata [`<link>`](/reference/react-dom/components/link) tags anywhere in your component tree. These work the same way in all environments, including fully client-side code, SSR, and RSC. This provides built-in support for features pioneered by libraries like [React Helmet](https://github.com/nfl/react-helmet).

* **Asset Loading**: we integrated Suspense with the loading lifecycle of resources such as stylesheets, fonts, and scripts so that React takes them into account to determine whether the content in elements like [`<style>`](/reference/react-dom/components/style), [`<link>`](/reference/react-dom/components/link), and [`<script>`](/reference/react-dom/components/script) are ready to be displayed. We’ve also added new [Resource Loading APIs](/reference/react-dom#resource-preloading-apis) like `preload` and `preinit` to provide greater control for when a resource should load and initialize.

* **Actions**: As shared above, we’ve added Actions to manage sending data from the client to the server. You can add `action` to elements like [`<form/>`](/reference/react-dom/components/form), access the status with [`useFormStatus`](/reference/react-dom/hooks/useFormStatus), handle the result with [`useActionState`](/reference/react/useActionState), and optimistically update the UI with [`useOptimistic`](/reference/react/useOptimistic).

Since all of these features work together, it’s difficult to release them in the Stable channel individually. Releasing Actions without the complementary hooks for accessing form states would limit the practical usability of Actions. Introducing React Server Components without integrating Server Actions would complicate modifying data on the server.

Before we can release a set of features to the Stable channel, we need to ensure they work cohesively and developers have everything they need to use them in production. React Canaries allow us to develop these features individually, and release the stable APIs incrementally until the entire feature set is complete.

The current set of features in React Canary are complete and ready to release.

## The Next Major Version of React[](#the-next-major-version-of-react "Link for The Next Major Version of React ")

After a couple of years of iteration, `react@canary` is now ready to ship to `react@latest`. The new features mentioned above are compatible with any environment your app runs in, providing everything needed for production use. Since Asset Loading and Document Metadata may be a breaking change for some apps, the next version of React will be a major version: **React 19**.

There’s still more to be done to prepare for release. In React 19, we’re also adding long-requested improvements which require breaking changes like support for Web Components. Our focus now is to land these changes, prepare for release, finalize docs for new features, and publish announcements for what’s included.

We’ll share more information about everything React 19 includes, how to adopt the new client features, and how to build support for React Server Components in the coming months.

## Offscreen (renamed to Activity).[](#offscreen-renamed-to-activity "Link for Offscreen (renamed to Activity). ")

Since our last update, we’ve renamed a capability we’re researching from “Offscreen” to “Activity”. The name “Offscreen” implied that it only applied to parts of the app that were not visible, but while researching the feature we realized that it’s possible for parts of the app to be visible and inactive, such as content behind a modal. The new name more closely reflects the behavior of marking certain parts of the app “active” or “inactive”.

Activity is still under research and our remaining work is to finalize the primitives that are exposed to library developers. We’ve deprioritized this area while we focus on shipping features that are more complete.

***

In addition to this update, our team has presented at conferences and made appearances on podcasts to speak more on our work and answer questions.

* [Sathya Gunasekaran](https://github.com/gsathya) spoke about the React Compiler at the [React India](https://www.youtube.com/watch?v=kjOacmVsLSE) conference

* [Dan Abramov](/community/team#dan-abramov) gave a talk at [RemixConf](https://www.youtube.com/watch?v=zMf_xeGPn6s) titled “React from Another Dimension” which explores an alternative history of how React Server Components and Actions could have been created

* [Dan Abramov](/community/team#dan-abramov) was interviewed on [the Changelog’s JS Party podcast](https://changelog.com/jsparty/311) about React Server Components

* [Matt Carroll](/community/team#matt-carroll) was interviewed on the [Front-End Fire podcast](https://www.buzzsprout.com/2226499/14462424-interview-the-two-reacts-with-rachel-nabors-evan-bacon-and-matt-carroll) where he discussed [The Two Reacts](https://overreacted.io/the-two-reacts/)

Thanks [Lauren Tan](https://twitter.com/potetotes), [Sophie Alpert](https://twitter.com/sophiebits), [Jason Bonta](https://threads.net/someextent), [Eli White](https://twitter.com/Eli_White), and [Sathya Gunasekaran](https://twitter.com/_gsathya) for reviewing this post.

Thanks for reading, and [see you at React Conf](https://conf.react.dev/)!

[PreviousReact 19 RC Upgrade Guide](/blog/2024/04/25/react-19-upgrade-guide)

[NextReact Canaries: Enabling Incremental Feature Rollout Outside Meta](/blog/2023/05/03/react-canaries)

***

----
url: https://react.dev/blog/2021/12/17/react-conf-2021-recap
----

[Blog](/blog)

# React Conf 2021 Recap[](#undefined "Link for this heading")

December 17, 2021 by [Jesslyn Tannady](https://twitter.com/jtannady) and [Rick Hanlon](https://twitter.com/rickhanlonii)

***

Last week we hosted our 6th React Conf. In previous years, we’ve used the React Conf stage to deliver industry changing announcements such as [*React Native*](https://engineering.fb.com/2015/03/26/android/react-native-bringing-modern-web-techniques-to-mobile/) and [*React Hooks*](https://reactjs.org/docs/hooks-intro.html). This year, we shared our multi-platform vision for React, starting with the release of React 18 and gradual adoption of concurrent features.

***

This was the first time React Conf was hosted online, and it was streamed for free, translated to 8 different languages. Participants from all over the world joined our conference Discord and the replay event for accessibility in all timezones. Over 50,000 people registered, with over 60,000 views of 19 talks, and 5,000 participants in Discord across both events.

All the talks are [available to stream online](https://www.youtube.com/watch?v=FZ0cG47msEk\&list=PLNG_1j3cPCaZZ7etkzWA7JfdmKWT0pMsa).

Here’s a summary of what was shared on stage:

## React 18 and concurrent features[](#react-18-and-concurrent-features "Link for React 18 and concurrent features ")

In the keynote, we shared our vision for the future of React starting with React 18.

React 18 adds the long-awaited concurrent renderer and updates to Suspense without any major breaking changes. Apps can upgrade to React 18 and begin gradually adopting concurrent features with the amount of effort on par with any other major release.

**This means there is no concurrent mode, only concurrent features.**

In the keynote, we also shared our vision for Suspense, Server Components, new React working groups, and our long-term many-platform vision for React Native.

Watch the full keynote from [Andrew Clark](https://twitter.com/acdlite), [Juan Tejada](https://twitter.com/_jstejada), [Lauren Tan](https://twitter.com/potetotes), and [Rick Hanlon](https://twitter.com/rickhanlonii) here:

## React 18 for Application Developers[](#react-18-for-application-developers "Link for React 18 for Application Developers ")

In the keynote, we also announced that the React 18 RC is available to try now. Pending further feedback, this is the exact version of React that we will publish to stable early next year.

To try the React 18 RC, upgrade your dependencies:

```
npm install react@rc react-dom@rc
```

and switch to the new `createRoot` API:

```
// before

const container = document.getElementById('root');

ReactDOM.render(<App />, container);



// after

const container = document.getElementById('root');

const root = ReactDOM.createRoot(container);

root.render(<App/>);
```

For a demo of upgrading to React 18, see [Shruti Kapoor](https://twitter.com/shrutikapoor08)’s talk here:

## Streaming Server Rendering with Suspense[](#streaming-server-rendering-with-suspense "Link for Streaming Server Rendering with Suspense ")

React 18 also includes improvements to server-side rendering performance using Suspense.

Streaming server rendering lets you generate HTML from React components on the server, and stream that HTML to your users. In React 18, you can use `Suspense` to break down your app into smaller independent units which can be streamed independently of each other without blocking the rest of the app. This means users will see your content sooner and be able to start interacting with it much faster.

For a deep dive, see [Shaundai Person](https://twitter.com/shaundai)’s talk here:

## The first React working group[](#the-first-react-working-group "Link for The first React working group ")

For React 18, we created our first Working Group to collaborate with a panel of experts, developers, library maintainers, and educators. Together we worked to create our gradual adoption strategy and refine new APIs such as `useId`, `useSyncExternalStore`, and `useInsertionEffect`.

For an overview of this work, see [Aakansha’ Doshi](https://twitter.com/aakansha1216)’s talk:

## React Developer Tooling[](#react-developer-tooling "Link for React Developer Tooling ")

To support the new features in this release, we also announced the newly formed React DevTools team and a new Timeline Profiler to help developers debug their React apps.

For more information and a demo of new DevTools features, see [Brian Vaughn](https://twitter.com/brian_d_vaughn)’s talk:

## React without memo[](#react-without-memo "Link for React without memo ")

Looking further into the future, [Xuan Huang (黄玄)](https://twitter.com/Huxpro) shared an update from our React Labs research into an auto-memoizing compiler. Check out this talk for more information and a demo of the compiler prototype:

## React docs keynote[](#react-docs-keynote "Link for React docs keynote ")

[Rachel Nabors](https://twitter.com/rachelnabors) kicked off a section of talks about learning and designing with React with a keynote about our investment in React’s new docs ([now shipped as react.dev](/blog/2023/03/16/introducing-react-dev)):

## And more…[](#and-more "Link for And more… ")

## Thank you[](#thank-you "Link for Thank you ")

This was our first year planning a conference ourselves, and we have a lot of people to thank.

First, thanks to all of our speakers [Aakansha Doshi](https://twitter.com/aakansha1216), [Andrew Clark](https://twitter.com/acdlite), [Brian Vaughn](https://twitter.com/brian_d_vaughn), [Daishi Kato](https://twitter.com/dai_shi), [Debbie O’Brien](https://twitter.com/debs_obrien), [Delba de Oliveira](https://twitter.com/delba_oliveira), [Diego Haz](https://twitter.com/diegohaz), [Eric Rozell](https://twitter.com/EricRozell), [Helen Lin](https://twitter.com/wizardlyhel), [Juan Tejada](https://twitter.com/_jstejada), [Lauren Tan](https://twitter.com/potetotes), [Linton Ye](https://twitter.com/lintonye), [Lyle Troxell](https://twitter.com/lyle), [Rachel Nabors](https://twitter.com/rachelnabors), [Rick Hanlon](https://twitter.com/rickhanlonii), [Robert Balicki](https://twitter.com/StatisticsFTW), [Roman Rädle](https://twitter.com/raedle), [Sarah Rainsberger](https://twitter.com/sarah11918), [Shaundai Person](https://twitter.com/shaundai), [Shruti Kapoor](https://twitter.com/shrutikapoor08), [Steven Moyes](https://twitter.com/moyessa), [Tafu Nakazaki](https://twitter.com/hawaiiman0), and [Xuan Huang (黄玄)](https://twitter.com/Huxpro).

Thanks to everyone who helped provide feedback on talks including [Andrew Clark](https://twitter.com/acdlite), [Dan Abramov](https://bsky.app/profile/danabra.mov), [Dave McCabe](https://twitter.com/mcc_abe), [Eli White](https://twitter.com/Eli_White), [Joe Savona](https://twitter.com/en_JS), [Lauren Tan](https://twitter.com/potetotes), [Rachel Nabors](https://twitter.com/rachelnabors), and [Tim Yung](https://twitter.com/yungsters).

[PreviousHow to Upgrade to React 18](/blog/2022/03/08/react-18-upgrade-guide)

[NextThe Plan for React 18](/blog/2021/06/08/the-plan-for-react-18)

***

----
url: https://react.dev/learn/react-compiler/incremental-adoption
----

[Learn React](/learn)

[React Compiler](/learn/react-compiler)

# Incremental Adoption[](#undefined "Link for this heading")

React Compiler can be adopted incrementally, allowing you to try it on specific parts of your codebase first. This guide shows you how to gradually roll out the compiler in existing projects.

### You will learn

* Why incremental adoption is recommended
* Using Babel overrides for directory-based adoption
* Using the “use memo” directive for opt-in compilation
* Using the “use no memo” directive to exclude components
* Runtime feature flags with gating
* Monitoring your adoption progress

## Why Incremental Adoption?[](#why-incremental-adoption "Link for Why Incremental Adoption? ")

React Compiler is designed to optimize your entire codebase automatically, but you don’t have to adopt it all at once. Incremental adoption gives you control over the rollout process, letting you test the compiler on small parts of your app before expanding to the rest.

Starting small helps you build confidence in the compiler’s optimizations. You can verify that your app behaves correctly with compiled code, measure performance improvements, and identify any edge cases specific to your codebase. This approach is especially valuable for production applications where stability is critical.

Incremental adoption also makes it easier to address any Rules of React violations the compiler might find. Instead of fixing violations across your entire codebase at once, you can tackle them systematically as you expand compiler coverage. This keeps the migration manageable and reduces the risk of introducing bugs.

By controlling which parts of your code get compiled, you can also run A/B tests to measure the real-world impact of the compiler’s optimizations. This data helps you make informed decisions about full adoption and demonstrates the value to your team.

## Approaches to Incremental Adoption[](#approaches-to-incremental-adoption "Link for Approaches to Incremental Adoption ")

There are three main approaches to adopt React Compiler incrementally:

1. **Babel overrides** - Apply the compiler to specific directories
2. **Opt-in with “use memo”** - Only compile components that explicitly opt in
3. **Runtime gating** - Control compilation with feature flags

All approaches allow you to test the compiler on specific parts of your application before full rollout.

## Directory-Based Adoption with Babel Overrides[](#directory-based-adoption "Link for Directory-Based Adoption with Babel Overrides ")

Babel’s `overrides` option lets you apply different plugins to different parts of your codebase. This is ideal for gradually adopting React Compiler directory by directory.

### Basic Configuration[](#basic-configuration "Link for Basic Configuration ")

Start by applying the compiler to a specific directory:

```
// babel.config.js

module.exports = {

  plugins: [

    // Global plugins that apply to all files

  ],

  overrides: [

    {

      test: './src/modern/**/*.{js,jsx,ts,tsx}',

      plugins: [

        'babel-plugin-react-compiler'

      ]

    }

  ]

};
```

### Expanding Coverage[](#expanding-coverage "Link for Expanding Coverage ")

As you gain confidence, add more directories:

```
// babel.config.js

module.exports = {

  plugins: [

    // Global plugins

  ],

  overrides: [

    {

      test: ['./src/modern/**/*.{js,jsx,ts,tsx}', './src/features/**/*.{js,jsx,ts,tsx}'],

      plugins: [

        'babel-plugin-react-compiler'

      ]

    },

    {

      test: './src/legacy/**/*.{js,jsx,ts,tsx}',

      plugins: [

        // Different plugins for legacy code

      ]

    }

  ]

};
```

### With Compiler Options[](#with-compiler-options "Link for With Compiler Options ")

You can also configure compiler options per override:

```
// babel.config.js

module.exports = {

  plugins: [],

  overrides: [

    {

      test: './src/experimental/**/*.{js,jsx,ts,tsx}',

      plugins: [

        ['babel-plugin-react-compiler', {

          // options ...

        }]

      ]

    },

    {

      test: './src/production/**/*.{js,jsx,ts,tsx}',

      plugins: [

        ['babel-plugin-react-compiler', {

          // options ...

        }]

      ]

    }

  ]

};
```

## Opt-in Mode with “use memo”[](#opt-in-mode-with-use-memo "Link for Opt-in Mode with “use memo” ")

For maximum control, you can use `compilationMode: 'annotation'` to only compile components and hooks that explicitly opt in with the `"use memo"` directive.

### Note

This approach gives you fine-grained control over individual components and hooks. It’s useful when you want to test the compiler on specific components without affecting entire directories.

### Annotation Mode Configuration[](#annotation-mode-configuration "Link for Annotation Mode Configuration ")

```
// babel.config.js

module.exports = {

  plugins: [

    ['babel-plugin-react-compiler', {

      compilationMode: 'annotation',

    }],

  ],

};
```

### Using the Directive[](#using-the-directive "Link for Using the Directive ")

Add `"use memo"` at the beginning of functions you want to compile:

```
function TodoList({ todos }) {

  "use memo"; // Opt this component into compilation



  const sortedTodos = todos.slice().sort();



  return (

    <ul>

      {sortedTodos.map(todo => (

        <TodoItem key={todo.id} todo={todo} />

      ))}

    </ul>

  );

}



function useSortedData(data) {

  "use memo"; // Opt this hook into compilation



  return data.slice().sort();

}
```

With `compilationMode: 'annotation'`, you must:

* Add `"use memo"` to every component you want optimized
* Add `"use memo"` to every custom hook
* Remember to add it to new components

This gives you precise control over which components are compiled while you evaluate the compiler’s impact.

## Runtime Feature Flags with Gating[](#runtime-feature-flags-with-gating "Link for Runtime Feature Flags with Gating ")

The `gating` option enables you to control compilation at runtime using feature flags. This is useful for running A/B tests or gradually rolling out the compiler based on user segments.

### How Gating Works[](#how-gating-works "Link for How Gating Works ")

The compiler wraps optimized code in a runtime check. If the gate returns `true`, the optimized version runs. Otherwise, the original code runs.

### Gating Configuration[](#gating-configuration "Link for Gating Configuration ")

```
// babel.config.js

module.exports = {

  plugins: [

    ['babel-plugin-react-compiler', {

      gating: {

        source: 'ReactCompilerFeatureFlags',

        importSpecifierName: 'isCompilerEnabled',

      },

    }],

  ],

};
```

### Implementing the Feature Flag[](#implementing-the-feature-flag "Link for Implementing the Feature Flag ")

Create a module that exports your gating function:

```
// ReactCompilerFeatureFlags.js

export function isCompilerEnabled() {

  // Use your feature flag system

  return getFeatureFlag('react-compiler-enabled');

}
```

## Troubleshooting Adoption[](#troubleshooting-adoption "Link for Troubleshooting Adoption ")

If you encounter issues during adoption:

1. Use `"use no memo"` to temporarily exclude problematic components
2. Check the [debugging guide](/learn/react-compiler/debugging) for common issues
3. Fix Rules of React violations identified by the ESLint plugin
4. Consider using `compilationMode: 'annotation'` for more gradual adoption

## Next Steps[](#next-steps "Link for Next Steps ")

* Read the [configuration guide](/reference/react-compiler/configuration) for more options
* Learn about [debugging techniques](/learn/react-compiler/debugging)
* Check the [API reference](/reference/react-compiler/configuration) for all compiler options

[PreviousInstallation](/learn/react-compiler/installation)

[NextDebugging and Troubleshooting](/learn/react-compiler/debugging)

***

----
url: https://18.react.dev/learn/escape-hatches
----

```
const ref = useRef(0);
```

Like state, refs are retained by React between re-renders. However, setting state re-renders a component. Changing a ref does not! You can access the current value of that ref through the `ref.current` property.

```
import { useRef } from 'react';

export default function Counter() {
  let ref = useRef(0);

  function handleClick() {
    ref.current = ref.current + 1;
    alert('You clicked ' + ref.current + ' times!');
  }

  return (
    <button onClick={handleClick}>
      Click me!
    </button>
  );
}
```

A ref is like a secret pocket of your component that React doesn’t track. For example, you can use refs to store [timeout IDs](https://developer.mozilla.org/en-US/docs/Web/API/setTimeout#return_value), [DOM elements](https://developer.mozilla.org/en-US/docs/Web/API/Element), and other objects that don’t impact the component’s rendering output.

## Ready to learn this topic?

Read **[Referencing Values with Refs](/learn/referencing-values-with-refs)** to learn how to use refs to remember information.

[Read More](/learn/referencing-values-with-refs)

***

## Manipulating the DOM with refs[](#manipulating-the-dom-with-refs "Link for Manipulating the DOM with refs ")

React automatically updates the DOM to match your render output, so your components won’t often need to manipulate it. However, sometimes you might need access to the DOM elements managed by React—for example, to focus a node, scroll to it, or measure its size and position. There is no built-in way to do those things in React, so you will need a ref to the DOM node. For example, clicking the button will focus the input using a ref:

```
import { useRef } from 'react';

export default function Form() {
  const inputRef = useRef(null);

  function handleClick() {
    inputRef.current.focus();
  }

  return (
    <>
      <input ref={inputRef} />
      <button onClick={handleClick}>
        Focus the input
      </button>
    </>
  );
}
```

## Ready to learn this topic?

Read **[Manipulating the DOM with Refs](/learn/manipulating-the-dom-with-refs)** to learn how to access DOM elements managed by React.

[Read More](/learn/manipulating-the-dom-with-refs)

***

## Synchronizing with Effects[](#synchronizing-with-effects "Link for Synchronizing with Effects ")

Some components need to synchronize with external systems. For example, you might want to control a non-React component based on the React state, set up a server connection, or send an analytics log when a component appears on the screen. Unlike event handlers, which let you handle particular events, *Effects* let you run some code after rendering. Use them to synchronize your component with a system outside of React.

Press Play/Pause a few times and see how the video player stays synchronized to the `isPlaying` prop value:

```
import { useState, useRef, useEffect } from 'react';

function VideoPlayer({ src, isPlaying }) {
  const ref = useRef(null);

  useEffect(() => {
    if (isPlaying) {
      ref.current.play();
    } else {
      ref.current.pause();
    }
  }, [isPlaying]);

  return <video ref={ref} src={src} loop playsInline />;
}

export default function App() {
  const [isPlaying, setIsPlaying] = useState(false);
  return (
    <>
      <button onClick={() => setIsPlaying(!isPlaying)}>
        {isPlaying ? 'Pause' : 'Play'}
      </button>
      <VideoPlayer
        isPlaying={isPlaying}
        src="https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4"
      />
    </>
  );
}
```

Many Effects also “clean up” after themselves. For example, an Effect that sets up a connection to a chat server should return a *cleanup function* that tells React how to disconnect your component from that server:

```
import { useState, useEffect } from 'react';
import { createConnection } from './chat.js';

export default function ChatRoom() {
  useEffect(() => {
    const connection = createConnection();
    connection.connect();
    return () => connection.disconnect();
  }, []);
  return <h1>Welcome to the chat!</h1>;
}
```

In development, React will immediately run and clean up your Effect one extra time. This is why you see `"✅ Connecting..."` printed twice. This ensures that you don’t forget to implement the cleanup function.

## Ready to learn this topic?

Read **[Synchronizing with Effects](/learn/synchronizing-with-effects)** to learn how to synchronize components with external systems.

[Read More](/learn/synchronizing-with-effects)

***

## You Might Not Need An Effect[](#you-might-not-need-an-effect "Link for You Might Not Need An Effect ")

Effects are an escape hatch from the React paradigm. They let you “step outside” of React and synchronize your components with some external system. If there is no external system involved (for example, if you want to update a component’s state when some props or state change), you shouldn’t need an Effect. Removing unnecessary Effects will make your code easier to follow, faster to run, and less error-prone.

There are two common cases in which you don’t need Effects:

* **You don’t need Effects to transform data for rendering.**
* **You don’t need Effects to handle user events.**

For example, you don’t need an Effect to adjust some state based on other state:

```
function Form() {

  const [firstName, setFirstName] = useState('Taylor');

  const [lastName, setLastName] = useState('Swift');



  // 🔴 Avoid: redundant state and unnecessary Effect

  const [fullName, setFullName] = useState('');

  useEffect(() => {

    setFullName(firstName + ' ' + lastName);

  }, [firstName, lastName]);

  // ...

}
```

Instead, calculate as much as you can while rendering:

```
function Form() {

  const [firstName, setFirstName] = useState('Taylor');

  const [lastName, setLastName] = useState('Swift');

  // ✅ Good: calculated during rendering

  const fullName = firstName + ' ' + lastName;

  // ...

}
```

However, you *do* need Effects to synchronize with external systems.

## Ready to learn this topic?

Read **[You Might Not Need an Effect](/learn/you-might-not-need-an-effect)** to learn how to remove unnecessary Effects.

[Read More](/learn/you-might-not-need-an-effect)

***

## Lifecycle of reactive effects[](#lifecycle-of-reactive-effects "Link for Lifecycle of reactive effects ")

Effects have a different lifecycle from components. Components may mount, update, or unmount. An Effect can only do two things: to start synchronizing something, and later to stop synchronizing it. This cycle can happen multiple times if your Effect depends on props and state that change over time.

This Effect depends on the value of the `roomId` prop. Props are *reactive values,* which means they can change on a re-render. Notice that the Effect *re-synchronizes* (and re-connects to the server) if `roomId` changes:

```
import { useState, useEffect } from 'react';
import { createConnection } from './chat.js';

const serverUrl = 'https://localhost:1234';

function ChatRoom({ roomId }) {
  useEffect(() => {
    const connection = createConnection(serverUrl, roomId);
    connection.connect();
    return () => connection.disconnect();
  }, [roomId]);

  return <h1>Welcome to the {roomId} room!</h1>;
}

export default function App() {
  const [roomId, setRoomId] = useState('general');
  return (
    <>
      <label>
        Choose the chat room:{' '}
        <select
          value={roomId}
          onChange={e => setRoomId(e.target.value)}
        >
          <option value="general">general</option>
          <option value="travel">travel</option>
          <option value="music">music</option>
        </select>
      </label>
      <hr />
      <ChatRoom roomId={roomId} />
    </>
  );
}
```

React provides a linter rule to check that you’ve specified your Effect’s dependencies correctly. If you forget to specify `roomId` in the list of dependencies in the above example, the linter will find that bug automatically.

## Ready to learn this topic?

Read **[Lifecycle of Reactive Events](/learn/lifecycle-of-reactive-effects)** to learn how an Effect’s lifecycle is different from a component’s.

[Read More](/learn/lifecycle-of-reactive-effects)

***

## Separating events from Effects[](#separating-events-from-effects "Link for Separating events from Effects ")

### Under Construction

This section describes an **experimental API that has not yet been released** in a stable version of React.

Event handlers only re-run when you perform the same interaction again. Unlike event handlers, Effects re-synchronize if any of the values they read, like props or state, are different than during last render. Sometimes, you want a mix of both behaviors: an Effect that re-runs in response to some values but not others.

All code inside Effects is *reactive.* It will run again if some reactive value it reads has changed due to a re-render. For example, this Effect will re-connect to the chat if either `roomId` or `theme` have changed:

```
import { useState, useEffect } from 'react';
import { createConnection, sendMessage } from './chat.js';
import { showNotification } from './notifications.js';

const serverUrl = 'https://localhost:1234';

function ChatRoom({ roomId, theme }) {
  useEffect(() => {
    const connection = createConnection(serverUrl, roomId);
    connection.on('connected', () => {
      showNotification('Connected!', theme);
    });
    connection.connect();
    return () => connection.disconnect();
  }, [roomId, theme]);

  return <h1>Welcome to the {roomId} room!</h1>
}

export default function App() {
  const [roomId, setRoomId] = useState('general');
  const [isDark, setIsDark] = useState(false);
  return (
    <>
      <label>
        Choose the chat room:{' '}
        <select
          value={roomId}
          onChange={e => setRoomId(e.target.value)}
        >
          <option value="general">general</option>
          <option value="travel">travel</option>
          <option value="music">music</option>
        </select>
      </label>
      <label>
        <input
          type="checkbox"
          checked={isDark}
          onChange={e => setIsDark(e.target.checked)}
        />
        Use dark theme
      </label>
      <hr />
      <ChatRoom
        roomId={roomId}
        theme={isDark ? 'dark' : 'light'} 
      />
    </>
  );
}
```

This is not ideal. You want to re-connect to the chat only if the `roomId` has changed. Switching the `theme` shouldn’t re-connect to the chat! Move the code reading `theme` out of your Effect into an *Effect Event*:

```
import { useState, useEffect } from 'react';
import { experimental_useEffectEvent as useEffectEvent } from 'react';
import { createConnection, sendMessage } from './chat.js';
import { showNotification } from './notifications.js';

const serverUrl = 'https://localhost:1234';

function ChatRoom({ roomId, theme }) {
  const onConnected = useEffectEvent(() => {
    showNotification('Connected!', theme);
  });

  useEffect(() => {
    const connection = createConnection(serverUrl, roomId);
    connection.on('connected', () => {
      onConnected();
    });
    connection.connect();
    return () => connection.disconnect();
  }, [roomId]);

  return <h1>Welcome to the {roomId} room!</h1>
}

export default function App() {
  const [roomId, setRoomId] = useState('general');
  const [isDark, setIsDark] = useState(false);
  return (
    <>
      <label>
        Choose the chat room:{' '}
        <select
          value={roomId}
          onChange={e => setRoomId(e.target.value)}
        >
          <option value="general">general</option>
          <option value="travel">travel</option>
          <option value="music">music</option>
        </select>
      </label>
      <label>
        <input
          type="checkbox"
          checked={isDark}
          onChange={e => setIsDark(e.target.checked)}
        />
        Use dark theme
      </label>
      <hr />
      <ChatRoom
        roomId={roomId}
        theme={isDark ? 'dark' : 'light'} 
      />
    </>
  );
}
```

Code inside Effect Events isn’t reactive, so changing the `theme` no longer makes your Effect re-connect.

## Ready to learn this topic?

Read **[Separating Events from Effects](/learn/separating-events-from-effects)** to learn how to prevent some values from re-triggering Effects.

[Read More](/learn/separating-events-from-effects)

***

## Removing Effect dependencies[](#removing-effect-dependencies "Link for Removing Effect dependencies ")

When you write an Effect, the linter will verify that you’ve included every reactive value (like props and state) that the Effect reads in the list of your Effect’s dependencies. This ensures that your Effect remains synchronized with the latest props and state of your component. Unnecessary dependencies may cause your Effect to run too often, or even create an infinite loop. The way you remove them depends on the case.

For example, this Effect depends on the `options` object which gets re-created every time you edit the input:

```
import { useState, useEffect } from 'react';
import { createConnection } from './chat.js';

const serverUrl = 'https://localhost:1234';

function ChatRoom({ roomId }) {
  const [message, setMessage] = useState('');

  const options = {
    serverUrl: serverUrl,
    roomId: roomId
  };

  useEffect(() => {
    const connection = createConnection(options);
    connection.connect();
    return () => connection.disconnect();
  }, [options]);

  return (
    <>
      <h1>Welcome to the {roomId} room!</h1>
      <input value={message} onChange={e => setMessage(e.target.value)} />
    </>
  );
}

export default function App() {
  const [roomId, setRoomId] = useState('general');
  return (
    <>
      <label>
        Choose the chat room:{' '}
        <select
          value={roomId}
          onChange={e => setRoomId(e.target.value)}
        >
          <option value="general">general</option>
          <option value="travel">travel</option>
          <option value="music">music</option>
        </select>
      </label>
      <hr />
      <ChatRoom roomId={roomId} />
    </>
  );
}
```

You don’t want the chat to re-connect every time you start typing a message in that chat. To fix this problem, move creation of the `options` object inside the Effect so that the Effect only depends on the `roomId` string:

```
import { useState, useEffect } from 'react';
import { createConnection } from './chat.js';

const serverUrl = 'https://localhost:1234';

function ChatRoom({ roomId }) {
  const [message, setMessage] = useState('');

  useEffect(() => {
    const options = {
      serverUrl: serverUrl,
      roomId: roomId
    };
    const connection = createConnection(options);
    connection.connect();
    return () => connection.disconnect();
  }, [roomId]);

  return (
    <>
      <h1>Welcome to the {roomId} room!</h1>
      <input value={message} onChange={e => setMessage(e.target.value)} />
    </>
  );
}

export default function App() {
  const [roomId, setRoomId] = useState('general');
  return (
    <>
      <label>
        Choose the chat room:{' '}
        <select
          value={roomId}
          onChange={e => setRoomId(e.target.value)}
        >
          <option value="general">general</option>
          <option value="travel">travel</option>
          <option value="music">music</option>
        </select>
      </label>
      <hr />
      <ChatRoom roomId={roomId} />
    </>
  );
}
```

Notice that you didn’t start by editing the dependency list to remove the `options` dependency. That would be wrong. Instead, you changed the surrounding code so that the dependency became *unnecessary.* Think of the dependency list as a list of all the reactive values used by your Effect’s code. You don’t intentionally choose what to put on that list. The list describes your code. To change the dependency list, change the code.

## Ready to learn this topic?

Read **[Removing Effect Dependencies](/learn/removing-effect-dependencies)** to learn how to make your Effect re-run less often.

[Read More](/learn/removing-effect-dependencies)

***

## Reusing logic with custom Hooks[](#reusing-logic-with-custom-hooks "Link for Reusing logic with custom Hooks ")

React comes with built-in Hooks like `useState`, `useContext`, and `useEffect`. Sometimes, you’ll wish that there was a Hook for some more specific purpose: for example, to fetch data, to keep track of whether the user is online, or to connect to a chat room. To do this, you can create your own Hooks for your application’s needs.

In this example, the `usePointerPosition` custom Hook tracks the cursor position, while `useDelayedValue` custom Hook returns a value that’s “lagging behind” the value you passed by a certain number of milliseconds. Move the cursor over the sandbox preview area to see a moving trail of dots following the cursor:

```
import { usePointerPosition } from './usePointerPosition.js';
import { useDelayedValue } from './useDelayedValue.js';

export default function Canvas() {
  const pos1 = usePointerPosition();
  const pos2 = useDelayedValue(pos1, 100);
  const pos3 = useDelayedValue(pos2, 200);
  const pos4 = useDelayedValue(pos3, 100);
  const pos5 = useDelayedValue(pos4, 50);
  return (
    <>
      <Dot position={pos1} opacity={1} />
      <Dot position={pos2} opacity={0.8} />
      <Dot position={pos3} opacity={0.6} />
      <Dot position={pos4} opacity={0.4} />
      <Dot position={pos5} opacity={0.2} />
    </>
  );
}

function Dot({ position, opacity }) {
  return (
    <div style={{
      position: 'absolute',
      backgroundColor: 'pink',
      borderRadius: '50%',
      opacity,
      transform: `translate(${position.x}px, ${position.y}px)`,
      pointerEvents: 'none',
      left: -20,
      top: -20,
      width: 40,
      height: 40,
    }} />
  );
}
```

You can create custom Hooks, compose them together, pass data between them, and reuse them between components. As your app grows, you will write fewer Effects by hand because you’ll be able to reuse custom Hooks you already wrote. There are also many excellent custom Hooks maintained by the React community.

## Ready to learn this topic?

Read **[Reusing Logic with Custom Hooks](/learn/reusing-logic-with-custom-hooks)** to learn how to share logic between components.

[Read More](/learn/reusing-logic-with-custom-hooks)

***

## What’s next?[](#whats-next "Link for What’s next? ")

Head over to [Referencing Values with Refs](/learn/referencing-values-with-refs) to start reading this chapter page by page!

[PreviousScaling Up with Reducer and Context](/learn/scaling-up-with-reducer-and-context)

[NextReferencing Values with Refs](/learn/referencing-values-with-refs)

***

----
url: https://legacy.reactjs.org/blog/2013/11/18/community-roundup-11.html
----

November 18, 2013 by [Vjeux](https://twitter.com/vjeux)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

This round-up is the proof that React has taken off from its Facebook’s root: it features three in-depth presentations of React done by external people. This is awesome, keep them coming!

## [](#super-vanjs-2013-talk)Super VanJS 2013 Talk

[Steve Luscher](https://github.com/steveluscher) working at [LeanPub](https://leanpub.com/) made a 30 min talk at [Super VanJS](https://twitter.com/vanjs). He does a remarkable job at explaining why React is so fast with very exciting demos using the HTML5 Audio API.

## [](#react-tips)React Tips

[Connor McSheffrey](http://connormcsheffrey.com/) and [Cheng Lou](https://github.com/chenglou) added a new section to the documentation. It’s a list of small tips that you will probably find useful while working on React. Since each article is very small and focused, we [encourage you to contribute](/tips/introduction.html)!

* [Inline Styles](/tips/inline-styles.html)
* [If-Else in JSX](/tips/if-else-in-JSX.html)
* [Self-Closing Tag](/tips/self-closing-tag.html)
* [Maximum Number of JSX Root Nodes](/tips/maximum-number-of-jsx-root-nodes.html)
* [Shorthand for Specifying Pixel Values in style props](/tips/style-props-value-px.html)
* [Type of the Children props](/tips/children-props-type.html)
* [Value of null for Controlled Input](/tips/controlled-input-null-value.html)
* [`componentWillReceiveProps` Not Triggered After Mounting](/tips/componentWillReceiveProps-not-triggered-after-mounting.html)
* [Props in getInitialState Is an Anti-Pattern](/tips/props-in-getInitialState-as-anti-pattern.html)
* [DOM Event Listeners in a Component](/tips/dom-event-listeners.html)
* [Load Initial Data via AJAX](/tips/initial-ajax.html)
* [False in JSX](/tips/false-in-jsx.html)

## [](#intro-to-the-react-framework)Intro to the React Framework

[Pavan Podila](http://blog.pixelingene.com/) wrote an in-depth introduction to React on TutsPlus. This is definitively worth reading.

> Within a component-tree, data should always flow down. A parent-component should set the props of a child-component to pass any data from the parent to the child. This is termed as the Owner-Owned pair. On the other hand user-events (mouse, keyboard, touches) will always bubble up from the child all the way to the root component, unless handled in between.

[](http://dev.tutsplus.com/tutorials/intro-to-the-react-framework--net-35660)

\> > \[Read the full article ...]\(http\://dev.tutsplus.com/tutorials/intro-to-the-react-framework--net-35660)

## [](#140-characters-textarea)140-characters textarea

[Brian Kim](https://github.com/brainkim) wrote a small textarea component that gradually turns red as you reach the 140-characters limit. Because he only changes the background color, React is smart enough not to mess with the text selection.

## [](#genesis-skeleton)Genesis Skeleton

[Eric Clemmons](https://ericclemmons.github.io/) is working on a “Modern, opinionated, full-stack starter kit for rapid, streamlined application development”. The version 0.4.0 has just been released and has first-class support for React.

[](http://genesis-skeleton.com/)a>

## [](#agflow-talk)AgFlow Talk

[Robert Zaremba](http://rz.scale-it.pl/) working on [AgFlow](http://www.agflow.com/) recently talked in Poland about React.

> In a nutshell, I presented why we chose React among other available options (ember.js, angular, backbone …) in AgFlow, where I’m leading an application development.
>
> During the talk a wanted to highlight that React is not about implementing a Model, but a way to construct visible components with some state. React is simple. It is super simple, you can learn it in 1h. On the other hand what is model? Which functionality it should provide? React does one thing and does it the best (for me)!
>
> [Read the full article…](http://rz.scale-it.pl/2013/10/20/frontend_components_in_react.html)

## [](#jsx)JSX

[Todd Kennedy](http://tck.io/) working at Condé Nast wrote [JSXHint](https://github.com/CondeNast/JSXHint) and explains in a blog post his perspective on JSX.

> Lets start with the elephant in the room: JSX? Is this some sort of template language? Specifically no. This might have been the first big stumbling block. What looks like to be a templating language is actually an in-line DSL that gets transpiled directly into JavaScript by the JSX transpiler.
>
> Creating elements in memory is quick — copying those elements into the DOM is where the slowness occurs. This is due to a variety of issues, most namely reflow/paint. Changing the items in the DOM causes the browser to re-paint the display, apply styles, etc. We want to keep those operations to an absolute minimum, especially if we’re dealing with something that needs to update the DOM frequently.
>
> [Read the full article…](http://tck.io/posts/jsxhint_and_react.html)

## [](#photo-gallery)Photo Gallery

[Maykel Loomans](http://miekd.com/), designer at Instagram, wrote a gallery for photos he shot using React.

[](http://photos.miekd.com/xoxo2013/)a>

## [](#random-tweet)Random Tweet

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2013-11-18-community-roundup-11.md)

----
url: https://legacy.reactjs.org/blog/2013/06/19/community-roundup-2.html
----

June 19, 2013 by [Vjeux](https://twitter.com/vjeux)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

Since the launch we have received a lot of feedback and are actively working on React 0.4. In the meantime, here are the highlights of this week.

## [](#some-quick-thoughts-on-react)Some quick thoughts on React

[Andrew Greig](http://www.andrewgreig.com/) made a blog post that gives a high level description of what React is.

> I have been using Facebook’s recently released JavaScript framework called React.js for the last few days and have managed to obtain a rather high level understanding of how it works and formed a good perspective on how it fits in to the entire javascript framework ecosystem.
>
> Basically, React is not an MVC framework. It is not a replacement for Backbone or Knockout or Angular, instead it is designed to work with existing frameworks and help extend their functionality.
>
> It is designed for building big UIs. The type where you have lots of reusable components that are handling events and presenting and changing some backend data. In a traditional MVC app, React fulfils the role of the View. So you would still need to handle the Model and Controller on your own.
>
> I found the best way to utilise React was to pair it with Backbone, with React replacing the Backbone View, or to write your own Model/Data object and have React communicate with that.
>
> [Read the full post…](http://www.andrewgreig.com/637/)

## [](#react-and-socketio-chat-application)React and Socket.IO Chat Application

[Danial Khosravi](https://danialk.github.io/) made a real-time chat application that interacts with the back-end using Socket.IO.

> A week ago I was playing with AngularJS and [this little chat application](https://github.com/btford/angular-socket-io-im) which uses socket.io and nodejs for realtime communication. Yesterday I saw a post about ReactJS in [EchoJS](http://www.echojs.com/) and started playing with this UI library. After playing a bit with React, I decided to write and chat application using React and I used Bran Ford’s Backend for server side of this little app.
>
> [](https://danialk.github.io/blog/2013/06/16/reactjs-and-socket-dot-io-chat-application/)
>
> [Read the full post…](https://danialk.github.io/blog/2013/06/16/reactjs-and-socket-dot-io-chat-application/)

## [](#react-and-other-frameworks)React and Other Frameworks

[Pete Hunt](http://www.petehunt.net/blog/) wrote an answer on Quora comparing React and Angular directives. At the end, he explains how you can make an Angular directive that is in fact being rendered with React.

> To set the record straight: React components are far more powerful than Angular templates; they should be compared with Angular’s directives instead. So I took the first Google hit for “AngularJS directive tutorial” (AngularJS Directives Tutorial - Fundoo Solutions), rewrote it in React and compared them. \[…]
>
> We’ve designed React from the beginning to work well with other libraries. Angular is no exception. Let’s take the original Angular example and use React to implement the fundoo-rating directive.
>
> [Read the full post…](https://www.quora.com/Pete-Hunt/Posts/Facebooks-React-vs-AngularJS-A-Closer-Look)

In the same vein, [Markov Twain](https://twitter.com/markov_twain/status/345702941845499906) re-implemented the examples on the front-page [with Ember](http://jsbin.com/azihiw/2/edit) and [Vlad Yazhbin](https://twitter.com/vla) re-implemented the tutorial [with Angular](http://jsfiddle.net/vla/Cdrse/).

## [](#web-components-react--x-tags)Web Components: React & x-tags

Mozilla and Google are actively working on Web Components. [Vjeux](http://blog.vjeux.com/) wrote a proof of concept that shows how to implement them using React.

> Using [x-tags](http://www.x-tags.org/) from Mozilla, we can write custom tags within the DOM. This is a great opportunity to be able to write reusable components without being tied to a particular library. I wrote [x-react](https://github.com/vjeux/react-xtags/) to have them being rendered in React.
>
> [](http://blog.vjeux.com/2013/javascript/custom-components-react-x-tags.html)
>
> [Read the full post…](http://blog.vjeux.com/2013/javascript/custom-components-react-x-tags.html)

## [](#react-todomvc-example)React TodoMVC Example

[TodoMVC.com](http://todomvc.com/) is a website that collects various implementations of the same basic Todo app. [Pete Hunt](http://www.petehunt.net/blog/) wrote an idiomatic React version.

> Developers these days are spoiled with choice when it comes to selecting an MV\* framework for structuring and organizing their JavaScript web apps.
>
> To help solve this problem, we created TodoMVC - a project which offers the same Todo application implemented using MV\* concepts in most of the popular JavaScript MV\* frameworks of today.
>
> [](http://todomvc.com/labs/architecture-examples/react/)
>
> [Read the source code…](https://github.com/tastejs/todomvc/tree/gh-pages/labs/architecture-examples/react)

## [](#jsx-is-not-html)JSX is not HTML

Many of you pointed out differences between JSX and HTML. In order to clear up some confusion, we have added some documentation that covers the four main differences:

* [Whitespace removal](/docs/jsx-is-not-html.html)
* [HTML Entities](/docs/jsx-is-not-html.html)
* [Comments](/docs/jsx-is-not-html.html)
* [Custom HTML Attributes](/docs/jsx-is-not-html.html)

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2013-06-19-community-roundup-2.md)

----
url: https://react.dev/learn/managing-state
----

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function Form() {
  const [answer, setAnswer] = useState('');
  const [error, setError] = useState(null);
  const [status, setStatus] = useState('typing');

  if (status === 'success') {
    return <h1>That's right!</h1>
  }

  async function handleSubmit(e) {
    e.preventDefault();
    setStatus('submitting');
    try {
      await submitForm(answer);
      setStatus('success');
    } catch (err) {
      setStatus('typing');
      setError(err);
    }
  }

  function handleTextareaChange(e) {
    setAnswer(e.target.value);
  }

  return (
    <>
      <h2>City quiz</h2>
      <p>
        In which city is there a billboard that turns air into drinkable water?
      </p>
      <form onSubmit={handleSubmit}>
        <textarea
          value={answer}
          onChange={handleTextareaChange}
          disabled={status === 'submitting'}
        />
        <br />
        <button disabled={
          answer.length === 0 ||
          status === 'submitting'
        }>
          Submit
        </button>
        {error !== null &&
          <p className="Error">
            {error.message}
          </p>
        }
      </form>
    </>
  );
}

function submitForm(answer) {
  // Pretend it's hitting the network.
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      let shouldError = answer.toLowerCase() !== 'lima'
      if (shouldError) {
        reject(new Error('Good guess but a wrong answer. Try again!'));
      } else {
        resolve();
      }
    }, 1500);
  });
}
```

## Ready to learn this topic?

Read **[Reacting to Input with State](/learn/reacting-to-input-with-state)** to learn how to approach interactions with a state-driven mindset.

[Read More](/learn/reacting-to-input-with-state)

***

## Choosing the state structure[](#choosing-the-state-structure "Link for Choosing the state structure ")

Structuring state well can make a difference between a component that is pleasant to modify and debug, and one that is a constant source of bugs. The most important principle is that state shouldn’t contain redundant or duplicated information. If there’s unnecessary state, it’s easy to forget to update it, and introduce bugs!

For example, this form has a **redundant** `fullName` state variable:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function Form() {
  const [firstName, setFirstName] = useState('');
  const [lastName, setLastName] = useState('');
  const [fullName, setFullName] = useState('');

  function handleFirstNameChange(e) {
    setFirstName(e.target.value);
    setFullName(e.target.value + ' ' + lastName);
  }

  function handleLastNameChange(e) {
    setLastName(e.target.value);
    setFullName(firstName + ' ' + e.target.value);
  }

  return (
    <>
      <h2>Let’s check you in</h2>
      <label>
        First name:{' '}
        <input
          value={firstName}
          onChange={handleFirstNameChange}
        />
      </label>
      <label>
        Last name:{' '}
        <input
          value={lastName}
          onChange={handleLastNameChange}
        />
      </label>
      <p>
        Your ticket will be issued to: <b>{fullName}</b>
      </p>
    </>
  );
}
```

You can remove it and simplify the code by calculating `fullName` while the component is rendering:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function Form() {
  const [firstName, setFirstName] = useState('');
  const [lastName, setLastName] = useState('');

  const fullName = firstName + ' ' + lastName;

  function handleFirstNameChange(e) {
    setFirstName(e.target.value);
  }

  function handleLastNameChange(e) {
    setLastName(e.target.value);
  }

  return (
    <>
      <h2>Let’s check you in</h2>
      <label>
        First name:{' '}
        <input
          value={firstName}
          onChange={handleFirstNameChange}
        />
      </label>
      <label>
        Last name:{' '}
        <input
          value={lastName}
          onChange={handleLastNameChange}
        />
      </label>
      <p>
        Your ticket will be issued to: <b>{fullName}</b>
      </p>
    </>
  );
}
```

This might seem like a small change, but many bugs in React apps are fixed this way.

## Ready to learn this topic?

Read **[Choosing the State Structure](/learn/choosing-the-state-structure)** to learn how to design the state shape to avoid bugs.

[Read More](/learn/choosing-the-state-structure)

***

## Sharing state between components[](#sharing-state-between-components "Link for Sharing state between components ")

Sometimes, you want the state of two components to always change together. To do it, remove state from both of them, move it to their closest common parent, and then pass it down to them via props. This is known as “lifting state up”, and it’s one of the most common things you will do writing React code.

In this example, only one panel should be active at a time. To achieve this, instead of keeping the active state inside each individual panel, the parent component holds the state and specifies the props for its children.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function Accordion() {
  const [activeIndex, setActiveIndex] = useState(0);
  return (
    <>
      <h2>Almaty, Kazakhstan</h2>
      <Panel
        title="About"
        isActive={activeIndex === 0}
        onShow={() => setActiveIndex(0)}
      >
        With a population of about 2 million, Almaty is Kazakhstan's largest city. From 1929 to 1997, it was its capital city.
      </Panel>
      <Panel
        title="Etymology"
        isActive={activeIndex === 1}
        onShow={() => setActiveIndex(1)}
      >
        The name comes from <span lang="kk-KZ">алма</span>, the Kazakh word for "apple" and is often translated as "full of apples". In fact, the region surrounding Almaty is thought to be the ancestral home of the apple, and the wild <i lang="la">Malus sieversii</i> is considered a likely candidate for the ancestor of the modern domestic apple.
      </Panel>
    </>
  );
}

function Panel({
  title,
  children,
  isActive,
  onShow
}) {
  return (
    <section className="panel">
      <h3>{title}</h3>
      {isActive ? (
        <p>{children}</p>
      ) : (
        <button onClick={onShow}>
          Show
        </button>
      )}
    </section>
  );
}
```

## Ready to learn this topic?

Read **[Sharing State Between Components](/learn/sharing-state-between-components)** to learn how to lift state up and keep components in sync.

[Read More](/learn/sharing-state-between-components)

***

## Preserving and resetting state[](#preserving-and-resetting-state "Link for Preserving and resetting state ")

When you re-render a component, React needs to decide which parts of the tree to keep (and update), and which parts to discard or re-create from scratch. In most cases, React’s automatic behavior works well enough. By default, React preserves the parts of the tree that “match up” with the previously rendered component tree.

However, sometimes this is not what you want. In this chat app, typing a message and then switching the recipient does not reset the input. This can make the user accidentally send a message to the wrong person:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';
import Chat from './Chat.js';
import ContactList from './ContactList.js';

export default function Messenger() {
  const [to, setTo] = useState(contacts[0]);
  return (
    <div>
      <ContactList
        contacts={contacts}
        selectedContact={to}
        onSelect={contact => setTo(contact)}
      />
      <Chat contact={to} />
    </div>
  )
}

const contacts = [
  { name: 'Taylor', email: 'taylor@mail.com' },
  { name: 'Alice', email: 'alice@mail.com' },
  { name: 'Bob', email: 'bob@mail.com' }
];
```

React lets you override the default behavior, and *force* a component to reset its state by passing it a different `key`, like `<Chat key={email} />`. This tells React that if the recipient is different, it should be considered a *different* `Chat` component that needs to be re-created from scratch with the new data (and UI like inputs). Now switching between the recipients resets the input field—even though you render the same component.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';
import Chat from './Chat.js';
import ContactList from './ContactList.js';

export default function Messenger() {
  const [to, setTo] = useState(contacts[0]);
  return (
    <div>
      <ContactList
        contacts={contacts}
        selectedContact={to}
        onSelect={contact => setTo(contact)}
      />
      <Chat key={to.email} contact={to} />
    </div>
  )
}

const contacts = [
  { name: 'Taylor', email: 'taylor@mail.com' },
  { name: 'Alice', email: 'alice@mail.com' },
  { name: 'Bob', email: 'bob@mail.com' }
];
```

## Ready to learn this topic?

Read **[Preserving and Resetting State](/learn/preserving-and-resetting-state)** to learn the lifetime of state and how to control it.

[Read More](/learn/preserving-and-resetting-state)

***

## Extracting state logic into a reducer[](#extracting-state-logic-into-a-reducer "Link for Extracting state logic into a reducer ")

Components with many state updates spread across many event handlers can get overwhelming. For these cases, you can consolidate all the state update logic outside your component in a single function, called “reducer”. Your event handlers become concise because they only specify the user “actions”. At the bottom of the file, the reducer function specifies how the state should update in response to each action!

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useReducer } from 'react';
import AddTask from './AddTask.js';
import TaskList from './TaskList.js';

export default function TaskApp() {
  const [tasks, dispatch] = useReducer(
    tasksReducer,
    initialTasks
  );

  function handleAddTask(text) {
    dispatch({
      type: 'added',
      id: nextId++,
      text: text,
    });
  }

  function handleChangeTask(task) {
    dispatch({
      type: 'changed',
      task: task
    });
  }

  function handleDeleteTask(taskId) {
    dispatch({
      type: 'deleted',
      id: taskId
    });
  }

  return (
    <>
      <h1>Prague itinerary</h1>
      <AddTask
        onAddTask={handleAddTask}
      />
      <TaskList
        tasks={tasks}
        onChangeTask={handleChangeTask}
        onDeleteTask={handleDeleteTask}
      />
    </>
  );
}

function tasksReducer(tasks, action) {
  switch (action.type) {
    case 'added': {
      return [...tasks, {
        id: action.id,
        text: action.text,
        done: false
      }];
    }
    case 'changed': {
      return tasks.map(t => {
        if (t.id === action.task.id) {
          return action.task;
        } else {
          return t;
        }
      });
    }
    case 'deleted': {
      return tasks.filter(t => t.id !== action.id);
    }
    default: {
      throw Error('Unknown action: ' + action.type);
    }
  }
}

let nextId = 3;
const initialTasks = [
  { id: 0, text: 'Visit Kafka Museum', done: true },
  { id: 1, text: 'Watch a puppet show', done: false },
  { id: 2, text: 'Lennon Wall pic', done: false }
];
```

## Ready to learn this topic?

Read **[Extracting State Logic into a Reducer](/learn/extracting-state-logic-into-a-reducer)** to learn how to consolidate logic in the reducer function.

[Read More](/learn/extracting-state-logic-into-a-reducer)

***

## Passing data deeply with context[](#passing-data-deeply-with-context "Link for Passing data deeply with context ")

Usually, you will pass information from a parent component to a child component via props. But passing props can become inconvenient if you need to pass some prop through many components, or if many components need the same information. Context lets the parent component make some information available to any component in the tree below it—no matter how deep it is—without passing it explicitly through props.

Here, the `Heading` component determines its heading level by “asking” the closest `Section` for its level. Each `Section` tracks its own level by asking the parent `Section` and adding one to it. Every `Section` provides information to all components below it without passing props—it does that through context.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import Heading from './Heading.js';
import Section from './Section.js';

export default function Page() {
  return (
    <Section>
      <Heading>Title</Heading>
      <Section>
        <Heading>Heading</Heading>
        <Heading>Heading</Heading>
        <Heading>Heading</Heading>
        <Section>
          <Heading>Sub-heading</Heading>
          <Heading>Sub-heading</Heading>
          <Heading>Sub-heading</Heading>
          <Section>
            <Heading>Sub-sub-heading</Heading>
            <Heading>Sub-sub-heading</Heading>
            <Heading>Sub-sub-heading</Heading>
          </Section>
        </Section>
      </Section>
    </Section>
  );
}
```

## Ready to learn this topic?

Read **[Passing Data Deeply with Context](/learn/passing-data-deeply-with-context)** to learn about using context as an alternative to passing props.

[Read More](/learn/passing-data-deeply-with-context)

***

## Scaling up with reducer and context[](#scaling-up-with-reducer-and-context "Link for Scaling up with reducer and context ")

Reducers let you consolidate a component’s state update logic. Context lets you pass information deep down to other components. You can combine reducers and context together to manage state of a complex screen.

With this approach, a parent component with complex state manages it with a reducer. Other components anywhere deep in the tree can read its state via context. They can also dispatch actions to update that state.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import AddTask from './AddTask.js';
import TaskList from './TaskList.js';
import { TasksProvider } from './TasksContext.js';

export default function TaskApp() {
  return (
    <TasksProvider>
      <h1>Day off in Kyoto</h1>
      <AddTask />
      <TaskList />
    </TasksProvider>
  );
}
```

## Ready to learn this topic?

Read **[Scaling Up with Reducer and Context](/learn/scaling-up-with-reducer-and-context)** to learn how state management scales in a growing app.

[Read More](/learn/scaling-up-with-reducer-and-context)

***

## What’s next?[](#whats-next "Link for What’s next? ")

Head over to [Reacting to Input with State](/learn/reacting-to-input-with-state) to start reading this chapter page by page!

Or, if you’re already familiar with these topics, why not read about [Escape Hatches](/learn/escape-hatches)?

[PreviousUpdating Arrays in State](/learn/updating-arrays-in-state)

[NextReacting to Input with State](/learn/reacting-to-input-with-state)

***

----
url: https://react.dev/reference/react/useImperativeHandle
----

[API Reference](/reference/react)

[Hooks](/reference/react/hooks)

# useImperativeHandle[](#undefined "Link for this heading")

`useImperativeHandle` is a React Hook that lets you customize the handle exposed as a [ref.](/learn/manipulating-the-dom-with-refs)

```
useImperativeHandle(ref, createHandle, dependencies?)
```

* [Reference](#reference)
  * [`useImperativeHandle(ref, createHandle, dependencies?)`](#useimperativehandle)

* [Usage](#usage)

  * [Exposing a custom ref handle to the parent component](#exposing-a-custom-ref-handle-to-the-parent-component)
  * [Exposing your own imperative methods](#exposing-your-own-imperative-methods)

***

## Reference[](#reference "Link for Reference ")

### `useImperativeHandle(ref, createHandle, dependencies?)`[](#useimperativehandle "Link for this heading")

Call `useImperativeHandle` at the top level of your component to customize the ref handle it exposes:

```
import { useImperativeHandle } from 'react';



function MyInput({ ref }) {

  useImperativeHandle(ref, () => {

    return {

      // ... your methods ...

    };

  }, []);

  // ...
```

[See more examples below.](#usage)

#### Parameters[](#parameters "Link for Parameters ")

* `ref`: The `ref` you received as a prop to the `MyInput` component.

* `createHandle`: A function that takes no arguments and returns the ref handle you want to expose. That ref handle can have any type. Usually, you will return an object with the methods you want to expose.

* **optional** `dependencies`: The list of all reactive values referenced inside of the `createHandle` code. Reactive values include props, state, and all the variables and functions declared directly inside your component body. If your linter is [configured for React](/learn/editor-setup#linting), it will verify that every reactive value is correctly specified as a dependency. The list of dependencies must have a constant number of items and be written inline like `[dep1, dep2, dep3]`. React will compare each dependency with its previous value using the [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) comparison. If a re-render resulted in a change to some dependency, or if you omitted this argument, your `createHandle` function will re-execute, and the newly created handle will be assigned to the ref.

### Note

Starting with React 19, [`ref` is available as a prop.](/blog/2024/12/05/react-19#ref-as-a-prop) In React 18 and earlier, it was necessary to get the `ref` from [`forwardRef`.](/reference/react/forwardRef)

#### Returns[](#returns "Link for Returns ")

`useImperativeHandle` returns `undefined`.

***

## Usage[](#usage "Link for Usage ")

### Exposing a custom ref handle to the parent component[](#exposing-a-custom-ref-handle-to-the-parent-component "Link for Exposing a custom ref handle to the parent component ")

To expose a DOM node to the parent element, pass in the `ref` prop to the node.

```
function MyInput({ ref }) {

  return <input ref={ref} />;

};
```

With the code above, [a ref to `MyInput` will receive the `<input>` DOM node.](/learn/manipulating-the-dom-with-refs) However, you can expose a custom value instead. To customize the exposed handle, call `useImperativeHandle` at the top level of your component:

```
import { useImperativeHandle } from 'react';



function MyInput({ ref }) {

  useImperativeHandle(ref, () => {

    return {

      // ... your methods ...

    };

  }, []);



  return <input />;

};
```

Note that in the code above, the `ref` is no longer passed to the `<input>`.

For example, suppose you don’t want to expose the entire `<input>` DOM node, but you want to expose two of its methods: `focus` and `scrollIntoView`. To do this, keep the real browser DOM in a separate ref. Then use `useImperativeHandle` to expose a handle with only the methods that you want the parent component to call:

```
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} />;

};
```

Now, if the parent component gets a ref to `MyInput`, it will be able to call the `focus` and `scrollIntoView` methods on it. However, it will not have full access to the underlying `<input>` DOM node.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useRef } from 'react';
import MyInput from './MyInput.js';

export default function Form() {
  const ref = useRef(null);

  function handleClick() {
    ref.current.focus();
    // This won't work because the DOM node isn't exposed:
    // ref.current.style.opacity = 0.5;
  }

  return (
    <form>
      <MyInput placeholder="Enter your name" ref={ref} />
      <button type="button" onClick={handleClick}>
        Edit
      </button>
    </form>
  );
}
```

***

### Exposing your own imperative methods[](#exposing-your-own-imperative-methods "Link for Exposing your own imperative methods ")

The methods you expose via an imperative handle don’t have to match the DOM methods exactly. For example, this `Post` component exposes a `scrollAndFocusAddComment` method via an imperative handle. This lets the parent `Page` scroll the list of comments *and* focus the input field when you click the button:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useRef } from 'react';
import Post from './Post.js';

export default function Page() {
  const postRef = useRef(null);

  function handleClick() {
    postRef.current.scrollAndFocusAddComment();
  }

  return (
    <>
      <button onClick={handleClick}>
        Write a comment
      </button>
      <Post ref={postRef} />
    </>
  );
}
```

### Pitfall

**Do not overuse refs.** You should only use refs for *imperative* behaviors that you can’t express as props: for example, scrolling to a node, focusing a node, triggering an animation, selecting text, and so on.

**If you can express something as a prop, you should not use a ref.** For example, instead of exposing an imperative handle like `{ open, close }` from a `Modal` component, it is better to take `isOpen` as a prop like `<Modal isOpen={isOpen} />`. [Effects](/learn/synchronizing-with-effects) can help you expose imperative behaviors via props.

[PrevioususeId](/reference/react/useId)

[NextuseInsertionEffect](/reference/react/useInsertionEffect)

***

----
url: https://legacy.reactjs.org/blog/2015/10/01/react-render-and-top-level-api.html
----

October 01, 2015 by [Jim Sproch](http://www.jimsproch.com) and [Sebastian Markbåge](https://twitter.com/sebmarkbage)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

When you’re in React’s world you are just building components that fit into other components. Everything is a component. Unfortunately not everything around you is built using React. At the root of your tree you still have to write some plumbing code to connect the outer world into React.

The primary API for rendering into the DOM looks like this:

```
ReactDOM.render(reactElement, domContainerNode)
```

To update the properties of an existing component, you call render again with a new element.

If you are rendering React components within a single-page app, you may need to plug into the app’s view lifecycle to ensure your app will invoke unmountComponentAtNode at the appropriate time. React will not automatically clean up a tree. You need to manually call:

```
ReactDOM.unmountComponentAtNode(domContainerNode)
```

This is important and often forgotten. Forgetting to call `unmountComponentAtNode` will cause your app to leak memory. There is no way for us to automatically detect when it is appropriate to do this work. Every system is different.

It is not unique to the DOM. If you want to insert a React Native view in the middle of an existing iOS app you will hit similar issues.

## [](#helpers)Helpers

If you have multiple React roots, or a single root that gets deleted over time, we recommend that you always create your own wrapper API. These will all look slightly different depending on what your outer system looks like. For example, at Facebook we have a system that automatically ties into our page transition router to automatically call `unmountComponentAtNode`.

Rather than calling `ReactDOM.render()` directly everywhere, consider writing/using a library that will manage mounting and unmounting within your application.

In your environment you may want to always configure internationalization, routers, user data etc. If you have many different React roots it can be a pain to set up configuration nodes all over the place. By creating your own wrapper you can unify that configuration into one place.

## [](#object-oriented-updates)Object Oriented Updates

If you call `ReactDOM.render` a second time to update properties, all your props are completely replaced.

```
ReactDOM.render(<App locale="en-US" userID={1} />, container);
// props.userID == 1
// props.locale == "en-US"
ReactDOM.render(<App userID={2} />, container);
// props.userID == 2
// props.locale == undefined ??!?
```

In object-oriented programming, all state lives on each object instance and you apply changes incrementally by mutating that state, one piece at a time. If you are using React within an app that expects an object oriented API (for instance, if you are building a custom web component using React), it might be surprising/confusing to a user that setting a single property would wipe out all the other properties on your component.

We used to have a helper function called `setProps` which allowed you to update only a few properties at a time. Unfortunately this API lived on a component instance, required React to keep this state internally and wasn’t very natural anyway. Therefore, we’re deprecating it and suggest that you build it into your own wrapper instead.

Here’s some boilerplate to get you started. It is a 0.14 migration path for codebases using `setProps` and `replaceProps`.

```
class ReactComponentRenderer {
  constructor(klass, container) {
    this.klass = klass;
    this.container = container;
    this.props = {};
    this.component = null;
  }

  replaceProps(props, callback) {
    this.props = {};
    this.setProps(props, callback);
  }

  setProps(partialProps, callback) {
    if (this.klass == null) {
      console.warn(
        'setProps(...): Can only update a mounted or ' +
        'mounting component. This usually means you called setProps() on ' +
        'an unmounted component. This is a no-op.'
      );
      return;
    }
    Object.assign(this.props, partialProps);
    var element = React.createElement(this.klass, this.props);
    this.component = ReactDOM.render(element, this.container, callback);
  }

  unmount() {
    ReactDOM.unmountComponentAtNode(this.container);
    this.klass = null;
  }
}
```

Object-oriented APIs don’t look like that though. They use setters and methods. I think we can do better. If you know more about the component API that you’re rendering, you can create a more natural object-oriented API around your React component.

```
class ReactVideoPlayer {
  constructor(url, container) {
    this._container = container;
    this._url = url;
    this._isPlaying = false;
    this._render();
  }

  _render() {
    ReactDOM.render(
      <VideoPlayer url={this._url} playing={this._isPlaying} />,
      this._container
    );
  }

  get url() {
    return this._url;
  }

  set url(value) {
    this._url = value;
    this._render();
  }

  play() {
    this._isPlaying = true;
    this._render();
  }

  pause() {
    this._isPlaying = false;
    this._render();
  }

  destroy() {
    ReactDOM.unmountComponentAtNode(this._container);
  }
}
```

This example shows how to provide an imperative API on top of a declarative one. Similarly, the reverse can be done, and a declarative wrapper can be used when exposing a Web Component as a React component.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2015-10-01-react-render-and-top-level-api.md)

----
url: https://legacy.reactjs.org/docs/legacy-context.html
----

> Note:
>
> The legacy context API will be removed in a future major version. Use the [new context API](/docs/context.html) introduced with version 16.3. The legacy API will continue working for all 16.x releases.

## [](#how-to-use-context)How To Use Context

> This section documents a legacy API. See the [new API](/docs/context.html).

Suppose you have a structure like:

```
class Button extends React.Component {
  render() {
    return (
      <button style={{background: this.props.color}}>
        {this.props.children}
      </button>
    );
  }
}

class Message extends React.Component {
  render() {
    return (
      <div>
        {this.props.text} <Button color={this.props.color}>Delete</Button>
      </div>
    );
  }
}

class MessageList extends React.Component {
  render() {
    const color = "purple";
    const children = this.props.messages.map((message) =>
      <Message text={message.text} color={color} />
    );
    return <div>{children}</div>;
  }
}
```

In this example, we manually thread through a `color` prop in order to style the `Button` and `Message` components appropriately. Using context, we can pass this through the tree automatically:

```
import PropTypes from 'prop-types';

class Button extends React.Component {
  render() {
    return (
      <button style={{background: this.context.color}}>        {this.props.children}
      </button>
    );
  }
}

Button.contextTypes = {  color: PropTypes.string};
class Message extends React.Component {
  render() {
    return (
      <div>
        {this.props.text} <Button>Delete</Button>      </div>
    );
  }
}

class MessageList extends React.Component {
  getChildContext() {    return {color: "purple"};  }
  render() {
    const children = this.props.messages.map((message) =>
      <Message text={message.text} />
    );
    return <div>{children}</div>;
  }
}

MessageList.childContextTypes = {  color: PropTypes.string};
```

By adding `childContextTypes` and `getChildContext` to `MessageList` (the context provider), React passes the information down automatically and any component in the subtree (in this case, `Button`) can access it by defining `contextTypes`.

If `contextTypes` is not defined, then `context` will be an empty object.

> Note:
>
> `React.PropTypes` has moved into a different package since React v15.5. Please use [the `prop-types` library instead](https://www.npmjs.com/package/prop-types) to define `contextTypes`.
>
> We provide [a codemod script](/blog/2017/04/07/react-v15.5.0.html#migrating-from-react.proptypes) to automate the conversion.

### [](#parent-child-coupling)Parent-Child Coupling

> This section documents a legacy API. See the [new API](/docs/context.html).

Context can also let you build an API where parents and children communicate. For example, one library that works this way is [React Router V4](https://reacttraining.com/react-router):

```
import { BrowserRouter as Router, Route, Link } from 'react-router-dom';

const BasicExample = () => (
  <Router>
    <div>
      <ul>
        <li><Link to="/">Home</Link></li>
        <li><Link to="/about">About</Link></li>
        <li><Link to="/topics">Topics</Link></li>
      </ul>

      <hr />

      <Route exact path="/" component={Home} />
      <Route path="/about" component={About} />
      <Route path="/topics" component={Topics} />
    </div>
  </Router>
);
```

By passing down some information from the `Router` component, each `Link` and `Route` can communicate back to the containing `Router`.

Before you build components with an API similar to this, consider if there are cleaner alternatives. For example, you can pass entire React components as props if you’d like to.

### [](#referencing-context-in-lifecycle-methods)Referencing Context in Lifecycle Methods

> This section documents a legacy API. See the [new API](/docs/context.html).

If `contextTypes` is defined within a component, the following [lifecycle methods](/docs/react-component.html#the-component-lifecycle) will receive an additional parameter, the `context` object:

* [`constructor(props, context)`](/docs/react-component.html#constructor)
* [`componentWillReceiveProps(nextProps, nextContext)`](/docs/react-component.html#componentwillreceiveprops)
* [`shouldComponentUpdate(nextProps, nextState, nextContext)`](/docs/react-component.html#shouldcomponentupdate)
* [`componentWillUpdate(nextProps, nextState, nextContext)`](/docs/react-component.html#componentwillupdate)

> Note:
>
> As of React 16, `componentDidUpdate` no longer receives `prevContext`.

### [](#referencing-context-in-stateless-function-components)Referencing Context in Function Components

> This section documents a legacy API. See the [new API](/docs/context.html).

Function components are also able to reference `context` if `contextTypes` is defined as a property of the function. The following code shows a `Button` component written as a function component.

```
import PropTypes from 'prop-types';

const Button = ({children}, context) =>
  <button style={{background: context.color}}>
    {children}
  </button>;

Button.contextTypes = {color: PropTypes.string};
```

### [](#updating-context)Updating Context

> This section documents a legacy API. See the [new API](/docs/context.html).

Don’t do it.

React has an API to update context, but it is fundamentally broken and you should not use it.

The `getChildContext` function will be called when the state or props changes. In order to update data in the context, trigger a local state update with `this.setState`. This will trigger a new context and changes will be received by the children.

```
import PropTypes from 'prop-types';

class MediaQuery extends React.Component {
  constructor(props) {
    super(props);
    this.state = {type:'desktop'};
  }

  getChildContext() {
    return {type: this.state.type};
  }

  componentDidMount() {
    const checkMediaQuery = () => {
      const type = window.matchMedia("(min-width: 1025px)").matches ? 'desktop' : 'mobile';
      if (type !== this.state.type) {
        this.setState({type});
      }
    };

    window.addEventListener('resize', checkMediaQuery);
    checkMediaQuery();
  }

  render() {
    return this.props.children;
  }
}

MediaQuery.childContextTypes = {
  type: PropTypes.string
};
```

The problem is, if a context value provided by component changes, descendants that use that value won’t update if an intermediate parent returns `false` from `shouldComponentUpdate`. This is totally out of control of the components using context, so there’s basically no way to reliably update the context. [This blog post](https://medium.com/@mweststrate/how-to-safely-use-react-context-b7e343eff076) has a good explanation of why this is a problem and how you might get around it.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/legacy-context.md)

----
url: https://legacy.reactjs.org/docs/two-way-binding-helpers.html
----

> Note:
>
> `LinkedStateMixin` is deprecated as of React v15. The recommendation is to explicitly set the value and change handler, instead of using `LinkedStateMixin`.

**Importing**

```
import LinkedStateMixin from 'react-addons-linked-state-mixin'; // ES6
var LinkedStateMixin = require('react-addons-linked-state-mixin'); // ES5 with npm
```

## [](#overview)Overview

`LinkedStateMixin` is an easy way to express two-way binding with React.

In React, data flows one way: from owner to child. We think that this makes your app’s code easier to understand. You can think of it as “one-way data binding.”

However, there are lots of applications that require you to read some data and flow it back into your program. For example, when developing forms, you’ll often want to update some React `state` when you receive user input. Or perhaps you want to perform layout in JavaScript and react to changes in some DOM element size.

In React, you would implement this by listening to a “change” event, read from your data source (usually the DOM) and call `setState()` on one of your components. “Closing the data flow loop” explicitly leads to more understandable and easier-to-maintain programs. See [our forms documentation](/docs/forms.html) for more information.

Two-way binding — implicitly enforcing that some value in the DOM is always consistent with some React `state` — is concise and supports a wide variety of applications. We’ve provided `LinkedStateMixin`: syntactic sugar for setting up the common data flow loop pattern described above, or “linking” some data source to React `state`.

> Note:
>
> `LinkedStateMixin` is just a thin wrapper and convention around the `onChange`/`setState()` pattern. It doesn’t fundamentally change how data flows in your React application.

## [](#linkedstatemixin-before-and-after)LinkedStateMixin: Before and After

Here’s a simple form example without using `LinkedStateMixin`:

```
var createReactClass = require('create-react-class');

var NoLink = createReactClass({
  getInitialState: function() {
    return {message: 'Hello!'};
  },
  handleChange: function(event) {
    this.setState({message: event.target.value});
  },
  render: function() {
    var message = this.state.message;
    return <input type="text" value={message} onChange={this.handleChange} />;
  }
});
```

This works really well and it’s very clear how data is flowing, however, with a lot of form fields it could get a bit verbose. Let’s use `LinkedStateMixin` to save us some typing:

```
var createReactClass = require('create-react-class');

var WithLink = createReactClass({
  mixins: [LinkedStateMixin],  getInitialState: function() {
    return {message: 'Hello!'};
  },
  render: function() {
    return <input type="text" valueLink={this.linkState('message')} />;  }
});
```

`LinkedStateMixin` adds a method to your React component called `linkState()`. `linkState()` returns a `valueLink` object which contains the current value of the React state and a callback to change it.

`valueLink` objects can be passed up and down the tree as props, so it’s easy (and explicit) to set up two-way binding between a component deep in the hierarchy and state that lives higher in the hierarchy.

Note that checkboxes have a special behavior regarding their `value` attribute, which is the value that will be sent on form submit if the checkbox is checked (defaults to `on`). The `value` attribute is not updated when the checkbox is checked or unchecked. For checkboxes, you should use `checkedLink` instead of `valueLink`:

```
<input type="checkbox" checkedLink={this.linkState('booleanValue')} />
```

## [](#under-the-hood)Under the Hood

There are two sides to `LinkedStateMixin`: the place where you create the `valueLink` instance and the place where you use it. To prove how simple `LinkedStateMixin` is, let’s rewrite each side separately to be more explicit.

### [](#valuelink-without-linkedstatemixin)valueLink Without LinkedStateMixin

```
var createReactClass = require('create-react-class');

var WithoutMixin = createReactClass({
  getInitialState: function() {
    return {message: 'Hello!'};
  },
  handleChange: function(newValue) {    this.setState({message: newValue});  },  render: function() {
    var valueLink = {      value: this.state.message,      requestChange: this.handleChange    };    return <input type="text" valueLink={valueLink} />;
  }
});
```

As you can see, `valueLink` objects are very simple objects that just have a `value` and `requestChange` prop. And `LinkedStateMixin` is similarly simple: it just populates those fields with a value from `this.state` and a callback that calls `this.setState()`.

### [](#linkedstatemixin-without-valuelink)LinkedStateMixin Without valueLink

```
var LinkedStateMixin = require('react-addons-linked-state-mixin');
var createReactClass = require('create-react-class');

var WithoutLink = createReactClass({
  mixins: [LinkedStateMixin],
  getInitialState: function() {
    return {message: 'Hello!'};
  },
  render: function() {
    var valueLink = this.linkState('message');
    var handleChange = function(e) {
      valueLink.requestChange(e.target.value);
    };
    return <input type="text" value={valueLink.value} onChange={handleChange} />;
  }
});
```

The `valueLink` prop is also quite simple. It simply handles the `onChange` event and calls `this.props.valueLink.requestChange()` and also uses `this.props.valueLink.value` instead of `this.props.value`. That’s it!

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/addons-two-way-binding-helpers.md)

----
url: https://react.dev/reference/react-dom/components/progress
----

[API Reference](/reference/react)

[Components](/reference/react-dom/components)

# \<progress>[](#undefined "Link for this heading")

The [built-in browser `<progress>` component](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/progress) lets you render a progress indicator.

```
<progress value={0.5} />
```

* [Reference](#reference)
  * [`<progress>`](#progress)
* [Usage](#usage)
  * [Controlling a progress indicator](#controlling-a-progress-indicator)

***

## Reference[](#reference "Link for Reference ")

### `<progress>`[](#progress "Link for this heading")

To display a progress indicator, render the [built-in browser `<progress>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/progress) component.

```
<progress value={0.5} />
```

[See more examples below.](#usage)

#### Props[](#props "Link for Props ")

`<progress>` supports all [common element props.](/reference/react-dom/components/common#common-props)

Additionally, `<progress>` supports these props:

* [`max`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/progress#max): A number. Specifies the maximum `value`. Defaults to `1`.
* [`value`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/progress#value): A number between `0` and `max`, or `null` for indeterminate progress. Specifies how much was done.

***

## Usage[](#usage "Link for Usage ")

### Controlling a progress indicator[](#controlling-a-progress-indicator "Link for Controlling a progress indicator ")

To display a progress indicator, render a `<progress>` component. You can pass a number `value` between `0` and the `max` value you specify. If you don’t pass a `max` value, it will assumed to be `1` by default.

If the operation is not ongoing, pass `value={null}` to put the progress indicator into an indeterminate state.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
export default function App() {
  return (
    <>
      <progress value={0} />
      <progress value={0.5} />
      <progress value={0.7} />
      <progress value={75} max={100} />
      <progress value={1} />
      <progress value={null} />
    </>
  );
}
```

[Previous\<option>](/reference/react-dom/components/option)

[Next\<select>](/reference/react-dom/components/select)

***

----
url: https://18.react.dev/reference/react-dom/prefetchDNS
----

[API Reference](/reference/react)

[APIs](/reference/react-dom)

# prefetchDNS[](#undefined "Link for this heading")

### Canary

The `prefetchDNS` function is currently only available in React’s Canary and experimental channels. Learn more about [React’s release channels here](/community/versioning-policy#all-release-channels).

`prefetchDNS` lets you eagerly look up the IP of a server that you expect to load resources from.

```
prefetchDNS("https://example.com");
```

* [Reference](#reference)
  * [`prefetchDNS(href)`](#prefetchdns)

* [Usage](#usage)

  * [Prefetching DNS when rendering](#prefetching-dns-when-rendering)
  * [Prefetching DNS in an event handler](#prefetching-dns-in-an-event-handler)

***

## Reference[](#reference "Link for Reference ")

### `prefetchDNS(href)`[](#prefetchdns "Link for this heading")

To look up a host, call the `prefetchDNS` function from `react-dom`.

```
import { prefetchDNS } from 'react-dom';



function AppRoot() {

  prefetchDNS("https://example.com");

  // ...

}
```

***

## Usage[](#usage "Link for Usage ")

### Prefetching DNS when rendering[](#prefetching-dns-when-rendering "Link for Prefetching DNS when rendering ")

Call `prefetchDNS` when rendering a component if you know that its children will load external resources from that host.

```
import { prefetchDNS } from 'react-dom';



function AppRoot() {

  prefetchDNS("https://example.com");

  return ...;

}
```

### Prefetching DNS in an event handler[](#prefetching-dns-in-an-event-handler "Link for Prefetching DNS in an event handler ")

Call `prefetchDNS` in an event handler before transitioning to a page or state where external resources will be needed. This gets the process started earlier than if you call it during the rendering of the new page or state.

```
import { prefetchDNS } from 'react-dom';



function CallToAction() {

  const onClick = () => {

    prefetchDNS('http://example.com');

    startWizard();

  }

  return (

    <button onClick={onClick}>Start Wizard</button>

  );

}
```

[Previouspreconnect](/reference/react-dom/preconnect)

[Nextpreinit](/reference/react-dom/preinit)

***

----
url: https://legacy.reactjs.org/docs/context.html
----

> These docs are old and won’t be updated. Go to [react.dev](https://react.dev/) for the new React docs.
>
> These new documentation pages teach modern React and include live examples:
>
> * [Passing Data Deeply with Context](https://react.dev/learn/passing-data-deeply-with-context)
> * [`useContext`](https://react.dev/reference/react/useContext)

Context provides a way to pass data through the component tree without having to pass props down manually at every level.

In a typical React application, data is passed top-down (parent to child) via props, but such usage can be cumbersome for certain types of props (e.g. locale preference, UI theme) that are required by many components within an application. Context provides a way to share values like these between components without having to explicitly pass a prop through every level of the tree.

* [When to Use Context](#when-to-use-context)

* [Before You Use Context](#before-you-use-context)

* [API](#api)

  * [React.createContext](#reactcreatecontext)
  * [Context.Provider](#contextprovider)
  * [Class.contextType](#classcontexttype)
  * [Context.Consumer](#contextconsumer)
  * [Context.displayName](#contextdisplayname)

* [Examples](#examples)

  * [Dynamic Context](#dynamic-context)
  * [Updating Context from a Nested Component](#updating-context-from-a-nested-component)
  * [Consuming Multiple Contexts](#consuming-multiple-contexts)

* [Caveats](#caveats)

* [Legacy API](#legacy-api)

## [](#when-to-use-context)When to Use Context

Context is designed to share data that can be considered “global” for a tree of React components, such as the current authenticated user, theme, or preferred language. For example, in the code below we manually thread through a “theme” prop in order to style the Button component:

```
class App extends React.Component {
  render() {
    return <Toolbar theme="dark" />;
  }
}

function Toolbar(props) {
  // The Toolbar component must take an extra "theme" prop  // and pass it to the ThemedButton. This can become painful  // if every single button in the app needs to know the theme  // because it would have to be passed through all components.  return (
    <div>
      <ThemedButton theme={props.theme} />    </div>
  );
}

class ThemedButton extends React.Component {
  render() {
    return <Button theme={this.props.theme} />;
  }
}
```

Using context, we can avoid passing props through intermediate elements:

```
// Context lets us pass a value deep into the component tree// without explicitly threading it through every component.// Create a context for the current theme (with "light" as the default).const ThemeContext = React.createContext('light');
class App extends React.Component {
  render() {
    // Use a Provider to pass the current theme to the tree below.    // Any component can read it, no matter how deep it is.    // In this example, we're passing "dark" as the current value.    return (
      <ThemeContext.Provider value="dark">        <Toolbar />
      </ThemeContext.Provider>
    );
  }
}

// A component in the middle doesn't have to// pass the theme down explicitly anymore.function Toolbar() {
  return (
    <div>
      <ThemedButton />
    </div>
  );
}

class ThemedButton extends React.Component {
  // Assign a contextType to read the current theme context.  // React will find the closest theme Provider above and use its value.  // In this example, the current theme is "dark".  static contextType = ThemeContext;
  render() {
    return <Button theme={this.context} />;  }
}
```

## [](#before-you-use-context)Before You Use Context

Context is primarily used when some data needs to be accessible by *many* components at different nesting levels. Apply it sparingly because it makes component reuse more difficult.

**If you only want to avoid passing some props through many levels, [component composition](/docs/composition-vs-inheritance.html) is often a simpler solution than context.**

For example, consider a `Page` component that passes a `user` and `avatarSize` prop several levels down so that deeply nested `Link` and `Avatar` components can read it:

```
<Page user={user} avatarSize={avatarSize} />
// ... which renders ...
<PageLayout user={user} avatarSize={avatarSize} />
// ... which renders ...
<NavigationBar user={user} avatarSize={avatarSize} />
// ... which renders ...
<Link href={user.permalink}>
  <Avatar user={user} size={avatarSize} />
</Link>
```

It might feel redundant to pass down the `user` and `avatarSize` props through many levels if in the end only the `Avatar` component really needs it. It’s also annoying that whenever the `Avatar` component needs more props from the top, you have to add them at all the intermediate levels too.

One way to solve this issue **without context** is to [pass down the `Avatar` component itself](/docs/composition-vs-inheritance.html#containment) so that the intermediate components don’t need to know about the `user` or `avatarSize` props:

```
function Page(props) {
  const user = props.user;
  const userLink = (
    <Link href={user.permalink}>
      <Avatar user={user} size={props.avatarSize} />
    </Link>
  );
  return <PageLayout userLink={userLink} />;
}

// Now, we have:
<Page user={user} avatarSize={avatarSize} />
// ... which renders ...
<PageLayout userLink={...} />
// ... which renders ...
<NavigationBar userLink={...} />
// ... which renders ...
{props.userLink}
```

With this change, only the top-most Page component needs to know about the `Link` and `Avatar` components’ use of `user` and `avatarSize`.

This *inversion of control* can make your code cleaner in many cases by reducing the amount of props you need to pass through your application and giving more control to the root components. Such inversion, however, isn’t the right choice in every case; moving more complexity higher in the tree makes those higher-level components more complicated and forces the lower-level components to be more flexible than you may want.

You’re not limited to a single child for a component. You may pass multiple children, or even have multiple separate “slots” for children, [as documented here](/docs/composition-vs-inheritance.html#containment):

```
function Page(props) {
  const user = props.user;
  const content = <Feed user={user} />;
  const topBar = (
    <NavigationBar>
      <Link href={user.permalink}>
        <Avatar user={user} size={props.avatarSize} />
      </Link>
    </NavigationBar>
  );
  return (
    <PageLayout
      topBar={topBar}
      content={content}
    />
  );
}
```

This pattern is sufficient for many cases when you need to decouple a child from its immediate parents. You can take it even further with [render props](/docs/render-props.html) if the child needs to communicate with the parent before rendering.

However, sometimes the same data needs to be accessible by many components in the tree, and at different nesting levels. Context lets you “broadcast” such data, and changes to it, to all components below. Common examples where using context might be simpler than the alternatives include managing the current locale, theme, or a data cache.

## [](#api)API

### [](#reactcreatecontext)`React.createContext`

```
const MyContext = React.createContext(defaultValue);
```

Creates a Context object. When React renders a component that subscribes to this Context object it will read the current context value from the closest matching `Provider` above it in the tree.

The `defaultValue` argument is **only** used when a component does not have a matching Provider above it in the tree. This default value can be helpful for testing components in isolation without wrapping them. Note: passing `undefined` as a Provider value does not cause consuming components to use `defaultValue`.

### [](#contextprovider)`Context.Provider`

```
<MyContext.Provider value={/* some value */}>
```

Every Context object comes with a Provider React component that allows consuming components to subscribe to context changes.

The Provider component accepts a `value` prop to be passed to consuming components that are descendants of this Provider. One Provider can be connected to many consumers. Providers can be nested to override values deeper within the tree.

All consumers that are descendants of a Provider will re-render whenever the Provider’s `value` prop changes. The propagation from Provider to its descendant consumers (including [`.contextType`](#classcontexttype) and [`useContext`](/docs/hooks-reference.html#usecontext)) is not subject to the `shouldComponentUpdate` method, so the consumer is updated even when an ancestor component skips an update.

Changes are determined by comparing the new and old values using the same algorithm as [`Object.is`](//developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is#Description).

> Note
>
> The way changes are determined can cause some issues when passing objects as `value`: see [Caveats](#caveats).

### [](#classcontexttype)`Class.contextType`

```
class MyClass extends React.Component {
  componentDidMount() {
    let value = this.context;
    /* perform a side-effect at mount using the value of MyContext */
  }
  componentDidUpdate() {
    let value = this.context;
    /* ... */
  }
  componentWillUnmount() {
    let value = this.context;
    /* ... */
  }
  render() {
    let value = this.context;
    /* render something based on the value of MyContext */
  }
}
MyClass.contextType = MyContext;
```

The `contextType` property on a class can be assigned a Context object created by [`React.createContext()`](#reactcreatecontext). Using this property lets you consume the nearest current value of that Context type using `this.context`. You can reference this in any of the lifecycle methods including the render function.

> Note:
>
> You can only subscribe to a single context using this API. If you need to read more than one see [Consuming Multiple Contexts](#consuming-multiple-contexts).
>
> If you are using the experimental [public class fields syntax](https://babeljs.io/docs/plugins/transform-class-properties/), you can use a **static** class field to initialize your `contextType`.

```
class MyClass extends React.Component {
  static contextType = MyContext;
  render() {
    let value = this.context;
    /* render something based on the value */
  }
}
```

### [](#contextconsumer)`Context.Consumer`

```
<MyContext.Consumer>
  {value => /* render something based on the context value */}
</MyContext.Consumer>
```

A React component that subscribes to context changes. Using this component lets you subscribe to a context within a [function component](/docs/components-and-props.html#function-and-class-components).

Requires a [function as a child](/docs/render-props.html#using-props-other-than-render). The function receives the current context value and returns a React node. The `value` argument passed to the function will be equal to the `value` prop of the closest Provider for this context above in the tree. If there is no Provider for this context above, the `value` argument will be equal to the `defaultValue` that was passed to `createContext()`.

> Note
>
> For more information about the ‘function as a child’ pattern, see [render props](/docs/render-props.html).

### [](#contextdisplayname)`Context.displayName`

Context object accepts a `displayName` string property. React DevTools uses this string to determine what to display for the context.

For example, the following component will appear as MyDisplayName in the DevTools:

```
const MyContext = React.createContext(/* some value */);
MyContext.displayName = 'MyDisplayName';
<MyContext.Provider> // "MyDisplayName.Provider" in DevTools
<MyContext.Consumer> // "MyDisplayName.Consumer" in DevTools
```

## [](#examples)Examples

### [](#dynamic-context)Dynamic Context

A more complex example with dynamic values for the theme:

**theme-context.js**

```
export const themes = {
  light: {
    foreground: '#000000',
    background: '#eeeeee',
  },
  dark: {
    foreground: '#ffffff',
    background: '#222222',
  },
};

export const ThemeContext = React.createContext(  themes.dark // default value);
```

**themed-button.js**

```
import {ThemeContext} from './theme-context';

class ThemedButton extends React.Component {
  render() {
    let props = this.props;
    let theme = this.context;    return (
      <button
        {...props}
        style={{backgroundColor: theme.background}}
      />
    );
  }
}
ThemedButton.contextType = ThemeContext;
export default ThemedButton;
```

**app.js**

```
import {ThemeContext, themes} from './theme-context';
import ThemedButton from './themed-button';

// An intermediate component that uses the ThemedButton
function Toolbar(props) {
  return (
    <ThemedButton onClick={props.changeTheme}>
      Change Theme
    </ThemedButton>
  );
}

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      theme: themes.light,
    };

    this.toggleTheme = () => {
      this.setState(state => ({
        theme:
          state.theme === themes.dark
            ? themes.light
            : themes.dark,
      }));
    };
  }

  render() {
    // The ThemedButton button inside the ThemeProvider    // uses the theme from state while the one outside uses    // the default dark theme    return (
      <Page>
        <ThemeContext.Provider value={this.state.theme}>          <Toolbar changeTheme={this.toggleTheme} />        </ThemeContext.Provider>        <Section>
          <ThemedButton />        </Section>
      </Page>
    );
  }
}

const root = ReactDOM.createRoot(
  document.getElementById('root')
);
root.render(<App />);
```

### [](#updating-context-from-a-nested-component)Updating Context from a Nested Component

It is often necessary to update the context from a component that is nested somewhere deeply in the component tree. In this case you can pass a function down through the context to allow consumers to update the context:

**theme-context.js**

```
// Make sure the shape of the default value passed to
// createContext matches the shape that the consumers expect!
export const ThemeContext = React.createContext({
  theme: themes.dark,  toggleTheme: () => {},});
```

**theme-toggler-button.js**

```
import {ThemeContext} from './theme-context';

function ThemeTogglerButton() {
  // The Theme Toggler Button receives not only the theme  // but also a toggleTheme function from the context  return (
    <ThemeContext.Consumer>
      {({theme, toggleTheme}) => (        <button
          onClick={toggleTheme}
          style={{backgroundColor: theme.background}}>
          Toggle Theme
        </button>
      )}
    </ThemeContext.Consumer>
  );
}

export default ThemeTogglerButton;
```

**app.js**

```
import {ThemeContext, themes} from './theme-context';
import ThemeTogglerButton from './theme-toggler-button';

class App extends React.Component {
  constructor(props) {
    super(props);

    this.toggleTheme = () => {
      this.setState(state => ({
        theme:
          state.theme === themes.dark
            ? themes.light
            : themes.dark,
      }));
    };

    // State also contains the updater function so it will    // be passed down into the context provider    this.state = {
      theme: themes.light,
      toggleTheme: this.toggleTheme,    };
  }

  render() {
    // The entire state is passed to the provider    return (
      <ThemeContext.Provider value={this.state}>        <Content />
      </ThemeContext.Provider>
    );
  }
}

function Content() {
  return (
    <div>
      <ThemeTogglerButton />
    </div>
  );
}

const root = ReactDOM.createRoot(
  document.getElementById('root')
);
root.render(<App />);
```

### [](#consuming-multiple-contexts)Consuming Multiple Contexts

To keep context re-rendering fast, React needs to make each context consumer a separate node in the tree.

```
// Theme context, default to light theme
const ThemeContext = React.createContext('light');

// Signed-in user context
const UserContext = React.createContext({
  name: 'Guest',
});

class App extends React.Component {
  render() {
    const {signedInUser, theme} = this.props;

    // App component that provides initial context values
    return (
      <ThemeContext.Provider value={theme}>        <UserContext.Provider value={signedInUser}>          <Layout />
        </UserContext.Provider>      </ThemeContext.Provider>    );
  }
}

function Layout() {
  return (
    <div>
      <Sidebar />
      <Content />
    </div>
  );
}

// A component may consume multiple contexts
function Content() {
  return (
    <ThemeContext.Consumer>      {theme => (        <UserContext.Consumer>          {user => (            <ProfilePage user={user} theme={theme} />          )}        </UserContext.Consumer>      )}    </ThemeContext.Consumer>  );
}
```

If two or more context values are often used together, you might want to consider creating your own render prop component that provides both.

## [](#caveats)Caveats

Because context uses reference identity to determine when to re-render, there are some gotchas that could trigger unintentional renders in consumers when a provider’s parent re-renders. For example, the code below will re-render all consumers every time the Provider re-renders because a new object is always created for `value`:

```
class App extends React.Component {
  render() {
    return (
      <MyContext.Provider value={{something: 'something'}}>        <Toolbar />
      </MyContext.Provider>
    );
  }
}
```

To get around this, lift the value into the parent’s state:

```
class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      value: {something: 'something'},    };
  }

  render() {
    return (
      <MyContext.Provider value={this.state.value}>        <Toolbar />
      </MyContext.Provider>
    );
  }
}
```

## [](#legacy-api)Legacy API

> Note
>
> React previously shipped with an experimental context API. The old API will be supported in all 16.x releases, but applications using it should migrate to the new version. The legacy API will be removed in a future major React version. Read the [legacy context docs here](/docs/legacy-context.html).

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/context.md)

----
url: https://legacy.reactjs.org/docs/testing-recipes.html
----

Common testing patterns for React components.

> Note:
>
> This page assumes you’re using [Jest](https://jestjs.io/) as a test runner. If you use a different test runner, you may need to adjust the API, but the overall shape of the solution will likely be the same. Read more details on setting up a testing environment on the [Testing Environments](/docs/testing-environments.html) page.

On this page, we will primarily use function components. However, these testing strategies don’t depend on implementation details, and work just as well for class components too.

* [Setup/Teardown](#setup--teardown)
* [`act()`](#act)
* [Rendering](#rendering)
* [Data Fetching](#data-fetching)
* [Mocking Modules](#mocking-modules)
* [Events](#events)
* [Timers](#timers)
* [Snapshot Testing](#snapshot-testing)
* [Multiple Renderers](#multiple-renderers)
* [Something Missing?](#something-missing)

***

### [](#setup--teardown)Setup/Teardown

For each test, we usually want to render our React tree to a DOM element that’s attached to `document`. This is important so that it can receive DOM events. When the test ends, we want to “clean up” and unmount the tree from the `document`.

A common way to do it is to use a pair of `beforeEach` and `afterEach` blocks so that they’ll always run and isolate the effects of a test to itself:

```
import { unmountComponentAtNode } from "react-dom";

let container = null;
beforeEach(() => {
  // setup a DOM element as a render target
  container = document.createElement("div");
  document.body.appendChild(container);
});

afterEach(() => {
  // cleanup on exiting
  unmountComponentAtNode(container);
  container.remove();
  container = null;
});
```

You may use a different pattern, but keep in mind that we want to execute the cleanup *even if a test fails*. Otherwise, tests can become “leaky”, and one test can change the behavior of another test. That makes them difficult to debug.

***

### [](#act)`act()`

When writing UI tests, tasks like rendering, user events, or data fetching can be considered as “units” of interaction with a user interface. `react-dom/test-utils` provides a helper called [`act()`](/docs/test-utils.html#act) that makes sure all updates related to these “units” have been processed and applied to the DOM before you make any assertions:

```
act(() => {
  // render components
});
// make assertions
```

This helps make your tests run closer to what real users would experience when using your application. The rest of these examples use `act()` to make these guarantees.

You might find using `act()` directly a bit too verbose. To avoid some of the boilerplate, you could use a library like [React Testing Library](https://testing-library.com/react), whose helpers are wrapped with `act()`.

> Note:
>
> The name `act` comes from the [Arrange-Act-Assert](http://wiki.c2.com/?ArrangeActAssert) pattern.

***

### [](#rendering)Rendering

Commonly, you might want to test whether a component renders correctly for given props. Consider a simple component that renders a message based on a prop:

```
// hello.js

import React from "react";

export default function Hello(props) {
  if (props.name) {
    return <h1>Hello, {props.name}!</h1>;
  } else {
    return <span>Hey, stranger</span>;
  }
}
```

We can write a test for this component:

```
// hello.test.js

import React from "react";
import { render, unmountComponentAtNode } from "react-dom";
import { act } from "react-dom/test-utils";

import Hello from "./hello";

let container = null;
beforeEach(() => {
  // setup a DOM element as a render target
  container = document.createElement("div");
  document.body.appendChild(container);
});

afterEach(() => {
  // cleanup on exiting
  unmountComponentAtNode(container);
  container.remove();
  container = null;
});

it("renders with or without a name", () => {
  act(() => {    render(<Hello />, container);  });  expect(container.textContent).toBe("Hey, stranger");
  act(() => {
    render(<Hello name="Jenny" />, container);
  });
  expect(container.textContent).toBe("Hello, Jenny!");

  act(() => {
    render(<Hello name="Margaret" />, container);
  });
  expect(container.textContent).toBe("Hello, Margaret!");
});
```

***

### [](#data-fetching)Data Fetching

Instead of calling real APIs in all your tests, you can mock requests with dummy data. Mocking data fetching with “fake” data prevents flaky tests due to an unavailable backend, and makes them run faster. Note: you may still want to run a subset of tests using an [“end-to-end”](/docs/testing-environments.html#end-to-end-tests-aka-e2e-tests) framework that tells whether the whole app is working together.

```
// user.js

import React, { useState, useEffect } from "react";

export default function User(props) {
  const [user, setUser] = useState(null);

  async function fetchUserData(id) {
    const response = await fetch("/" + id);
    setUser(await response.json());
  }

  useEffect(() => {
    fetchUserData(props.id);
  }, [props.id]);

  if (!user) {
    return "loading...";
  }

  return (
    <details>
      <summary>{user.name}</summary>
      <strong>{user.age}</strong> years old
      <br />
      lives in {user.address}
    </details>
  );
}
```

We can write tests for it:

```
// user.test.js

import React from "react";
import { render, unmountComponentAtNode } from "react-dom";
import { act } from "react-dom/test-utils";
import User from "./user";

let container = null;
beforeEach(() => {
  // setup a DOM element as a render target
  container = document.createElement("div");
  document.body.appendChild(container);
});

afterEach(() => {
  // cleanup on exiting
  unmountComponentAtNode(container);
  container.remove();
  container = null;
});

it("renders user data", async () => {
  const fakeUser = {    name: "Joni Baez",    age: "32",    address: "123, Charming Avenue"  };  jest.spyOn(global, "fetch").mockImplementation(() =>    Promise.resolve({      json: () => Promise.resolve(fakeUser)    })  );
  // Use the asynchronous version of act to apply resolved promises
  await act(async () => {
    render(<User id="123" />, container);
  });

  expect(container.querySelector("summary").textContent).toBe(fakeUser.name);
  expect(container.querySelector("strong").textContent).toBe(fakeUser.age);
  expect(container.textContent).toContain(fakeUser.address);

  // remove the mock to ensure tests are completely isolated  global.fetch.mockRestore();});
```

***

### [](#mocking-modules)Mocking Modules

Some modules might not work well inside a testing environment, or may not be as essential to the test itself. Mocking out these modules with dummy replacements can make it easier to write tests for your own code.

Consider a `Contact` component that embeds a third-party `GoogleMap` component:

```
// map.js

import React from "react";

import { LoadScript, GoogleMap } from "react-google-maps";
export default function Map(props) {
  return (
    <LoadScript id="script-loader" googleMapsApiKey="YOUR_API_KEY">
      <GoogleMap id="example-map" center={props.center} />
    </LoadScript>
  );
}

// contact.js

import React from "react";
import Map from "./map";

export default function Contact(props) {
  return (
    <div>
      <address>
        Contact {props.name} via{" "}
        <a data-testid="email" href={"mailto:" + props.email}>
          email
        </a>
        or on their <a data-testid="site" href={props.site}>
          website
        </a>.
      </address>
      <Map center={props.center} />
    </div>
  );
}
```

If we don’t want to load this component in our tests, we can mock out the dependency itself to a dummy component, and run our tests:

```
// contact.test.js

import React from "react";
import { render, unmountComponentAtNode } from "react-dom";
import { act } from "react-dom/test-utils";

import Contact from "./contact";
import MockedMap from "./map";

jest.mock("./map", () => {  return function DummyMap(props) {    return (      <div data-testid="map">        {props.center.lat}:{props.center.long}      </div>    );  };});
let container = null;
beforeEach(() => {
  // setup a DOM element as a render target
  container = document.createElement("div");
  document.body.appendChild(container);
});

afterEach(() => {
  // cleanup on exiting
  unmountComponentAtNode(container);
  container.remove();
  container = null;
});

it("should render contact information", () => {
  const center = { lat: 0, long: 0 };
  act(() => {
    render(
      <Contact
        name="Joni Baez"
        email="test@example.com"
        site="http://test.com"
        center={center}
      />,
      container
    );
  });

  expect(
    container.querySelector("[data-testid='email']").getAttribute("href")
  ).toEqual("mailto:test@example.com");

  expect(
    container.querySelector('[data-testid="site"]').getAttribute("href")
  ).toEqual("http://test.com");

  expect(container.querySelector('[data-testid="map"]').textContent).toEqual(
    "0:0"
  );
});
```

***

### [](#events)Events

We recommend dispatching real DOM events on DOM elements, and then asserting on the result. Consider a `Toggle` component:

```
// toggle.js

import React, { useState } from "react";

export default function Toggle(props) {
  const [state, setState] = useState(false);
  return (
    <button
      onClick={() => {
        setState(previousState => !previousState);
        props.onChange(!state);
      }}
      data-testid="toggle"
    >
      {state === true ? "Turn off" : "Turn on"}
    </button>
  );
}
```

We could write tests for it:

```
// toggle.test.js

import React from "react";
import { render, unmountComponentAtNode } from "react-dom";
import { act } from "react-dom/test-utils";

import Toggle from "./toggle";

let container = null;
beforeEach(() => {
  // setup a DOM element as a render target
  container = document.createElement("div");
  document.body.appendChild(container);});
afterEach(() => {
  // cleanup on exiting
  unmountComponentAtNode(container);
  container.remove();
  container = null;
});

it("changes value when clicked", () => {
  const onChange = jest.fn();
  act(() => {
    render(<Toggle onChange={onChange} />, container);
  });

  // get a hold of the button element, and trigger some clicks on it
  const button = document.querySelector("[data-testid=toggle]");
  expect(button.innerHTML).toBe("Turn on");

  act(() => {
    button.dispatchEvent(new MouseEvent("click", { bubbles: true }));
  });
  expect(onChange).toHaveBeenCalledTimes(1);
  expect(button.innerHTML).toBe("Turn off");

  act(() => {
    for (let i = 0; i < 5; i++) {
      button.dispatchEvent(new MouseEvent("click", { bubbles: true }));
    }  });

  expect(onChange).toHaveBeenCalledTimes(6);
  expect(button.innerHTML).toBe("Turn on");
});
```

Different DOM events and their properties are described in [MDN](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent). Note that you need to pass `{ bubbles: true }` in each event you create for it to reach the React listener because React automatically delegates events to the root.

> Note:
>
> React Testing Library offers a [more concise helper](https://testing-library.com/docs/dom-testing-library/api-events) for firing events.

***

### [](#timers)Timers

Your code might use timer-based functions like `setTimeout` to schedule more work in the future. In this example, a multiple choice panel waits for a selection and advances, timing out if a selection isn’t made in 5 seconds:

```
// card.js

import React, { useEffect } from "react";

export default function Card(props) {
  useEffect(() => {
    const timeoutID = setTimeout(() => {
      props.onSelect(null);
    }, 5000);
    return () => {
      clearTimeout(timeoutID);
    };
  }, [props.onSelect]);

  return [1, 2, 3, 4].map(choice => (
    <button
      key={choice}
      data-testid={choice}
      onClick={() => props.onSelect(choice)}
    >
      {choice}
    </button>
  ));
}
```

We can write tests for this component by leveraging [Jest’s timer mocks](https://jestjs.io/docs/en/timer-mocks), and testing the different states it can be in.

```
// card.test.js

import React from "react";
import { render, unmountComponentAtNode } from "react-dom";
import { act } from "react-dom/test-utils";

import Card from "./card";
let container = null;
beforeEach(() => {
  // setup a DOM element as a render target
  container = document.createElement("div");
  document.body.appendChild(container);
  jest.useFakeTimers();
});

afterEach(() => {
  // cleanup on exiting
  unmountComponentAtNode(container);
  container.remove();
  container = null;
  jest.useRealTimers();
});

it("should select null after timing out", () => {
  const onSelect = jest.fn();
  act(() => {
    render(<Card onSelect={onSelect} />, container);
  });

  // move ahead in time by 100ms  act(() => {
    jest.advanceTimersByTime(100);
  });
  expect(onSelect).not.toHaveBeenCalled();

  // and then move ahead by 5 seconds  act(() => {
    jest.advanceTimersByTime(5000);
  });
  expect(onSelect).toHaveBeenCalledWith(null);
});

it("should cleanup on being removed", () => {
  const onSelect = jest.fn();
  act(() => {
    render(<Card onSelect={onSelect} />, container);
  });
  act(() => {
    jest.advanceTimersByTime(100);
  });
  expect(onSelect).not.toHaveBeenCalled();

  // unmount the app
  act(() => {
    render(null, container);
  });
  act(() => {
    jest.advanceTimersByTime(5000);
  });
  expect(onSelect).not.toHaveBeenCalled();
});

it("should accept selections", () => {
  const onSelect = jest.fn();
  act(() => {
    render(<Card onSelect={onSelect} />, container);
  });

  act(() => {
    container
      .querySelector("[data-testid='2']")
      .dispatchEvent(new MouseEvent("click", { bubbles: true }));
  });

  expect(onSelect).toHaveBeenCalledWith(2);
});
```

You can use fake timers only in some tests. Above, we enabled them by calling `jest.useFakeTimers()`. The main advantage they provide is that your test doesn’t actually have to wait five seconds to execute, and you also didn’t need to make the component code more convoluted just for testing.

***

### [](#snapshot-testing)Snapshot Testing

Frameworks like Jest also let you save “snapshots” of data with [`toMatchSnapshot` / `toMatchInlineSnapshot`](https://jestjs.io/docs/en/snapshot-testing). With these, we can “save” the rendered component output and ensure that a change to it has to be explicitly committed as a change to the snapshot.

In this example, we render a component and format the rendered HTML with the [`pretty`](https://www.npmjs.com/package/pretty) package, before saving it as an inline snapshot:

```
// hello.test.js, again

import React from "react";
import { render, unmountComponentAtNode } from "react-dom";
import { act } from "react-dom/test-utils";
import pretty from "pretty";

import Hello from "./hello";

let container = null;
beforeEach(() => {
  // setup a DOM element as a render target
  container = document.createElement("div");
  document.body.appendChild(container);
});

afterEach(() => {
  // cleanup on exiting
  unmountComponentAtNode(container);
  container.remove();
  container = null;
});

it("should render a greeting", () => {
  act(() => {
    render(<Hello />, container);
  });

  expect(    pretty(container.innerHTML)  ).toMatchInlineSnapshot(); /* ... gets filled automatically by jest ... */
  act(() => {
    render(<Hello name="Jenny" />, container);
  });

  expect(
    pretty(container.innerHTML)
  ).toMatchInlineSnapshot(); /* ... gets filled automatically by jest ... */

  act(() => {
    render(<Hello name="Margaret" />, container);
  });

  expect(
    pretty(container.innerHTML)
  ).toMatchInlineSnapshot(); /* ... gets filled automatically by jest ... */
});
```

It’s typically better to make more specific assertions than to use snapshots. These kinds of tests include implementation details so they break easily, and teams can get desensitized to snapshot breakages. Selectively [mocking some child components](#mocking-modules) can help reduce the size of snapshots and keep them readable for the code review.

***

### [](#multiple-renderers)Multiple Renderers

In rare cases, you may be running a test on a component that uses multiple renderers. For example, you may be running snapshot tests on a component with `react-test-renderer`, that internally uses `render` from `react-dom` inside a child component to render some content. In this scenario, you can wrap updates with `act()`s corresponding to their renderers.

```
import { act as domAct } from "react-dom/test-utils";
import { act as testAct, create } from "react-test-renderer";
// ...
let root;
domAct(() => {
  testAct(() => {
    root = create(<App />);
  });
});
expect(root).toMatchSnapshot();
```

***

### [](#something-missing)Something Missing?

If some common scenario is not covered, please let us know on the [issue tracker](https://github.com/reactjs/reactjs.org/issues) for the documentation website.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/testing-recipes.md)

* Previous article

  [Testing Overview](/docs/testing.html)

* Next article

  [Testing Environments](/docs/testing-environments.html)

----
url: https://legacy.reactjs.org/blog/2015/08/13/reacteurope-roundup.html
----

August 13, 2015 by [Matthew Johnston](https://github.com/matthewathome)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

Last month, the first React.js European conference took place in the city of Paris, at ReactEurope. Attendees were treated to a range of talks covering React, React Native, Flux, Relay, and GraphQL. Big thanks to everyone involved with organizing the conference, to all the attendees, and everyone who gave their time to speak - it wouldn’t have been possible without the help and support of the React community.

[Christopher Chedeau](https://github.com/vjeux) gave the opening keynote to the conference:

[Spencer Ahrens](https://github.com/sahrens) walks through building an advanced gestural UI leveraging the unique power of the React Native layout and animation systems to build a complex and fluid experience:

[Lee Byron](https://github.com/leebyron) explores GraphQL, its core principles, how it works, and what makes it a powerful tool:

[Joseph Savona](https://github.com/josephsavona) explores the problems Relay solves, its architecture and the query lifecycle, and how can you use Relay to build more scalable apps. There are examples of how Relay powers applications as complex as the Facebook News Feed:

[Nick Schrock](https://github.com/schrockn) and [Dan Schafer](https://github.com/dschafer) take a deeper dive into putting GraphQL to work. How can we build a GraphQL API to work with an existing REST API or server-side data model? What are best practices when building a GraphQL API, and how do they differ from traditional REST best practices? How does Facebook use GraphQL? Most importantly, what does a complete and coherent GraphQL API looks like, and how can we get started building one?

[Sebastian Markbåge](https://github.com/sebmarkbage) talks about why the DOM is flawed and how it is becoming a second-class citizen in the land of React apps:

[Sebastian McKenzie](https://github.com/sebmck) goes over how existing JSX build pipeline infrastructure can be further utilised to perform even more significant code transformations such as transpilation, optimisation, profiling and more, reducing bugs, making your code faster and you as a developer more productive and happy:

[Cheng Lou](https://github.com/chenglou) gives a talk on the past, the present and the future of animation, and the place React can potentially take in this:

And there was a Q\&A session with the whole team covering a range of React topics:

And there were lots of great talks from the React community:

* [Michael Chan](https://www.youtube.com/watch?v=ERB1TJBn32c\&list=PLCC436JpVnK0Phxld2dD4tM4xPMxJCiRD\&index=2) looks at how to solve problems like CSS theming and media queries with contexts and plain old JavaScript. He also looks at the role of container-components and when it’s better to “just use CSS.”.
* [Elie Rotenberg](https://www.youtube.com/watch?v=JSjhhUvB9DY\&index=3\&list=PLCC436JpVnK0Phxld2dD4tM4xPMxJCiRD) talks about Flux over the Wire, building isomorphic, real-time React apps using a novel interpretation of Flux.
* [Ryan Florence](https://www.youtube.com/watch?v=BF58ZJ1ZQxY\&list=PLCC436JpVnK0Phxld2dD4tM4xPMxJCiRD\&index=6) says “Your front and back ends are already successfully in production but you don’t have to miss out on the productivity that React brings. Forget the rewrites, this is brownfield!”.
* [Dan Abramov](https://www.youtube.com/watch?v=xsSnOQynTHs\&index=7\&list=PLCC436JpVnK0Phxld2dD4tM4xPMxJCiRD) demonstrates how React can be used together with webpack Hot Module Replacement to create a live editing environment with time travel that supercharges your debugging experience and transforms the way you work on real apps every day.
* [Mikhail Davydov](https://www.youtube.com/watch?v=ee_U2t-8L48\&index=10\&list=PLCC436JpVnK0Phxld2dD4tM4xPMxJCiRD) shows you how to ask the browser layout engine for help, how to avoid slavery of DSL, and build declarative Text UI using only web-technologies like HTML, JS, CSS and React.
* [Kevin Robinson](https://www.youtube.com/watch?v=EOz4D_714R8\&list=PLCC436JpVnK3HvUSAHpt-LRJkIK8pQG6R\&index=3) shares how user experience choices are a primary influence on how Twitter design the data layer, especially for teams developing new products with full-stack capabilities.
* [Jed Watson](https://www.youtube.com/watch?v=ctwmd5L1U_Q\&list=PLCC436JpVnK3HvUSAHpt-LRJkIK8pQG6R\&index=4) shares what Thinkmill have learned about React and mobile app development, and how they’ve approached the unique challenges of mobile web apps - with tools that are useful to all developers building touch interfaces with React, as well as a walkthrough of their development process and framework.
* [Michael Jackson](https://www.youtube.com/watch?v=Q6Kczrgw6ic\&list=PLCC436JpVnK3HvUSAHpt-LRJkIK8pQG6R\&index=5) discusses how your users can benefit from the many tools that React Router provides including server-side rendering, real URLs on native devices, and much, much more.
* [Michael Ridgway](https://www.youtube.com/watch?v=MrozpFEBEBE\&index=7\&list=PLCC436JpVnK3HvUSAHpt-LRJkIK8pQG6R) walks you through an isomorphic Flux architecture to give you the holy grail of frontend development.
* [Aria Buckles](https://www.youtube.com/watch?v=2Qu-Ulrsfl8\&index=8\&list=PLCC436JpVnK3HvUSAHpt-LRJkIK8pQG6R) covers Khan Academy’s techniques and patterns to make dealing with large pure components simpler, as well as current open questions.
* [Evan Morikawa and Ben Gotow](https://www.youtube.com/watch?v=Uu4Yz2HmCgE\&index=9\&list=PLCC436JpVnK3HvUSAHpt-LRJkIK8pQG6R) talk about specific features of React & Flux, React CSS, programming design patterns, and custom libraries, which can turn a static application into a dynamic platform that an ecosystem of developers can build on top of.
* [Zalando](https://www.youtube.com/watch?v=3EQhkquvVmY\&list=PLCC436JpVnK0Phxld2dD4tM4xPMxJCiRD\&index=9), [Rangle.io](https://www.youtube.com/watch?v=nAWKR1bBDsU\&index=12\&list=PLCC436JpVnK0Phxld2dD4tM4xPMxJCiRD), [Automattic](https://www.youtube.com/watch?v=hjhyrBbDp6U\&index=13\&list=PLCC436JpVnK0Phxld2dD4tM4xPMxJCiRD), [Thinkmill](https://www.youtube.com/watch?v=ApoCktYaRxk\&list=PLCC436JpVnK0Phxld2dD4tM4xPMxJCiRD\&index=14), and [Red Badger](https://www.youtube.com/watch?v=hdKidiwR8DM\&list=PLCC436JpVnK0Phxld2dD4tM4xPMxJCiRD\&index=15) provided lots of insight into how larger companies are using React.

There was also a [great series of Lightning talks](https://www.youtube.com/playlist?list=PLCC436JpVnK3xnOZ727t0vd3nbb5ZqCyo) from [Joshua Sierles](https://github.com/jsierles), [Ovidiu Cherecheș](https://github.com/skidding), [Mike Grabowski](https://github.com/grabbou), [Dave Brotherstone](https://github.com/bruderstein), [Sunil Pai](https://github.com/threepointone), [Andreas Savvides](https://github.com/AnSavvides), and [Petr Bela](https://github.com/petrbela).

You can view the full list of talks on [the ReactEurope YouTube channel](https://www.youtube.com/channel/UCorlLn2oZfgOJ-FUcF2eZ1A).

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2015-08-13-reacteurope-roundup.md)

----
url: https://legacy.reactjs.org/blog/2014/09/12/community-round-up-22.html
----

September 12, 2014 by [Lou Husson](https://twitter.com/loukan42)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

This has been an exciting summer as four big companies: Yahoo, Mozilla, Airbnb and Reddit announced that they were using React!

|                                                                                                                                                                                                                                                                                                                                             |                                                                                                                                                                                                                                                                |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| > Our friends at [@yahoo](https://twitter.com/Yahoo) talk about migrating Yahoo! Mail from YUI to ReactJS at the next [#ReactJS](https://twitter.com/hashtag/ReactJS?src=hash) meetup! <http://t.co/Cu2AaE0sVE>
>
> — Facebook Open Source (@fbOpenSource) [September 12, 2014](https://twitter.com/fbOpenSource/status/510258065900572672) | > I guess [@reactjs](https://twitter.com/reactjs) is getting into Firefox :-) Thanks [@n1k0](https://twitter.com/n1k0) ! <https://t.co/kipfUS0hu4>
>
> — David Bruant (@DavidBruant) [July 4, 2014](https://twitter.com/DavidBruant/status/484956929933213696) |
| > .[@AirbnbNerds](https://twitter.com/AirbnbNerds) just launched our first user-facing React.js feature to production! We love it so far. <https://t.co/KtyudemcIW> /[@floydophone](https://twitter.com/floydophone)
>
> — spikebrehm (@spikebrehm) [July 22, 2014](https://twitter.com/spikebrehm/statuses/491645223643013121)             | > We shipped reddit's first production [@reactjs](https://twitter.com/reactjs) code last week, our checkout process. <https://t.co/KUInwsCmAF>
>
> — Brian Holt (@holtbt) [July 28, 2014](https://twitter.com/holtbt/statuses/493852312604254208)              |

## [](#reacts-architecture)React’s Architecture

[Vjeux](http://blog.vjeux.com/), from the React team, gave a talk at OSCON on the history of React and the various optimizations strategies that are implemented. You can also check out the [annotated slides](https://speakerdeck.com/vjeux/oscon-react-architecture) or [Chris Dawson](http://thenewstack.io/author/chrisdawson/)’s notes titled [JavaScript’s History and How it Led To React](http://thenewstack.io/javascripts-history-and-how-it-led-to-reactjs/).

## [](#v8-optimizations)v8 optimizations

Jakob Kummerow landed [two optimizations to V8](http://www.chromium.org/developers/speed-hall-of-fame#TOC-2014-06-18) specifically targeted at optimizing React. That’s really exciting to see browser vendors helping out on performance!

## [](#reusable-components-by-khan-academy)Reusable Components by Khan Academy

[Khan Academy](https://www.khanacademy.org/) released [many high quality standalone components](https://khan.github.io/react-components/) they are using. This is a good opportunity to see what React code used in production look like.

```
var TeX = require('react-components/js/tex.jsx');
React.renderComponent(<TeX>\nabla \cdot E = 4 \pi \rho</TeX>, domNode);

var translated = (
  <$_ first="Motoko" last="Kusanagi">
    Hello, %(first)s %(last)s!
  </$_>
);
```

## [](#react--browserify--gulp)React + Browserify + Gulp

[Trường](http://truongtx.me/) wrote a little guide to help your [getting started using React, Browserify and Gulp](http://truongtx.me/2014/07/18/using-reactjs-with-browserify-and-gulp/).

[](http://truongtx.me/2014/07/18/using-reactjs-with-browserify-and-gulp/)

## [](#react-style)React Style

After React put HTML inside of JavaScript, Sander Spies takes the same approach with CSS: [IntegratedCSS](https://github.com/SanderSpies/react-style). It seems weird at first but this is the direction where React is heading.

```
var Button = React.createClass({
  normalStyle: ReactStyle(function() {
    return { backgroundColor: vars.orange };
  }),
  activeStyle: ReactStyle(function() {
    if (this.state.active) {
      return { color: 'yellow', padding: '10px' };
    }
  }),
  render: function() {
    return (
      <div styles={[this.normalStyle(), this.activeStyle()]}>
        Hello, I'm styled
      </div>
    );
  }
});
```

## [](#virtual-dom-in-elm)Virtual DOM in Elm

[Evan Czaplicki](http://evan.czaplicki.us) explains how Elm implements the idea of a Virtual DOM and a diffing algorithm. This is great to see React ideas spread to other languages.

> Performance is a good hook, but the real benefit is that this approach leads to code that is easier to understand and maintain. In short, it becomes very simple to create reusable HTML widgets and abstract out common patterns. This is why people with larger code bases should be interested in virtual DOM approaches.
>
> [Read the full article](http://elm-lang.org/blog/Blazing-Fast-Html.elm)

## [](#components-tutorial)Components Tutorial

If you are getting started with React, [Joe Maddalone](http://www.joemaddalone.com/) made a good tutorial on how to build your first component.

## [](#saving-time--staying-sane)Saving time & staying sane?

When [Kent William Innholt](http://http://kentwilliam.com/) who works at [M>Path](http://mpath.com/) summed up his experience using React in an [article](http://kentwilliam.com/articles/saving-time-staying-sane-pros-cons-of-react-js).

> We’re building an ambitious new web app, where the UI complexity represents most of the app’s complexity overall. It includes a tremendous amount of UI widgets as well as a lot rules on what-to-show-when. This is exactly the sort of situation React.js was built to simplify.
>
> * **Big win**: Tighter coupling of markup and behavior
> * **Jury’s still out**: CSS lives outside React.js
> * **Big win**: Cascading updates and functional thinking
> * **Jury’s still out**: Verbose propagation
>
> [Read the article…](http://kentwilliam.com/articles/saving-time-staying-sane-pros-cons-of-react-js)

## [](#weather)Weather

To finish this round-up, Andrew Gleave made a page that displays the [Weather](https://github.com/andrewgleave/react-weather). It’s great to see that React is also used for small prototypes.

[](https://github.com/andrewgleave/react-weather)

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2014-09-12-community-round-up-22.md)

----
url: https://legacy.reactjs.org/blog/2013/07/02/react-v0-4-autobind-by-default.html
----

July 02, 2013 by [Paul O’Shannessy](https://twitter.com/zpao)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

React v0.4 is very close to completion. As we finish it off, we’d like to share with you some of the major changes we’ve made since v0.3. This is the first of several posts we’ll be making over the next week.

## [](#what-is-reactautobind)What is React.autoBind?

If you take a look at most of our current examples, you’ll see us using `React.autoBind` for event handlers. This is used in place of `Function.prototype.bind`. Remember that in JS, [function calls are late-bound](https://bonsaiden.github.io/JavaScript-Garden/#function.this). That means that if you simply pass a function around, the `this` used inside won’t necessarily be the `this` you expect. `Function.prototype.bind` creates a new, properly bound, function so that when called, `this` is exactly what you expect it to be.

Before we launched React, we would write this:

```
React.createClass({
  onClick: function(event) {/* do something with this */},
  render: function() {
    return <button onClick={this.onClick.bind(this)} />;  }
});
```

We wrote `React.autoBind` as a way to cache the function creation and save on memory usage. Since `render` can get called multiple times, if you used `this.onClick.bind(this)` you would actually create a new function on each pass. With React v0.3 you were able to write this instead:

```
React.createClass({
  onClick: React.autoBind(function(event) {/* do something with this */}),  render: function() {
    return <button onClick={this.onClick} />;  }
});
```

## [](#whats-changing-in-v04)What’s Changing in v0.4?

After using `React.autoBind` for a few weeks, we realized that there were very few times that we didn’t want that behavior. So we made it the default! Now all methods defined within `React.createClass` will already be bound to the correct instance.

Starting with v0.4 you can just write this:

```
React.createClass({
  onClick: function(event) {/* do something with this */},  render: function() {
    return <button onClick={this.onClick} />;  }
});
```

For v0.4 we will simply be making `React.autoBind` a no-op — it will just return the function you pass to it. Most likely you won’t have to change your code to account for this change, though we encourage you to update. We’ll publish a migration guide documenting this and other changes that come along with React v0.4.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2013-07-02-react-v0-4-autobind-by-default.md)

----
url: https://react.dev/blog
----

[Blog](/blog)

# React Blog[](#undefined "Link for this heading")

This blog is the official source for the updates from the React team. Anything important, including release notes or deprecation notices, will be posted here first.

You can also follow the [@react.dev](https://bsky.app/profile/react.dev) account on Bluesky, or [@reactjs](https://twitter.com/reactjs) account on Twitter, but you won’t miss anything essential if you only read this blog.

## [The React Foundation: A New Home for React Hosted by the Linux Foundation](/blog/2026/02/24/the-react-foundation)

[February 24, 2026](/blog/2026/02/24/the-react-foundation)

[The React Foundation has officially launched under the Linux Foundation.](/blog/2026/02/24/the-react-foundation)

[Read more](/blog/2026/02/24/the-react-foundation)

## [Denial of Service and Source Code Exposure in React Server Components](/blog/2025/12/11/denial-of-service-and-source-code-exposure-in-react-server-components)

[December 11, 2025](/blog/2025/12/11/denial-of-service-and-source-code-exposure-in-react-server-components)

[Security researchers have found and disclosed two additional vulnerabilities in React Server Components while attempting to exploit the patches in last week’s critical vulnerability…](/blog/2025/12/11/denial-of-service-and-source-code-exposure-in-react-server-components)

[Read more](/blog/2025/12/11/denial-of-service-and-source-code-exposure-in-react-server-components)

## [Critical Security Vulnerability in React Server Components](/blog/2025/12/03/critical-security-vulnerability-in-react-server-components)

[December 3, 2025](/blog/2025/12/03/critical-security-vulnerability-in-react-server-components)

[There is an unauthenticated remote code execution vulnerability in React Server Components. A fix has been published in versions 19.0.1, 19.1.2, and 19.2.1. We recommend upgrading immediately.](/blog/2025/12/03/critical-security-vulnerability-in-react-server-components)

[Read more](/blog/2025/12/03/critical-security-vulnerability-in-react-server-components)

## [React Conf 2025 Recap](/blog/2025/10/16/react-conf-2025-recap)

[October 16, 2025](/blog/2025/10/16/react-conf-2025-recap)

[Last week we hosted React Conf 2025. In this post, we summarize the talks and announcements from the event…](/blog/2025/10/16/react-conf-2025-recap)

[Read more](/blog/2025/10/16/react-conf-2025-recap)

## [React Compiler v1.0](/blog/2025/10/07/react-compiler-1)

[October 7, 2025](/blog/2025/10/07/react-compiler-1)

[We’re releasing the compiler’s first stable release today, plus linting and tooling improvements to make adoption easier.](/blog/2025/10/07/react-compiler-1)

[Read more](/blog/2025/10/07/react-compiler-1)

## [Introducing the React Foundation](/blog/2025/10/07/introducing-the-react-foundation)

[October 7, 2025](/blog/2025/10/07/introducing-the-react-foundation)

[Today, we’re announcing our plans to create the React Foundation and a new technical governance structure …](/blog/2025/10/07/introducing-the-react-foundation)

[Read more](/blog/2025/10/07/introducing-the-react-foundation)

## [React 19.2](/blog/2025/10/01/react-19-2)

[October 1, 2025](/blog/2025/10/01/react-19-2)

[React 19.2 adds new features like Activity, React Performance Tracks, useEffectEvent, and more. In this post …](/blog/2025/10/01/react-19-2)

[Read more](/blog/2025/10/01/react-19-2)

## [React Labs: View Transitions, Activity, and more](/blog/2025/04/23/react-labs-view-transitions-activity-and-more)

[April 23, 2025](/blog/2025/04/23/react-labs-view-transitions-activity-and-more)

[In React Labs posts, we write about projects in active research and development. In this post, we’re sharing two new experimental features that are ready to try today, and sharing other areas we’re working on now …](/blog/2025/04/23/react-labs-view-transitions-activity-and-more)

[Read more](/blog/2025/04/23/react-labs-view-transitions-activity-and-more)

## [Sunsetting Create React App](/blog/2025/02/14/sunsetting-create-react-app)

[February 14, 2025](/blog/2025/02/14/sunsetting-create-react-app)

[Today, we’re deprecating Create React App for new apps, and encouraging existing apps to migrate to a framework, or to migrate to a build tool like Vite, Parcel, or RSBuild. We’re also providing docs for when a framework isn’t a good fit for your project, you want to build your own framework, or you just want to learn how React works by building a React app from scratch …](/blog/2025/02/14/sunsetting-create-react-app)

[Read more](/blog/2025/02/14/sunsetting-create-react-app)

## [React v19](/blog/2024/12/05/react-19)

[December 5, 2024](/blog/2024/12/05/react-19)

[In the React 19 Upgrade Guide, we shared step-by-step instructions for upgrading your app to React 19. In this post, we’ll give an overview of the new features in React 19, and how you can adopt them …](/blog/2024/12/05/react-19)

[Read more](/blog/2024/12/05/react-19)

## [React Compiler Beta Release](/blog/2024/10/21/react-compiler-beta-release)

[October 21, 2024](/blog/2024/10/21/react-compiler-beta-release)

[We announced an experimental release of React Compiler at React Conf 2024. We’ve made a lot of progress since then, and in this post we want to share what’s next for React Compiler …](/blog/2024/10/21/react-compiler-beta-release)

[Read more](/blog/2024/10/21/react-compiler-beta-release)

## [React Conf 2024 Recap](/blog/2024/05/22/react-conf-2024-recap)

[May 22, 2024](/blog/2024/05/22/react-conf-2024-recap)

[Last week we hosted React Conf 2024, a two-day conference in Henderson, Nevada where 700+ attendees gathered in-person to discuss the latest in UI engineering. This was our first in-person conference since 2019, and we were thrilled to be able to bring the community together again …](/blog/2024/05/22/react-conf-2024-recap)

[Read more](/blog/2024/05/22/react-conf-2024-recap)

## [React 19 Upgrade Guide](/blog/2024/04/25/react-19-upgrade-guide)

[April 25, 2024](/blog/2024/04/25/react-19-upgrade-guide)

[The improvements added to React 19 require some breaking changes, but we’ve worked to make the upgrade as smooth as possible, and we don’t expect the changes to impact most apps. In this post, we will guide you through the steps for upgrading libraries to React 19 …](/blog/2024/04/25/react-19-upgrade-guide)

[Read more](/blog/2024/04/25/react-19-upgrade-guide)

## [React Labs: What We've Been Working On – February 2024](/blog/2024/02/15/react-labs-what-we-have-been-working-on-february-2024)

[February 15, 2024](/blog/2024/02/15/react-labs-what-we-have-been-working-on-february-2024)

[In React Labs posts, we write about projects in active research and development. Since our last update, we’ve made significant progress on React Compiler, new features, and React 19, and we’d like to share what we learned.](/blog/2024/02/15/react-labs-what-we-have-been-working-on-february-2024)

[Read more](/blog/2024/02/15/react-labs-what-we-have-been-working-on-february-2024)

## [React Canaries: Incremental Feature Rollout Outside Meta](/blog/2023/05/03/react-canaries)

[May 3, 2023](/blog/2023/05/03/react-canaries)

[Traditionally, new React features used to only be available at Meta first, and land in the open source releases later. We’d like to offer the React community an option to adopt individual new features as soon as their design is close to final—similar to how Meta uses React internally. We are introducing a new officially supported Canary release channel. It lets curated setups like frameworks decouple adoption of individual React features from the React release schedule.](/blog/2023/05/03/react-canaries)

[Read more](/blog/2023/05/03/react-canaries)

## [React Labs: What We've Been Working On – March 2023](/blog/2023/03/22/react-labs-what-we-have-been-working-on-march-2023)

[March 22, 2023](/blog/2023/03/22/react-labs-what-we-have-been-working-on-march-2023)

[In React Labs posts, we write about projects in active research and development. Since our last update, we’ve made significant progress on React Server Components, Asset Loading, Optimizing Compiler, Offscreen Rendering, and Transition Tracing, and we’d like to share what we learned.](/blog/2023/03/22/react-labs-what-we-have-been-working-on-march-2023)

[Read more](/blog/2023/03/22/react-labs-what-we-have-been-working-on-march-2023)

## [Introducing react.dev](/blog/2023/03/16/introducing-react-dev)

[March 16, 2023](/blog/2023/03/16/introducing-react-dev)

[Today we are thrilled to launch react.dev, the new home for React and its documentation. In this post, we would like to give you a tour of the new site.](/blog/2023/03/16/introducing-react-dev)

[Read more](/blog/2023/03/16/introducing-react-dev)

## [React Labs: What We've Been Working On – June 2022](/blog/2022/06/15/react-labs-what-we-have-been-working-on-june-2022)

[June 15, 2022](/blog/2022/06/15/react-labs-what-we-have-been-working-on-june-2022)

[React 18 was years in the making, and with it brought valuable lessons for the React team. Its release was the result of many years of research and exploring many paths. Some of those paths were successful; many more were dead-ends that led to new insights. One lesson we’ve learned is that it’s frustrating for the community to wait for new features without having insight into these paths that we’re exploring…](/blog/2022/06/15/react-labs-what-we-have-been-working-on-june-2022)

[Read more](/blog/2022/06/15/react-labs-what-we-have-been-working-on-june-2022)

## [React v18.0](/blog/2022/03/29/react-v18)

[March 29, 2022](/blog/2022/03/29/react-v18)

[React 18 is now available on npm! In our last post, we shared step-by-step instructions for upgrading your app to React 18. In this post, we’ll give an overview of what’s new in React 18, and what it means for the future…](/blog/2022/03/29/react-v18)

[Read more](/blog/2022/03/29/react-v18)

## [How to Upgrade to React 18](/blog/2022/03/08/react-18-upgrade-guide)

[March 8, 2022](/blog/2022/03/08/react-18-upgrade-guide)

[As we shared in the release post, React 18 introduces features powered by our new concurrent renderer, with a gradual adoption strategy for existing applications. In this post, we will guide you through the steps for upgrading to React 18…](/blog/2022/03/08/react-18-upgrade-guide)

[Read more](/blog/2022/03/08/react-18-upgrade-guide)

## [React Conf 2021 Recap](/blog/2021/12/17/react-conf-2021-recap)

[December 17, 2021](/blog/2021/12/17/react-conf-2021-recap)

[Last week we hosted our 6th React Conf. In previous years, we’ve used the React Conf stage to deliver industry changing announcements such as React Native and React Hooks. This year, we shared our multi-platform vision for React, starting with the release of React 18 and gradual adoption of concurrent features…](/blog/2021/12/17/react-conf-2021-recap)

[Read more](/blog/2021/12/17/react-conf-2021-recap)

## [The Plan for React 18](/blog/2021/06/08/the-plan-for-react-18)

[June 8, 2021](/blog/2021/06/08/the-plan-for-react-18)

[The React team is excited to share a few updates:](/blog/2021/06/08/the-plan-for-react-18)

[* We’ve started work on the React 18 release, which will be our next major version.* We’ve created a Working Group to prepare the community for gradual adoption of new features in React 18.* We’ve published a React 18 Alpha so that library authors can try it and provide feedback…](/blog/2021/06/08/the-plan-for-react-18)

[Read more](/blog/2021/06/08/the-plan-for-react-18)

## [Introducing Zero-Bundle-Size React Server Components](/blog/2020/12/21/data-fetching-with-react-server-components)

[December 21, 2020](/blog/2020/12/21/data-fetching-with-react-server-components)

[2020 has been a long year. As it comes to an end we wanted to share a special Holiday Update on our research into zero-bundle-size React Server Components. To introduce React Server Components, we have prepared a talk and a demo. If you want, you can check them out during the holidays, or later when work picks back up in the new year…](/blog/2020/12/21/data-fetching-with-react-server-components)

[Read more](/blog/2020/12/21/data-fetching-with-react-server-components)

***

### All release notes[](#all-release-notes "Link for All release notes ")

Not every React release deserves its own blog post, but you can find a detailed changelog for every release in the [`CHANGELOG.md`](https://github.com/facebook/react/blob/main/CHANGELOG.md) file in the React repository, as well as on the [Releases](https://github.com/facebook/react/releases) page.

***

### Older posts[](#older-posts "Link for Older posts ")

See the [older posts.](https://reactjs.org/blog/all.html)

***

----
url: https://react.dev/reference/react/useSyncExternalStore
----

[API Reference](/reference/react)

[Hooks](/reference/react/hooks)

# useSyncExternalStore[](#undefined "Link for this heading")

`useSyncExternalStore` is a React Hook that lets you subscribe to an external store.

```
const snapshot = useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot?)
```

***

## Reference[](#reference "Link for Reference ")

### `useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot?)`[](#usesyncexternalstore "Link for this heading")

Call `useSyncExternalStore` at the top level of your component to read a value from an external data store.

```
import { useSyncExternalStore } from 'react';

import { todosStore } from './todoStore.js';



function TodosApp() {

  const todos = useSyncExternalStore(todosStore.subscribe, todosStore.getSnapshot);

  // ...

}
```

  ```
  const LazyProductDetailPage = lazy(() => import('./ProductDetailPage.js'));



  function ShoppingApp() {

    const selectedProductId = useSyncExternalStore(...);



    // ❌ Calling `use` with a Promise dependent on `selectedProductId`

    const data = use(fetchItem(selectedProductId))



    // ❌ Conditionally rendering a lazy component based on `selectedProductId`

    return selectedProductId != null ? <LazyProductDetailPage /> : <FeaturedProducts />;

  }
  ```

***

## Usage[](#usage "Link for Usage ")

### Subscribing to an external store[](#subscribing-to-an-external-store "Link for Subscribing to an external store ")

Most of your React components will only read data from their [props,](/learn/passing-props-to-a-component) [state,](/reference/react/useState) and [context.](/reference/react/useContext) However, sometimes a component needs to read some data from some store outside of React that changes over time. This includes:

* Third-party state management libraries that hold state outside of React.
* Browser APIs that expose a mutable value and events to subscribe to its changes.

Call `useSyncExternalStore` at the top level of your component to read a value from an external data store.

```
import { useSyncExternalStore } from 'react';

import { todosStore } from './todoStore.js';



function TodosApp() {

  const todos = useSyncExternalStore(todosStore.subscribe, todosStore.getSnapshot);

  // ...

}
```

It returns the snapshot of the data in the store. You need to pass two functions as arguments:

1. The `subscribe` function should subscribe to the store and return a function that unsubscribes.
2. The `getSnapshot` function should read a snapshot of the data from the store.

React will use these functions to keep your component subscribed to the store and re-render it on changes.

For example, in the sandbox below, `todosStore` is implemented as an external store that stores data outside of React. The `TodosApp` component connects to that external store with the `useSyncExternalStore` Hook.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useSyncExternalStore } from 'react';
import { todosStore } from './todoStore.js';

export default function TodosApp() {
  const todos = useSyncExternalStore(todosStore.subscribe, todosStore.getSnapshot);
  return (
    <>
      <button onClick={() => todosStore.addTodo()}>Add todo</button>
      <hr />
      <ul>
        {todos.map(todo => (
          <li key={todo.id}>{todo.text}</li>
        ))}
      </ul>
    </>
  );
}
```

### Note

When possible, we recommend using built-in React state with [`useState`](/reference/react/useState) and [`useReducer`](/reference/react/useReducer) instead. The `useSyncExternalStore` API is mostly useful if you need to integrate with existing non-React code.

***

### Subscribing to a browser API[](#subscribing-to-a-browser-api "Link for Subscribing to a browser API ")

Another reason to add `useSyncExternalStore` is when you want to subscribe to some value exposed by the browser that changes over time. For example, suppose that you want your component to display whether the network connection is active. The browser exposes this information via a property called [`navigator.onLine`.](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/onLine)

This value can change without React’s knowledge, so you should read it with `useSyncExternalStore`.

```
import { useSyncExternalStore } from 'react';



function ChatIndicator() {

  const isOnline = useSyncExternalStore(subscribe, getSnapshot);

  // ...

}
```

To implement the `getSnapshot` function, read the current value from the browser API:

```
function getSnapshot() {

  return navigator.onLine;

}
```

Next, you need to implement the `subscribe` function. For example, when `navigator.onLine` changes, the browser fires the [`online`](https://developer.mozilla.org/en-US/docs/Web/API/Window/online_event) and [`offline`](https://developer.mozilla.org/en-US/docs/Web/API/Window/offline_event) events on the `window` object. You need to subscribe the `callback` argument to the corresponding events, and then return a function that cleans up the subscriptions:

```
function subscribe(callback) {

  window.addEventListener('online', callback);

  window.addEventListener('offline', callback);

  return () => {

    window.removeEventListener('online', callback);

    window.removeEventListener('offline', callback);

  };

}
```

Now React knows how to read the value from the external `navigator.onLine` API and how to subscribe to its changes. Disconnect your device from the network and notice that the component re-renders in response:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useSyncExternalStore } from 'react';

export default function ChatIndicator() {
  const isOnline = useSyncExternalStore(subscribe, getSnapshot);
  return <h1>{isOnline ? '✅ Online' : '❌ Disconnected'}</h1>;
}

function getSnapshot() {
  return navigator.onLine;
}

function subscribe(callback) {
  window.addEventListener('online', callback);
  window.addEventListener('offline', callback);
  return () => {
    window.removeEventListener('online', callback);
    window.removeEventListener('offline', callback);
  };
}
```

***

### Extracting the logic to a custom Hook[](#extracting-the-logic-to-a-custom-hook "Link for Extracting the logic to a custom Hook ")

Usually you won’t write `useSyncExternalStore` directly in your components. Instead, you’ll typically call it from your own custom Hook. This lets you use the same external store from different components.

For example, this custom `useOnlineStatus` Hook tracks whether the network is online:

```
import { useSyncExternalStore } from 'react';



export function useOnlineStatus() {

  const isOnline = useSyncExternalStore(subscribe, getSnapshot);

  return isOnline;

}



function getSnapshot() {

  // ...

}



function subscribe(callback) {

  // ...

}
```

Now different components can call `useOnlineStatus` without repeating the underlying implementation:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useOnlineStatus } from './useOnlineStatus.js';

function StatusBar() {
  const isOnline = useOnlineStatus();
  return <h1>{isOnline ? '✅ Online' : '❌ Disconnected'}</h1>;
}

function SaveButton() {
  const isOnline = useOnlineStatus();

  function handleSaveClick() {
    console.log('✅ Progress saved');
  }

  return (
    <button disabled={!isOnline} onClick={handleSaveClick}>
      {isOnline ? 'Save progress' : 'Reconnecting...'}
    </button>
  );
}

export default function App() {
  return (
    <>
      <SaveButton />
      <StatusBar />
    </>
  );
}
```

***

### Adding support for server rendering[](#adding-support-for-server-rendering "Link for Adding support for server rendering ")

If your React app uses [server rendering,](/reference/react-dom/server) your React components will also run outside the browser environment to generate the initial HTML. This creates a few challenges when connecting to an external store:

* If you’re connecting to a browser-only API, it won’t work because it does not exist on the server.
* If you’re connecting to a third-party data store, you’ll need its data to match between the server and client.

To solve these issues, pass a `getServerSnapshot` function as the third argument to `useSyncExternalStore`:

```
import { useSyncExternalStore } from 'react';



export function useOnlineStatus() {

  const isOnline = useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);

  return isOnline;

}



function getSnapshot() {

  return navigator.onLine;

}



function getServerSnapshot() {

  return true; // Always show "Online" for server-generated HTML

}



function subscribe(callback) {

  // ...

}
```

The `getServerSnapshot` function is similar to `getSnapshot`, but it runs only in two situations:

* It runs on the server when generating the HTML.
* It runs on the client during [hydration](/reference/react-dom/client/hydrateRoot), i.e. when React takes the server HTML and makes it interactive.

This lets you provide the initial snapshot value which will be used before the app becomes interactive. If there is no meaningful initial value for the server rendering, omit this argument to [force rendering on the client.](/reference/react/Suspense#providing-a-fallback-for-server-errors-and-client-only-content)

### Note

Make sure that `getServerSnapshot` returns the same exact data on the initial client render as it returned on the server. For example, if `getServerSnapshot` returned some prepopulated store content on the server, you need to transfer this content to the client. One way to do this is to emit a `<script>` tag during server rendering that sets a global like `window.MY_STORE_DATA`, and read from that global on the client in `getServerSnapshot`. Your external store should provide instructions on how to do that.

***

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### I’m getting an error: “The result of `getSnapshot` should be cached”[](#im-getting-an-error-the-result-of-getsnapshot-should-be-cached "Link for this heading")

This error means your `getSnapshot` function returns a new object every time it’s called, for example:

```
function getSnapshot() {

  // 🔴 Do not return always different objects from getSnapshot

  return {

    todos: myStore.todos

  };

}
```

React will re-render the component if `getSnapshot` return value is different from the last time. This is why, if you always return a different value, you will enter an infinite loop and get this error.

Your `getSnapshot` object should only return a different object if something has actually changed. If your store contains immutable data, you can return that data directly:

```
function getSnapshot() {

  // ✅ You can return immutable data

  return myStore.todos;

}
```

If your store data is mutable, your `getSnapshot` function should return an immutable snapshot of it. This means it *does* need to create new objects, but it shouldn’t do this for every single call. Instead, it should store the last calculated snapshot, and return the same snapshot as the last time if the data in the store has not changed. How you determine whether mutable data has changed depends on your mutable store.

***

### My `subscribe` function gets called after every re-render[](#my-subscribe-function-gets-called-after-every-re-render "Link for this heading")

This `subscribe` function is defined *inside* a component so it is different on every re-render:

```
function ChatIndicator() {

  // 🚩 Always a different function, so React will resubscribe on every re-render

  function subscribe() {

    // ...

  }



  const isOnline = useSyncExternalStore(subscribe, getSnapshot);



  // ...

}
```

React will resubscribe to your store if you pass a different `subscribe` function between re-renders. If this causes performance issues and you’d like to avoid resubscribing, move the `subscribe` function outside:

```
// ✅ Always the same function, so React won't need to resubscribe

function subscribe() {

  // ...

}



function ChatIndicator() {

  const isOnline = useSyncExternalStore(subscribe, getSnapshot);

  // ...

}
```

Alternatively, wrap `subscribe` into [`useCallback`](/reference/react/useCallback) to only resubscribe when some argument changes:

```
function ChatIndicator({ userId }) {

  // ✅ Same function as long as userId doesn't change

  const subscribe = useCallback(() => {

    // ...

  }, [userId]);



  const isOnline = useSyncExternalStore(subscribe, getSnapshot);



  // ...

}
```

[PrevioususeState](/reference/react/useState)

[NextuseTransition](/reference/react/useTransition)

***

----
url: https://18.react.dev/reference/react-dom/components/option
----

[API Reference](/reference/react)

[Components](/reference/react-dom/components)

# \<option>[](#undefined "Link for this heading")

The [built-in browser `<option>` component](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/option) lets you render an option inside a [`<select>`](/reference/react-dom/components/select) box.

```
<select>

  <option value="someOption">Some option</option>

  <option value="otherOption">Other option</option>

</select>
```

* [Reference](#reference)
  * [`<option>`](#option)
* [Usage](#usage)
  * [Displaying a select box with options](#displaying-a-select-box-with-options)

***

## Reference[](#reference "Link for Reference ")

### `<option>`[](#option "Link for this heading")

The [built-in browser `<option>` component](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/option) lets you render an option inside a [`<select>`](/reference/react-dom/components/select) box.

```
<select>

  <option value="someOption">Some option</option>

  <option value="otherOption">Other option</option>

</select>
```

[See more examples below.](#usage)

#### Props[](#props "Link for Props ")

`<option>` supports all [common element props.](/reference/react-dom/components/common#props)

Additionally, `<option>` supports these props:

* [`disabled`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/option#disabled): A boolean. If `true`, the option will not be selectable and will appear dimmed.
* [`label`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/option#label): A string. Specifies the meaning of the option. If not specified, the text inside the option is used.
* [`value`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/option#value): The value to be used [when submitting the parent `<select>` in a form](/reference/react-dom/components/select#reading-the-select-box-value-when-submitting-a-form) if this option is selected.

#### Caveats[](#caveats "Link for Caveats ")

* React does not support the `selected` attribute on `<option>`. Instead, pass this option’s `value` to the parent [`<select defaultValue>`](/reference/react-dom/components/select#providing-an-initially-selected-option) for an uncontrolled select box, or [`<select value>`](/reference/react-dom/components/select#controlling-a-select-box-with-a-state-variable) for a controlled select.

***

## Usage[](#usage "Link for Usage ")

### Displaying a select box with options[](#displaying-a-select-box-with-options "Link for Displaying a select box with options ")

Render a `<select>` with a list of `<option>` components inside to display a select box. Give each `<option>` a `value` representing the data to be submitted with the form.

[Read more about displaying a `<select>` with a list of `<option>` components.](/reference/react-dom/components/select)

```
export default function FruitPicker() {
  return (
    <label>
      Pick a fruit:
      <select name="selectedFruit">
        <option value="apple">Apple</option>
        <option value="banana">Banana</option>
        <option value="orange">Orange</option>
      </select>
    </label>
  );
}
```

[Previous\<input>](/reference/react-dom/components/input)

[Next\<progress>](/reference/react-dom/components/progress)

***

----
url: https://legacy.reactjs.org/docs/concurrent-mode-patterns.html
----

> Caution:
>
> This page is **somewhat outdated** and only exists for historical purposes.
>
> React 18 was released with support for concurrency. However, **there is no “mode” anymore,** and the new behavior is fully opt-in and only enabled [when you use the new features](https://reactjs.org/blog/2022/03/29/react-v18.html#gradually-adopting-concurrent-features).
>
> **For up-to-date high-level information, refer to:**
>
> * [React 18 Announcement](https://reactjs.org/blog/2022/03/29/react-v18.html)
> * [Upgrading to React 18](https://reactjs.org/blog/2022/03/08/react-18-upgrade-guide.html)
> * [React Conf 2021 Videos](https://reactjs.org/blog/2021/12/17/react-conf-2021-recap.html)
>
> **For details about concurrent APIs in React 18, refer to:**
>
> * [`React.Suspense`](https://reactjs.org/docs/react-api.html#reactsuspense) reference
> * [`React.startTransition`](https://reactjs.org/docs/react-api.html#starttransition) reference
> * [`React.useTransition`](https://reactjs.org/docs/hooks-reference.html#usetransition) reference
> * [`React.useDeferredValue`](https://reactjs.org/docs/hooks-reference.html#usedeferredvalue) reference
>
> The rest of this page includes content that’s stale, broken, or incorrect.

Usually, when we update the state, we expect to see changes on the screen immediately. This makes sense because we want to keep our app responsive to user input. However, there are cases where we might prefer to **defer an update from appearing on the screen**.

For example, if we switch from one page to another, and none of the code or data for the next screen has loaded yet, it might be frustrating to immediately see a blank page with a loading indicator. We might prefer to stay longer on the previous screen. Implementing this pattern has historically been difficult in React. Concurrent Mode offers a new set of tools to do that.

* [Transitions](#transitions)

  * [Wrapping setState in a Transition](#wrapping-setstate-in-a-transition)
  * [Adding a Pending Indicator](#adding-a-pending-indicator)
  * [Reviewing the Changes](#reviewing-the-changes)
  * [Where Does the Update Happen?](#where-does-the-update-happen)
  * [Transitions Are Everywhere](#transitions-are-everywhere)
  * [Baking Transitions Into the Design System](#baking-transitions-into-the-design-system)

* [The Three Steps](#the-three-steps)

  * [Default: Receded → Skeleton → Complete](#default-receded-skeleton-complete)
  * [Preferred: Pending → Skeleton → Complete](#preferred-pending-skeleton-complete)
  * [Wrap Lazy Features in `<Suspense>`](#wrap-lazy-features-in-suspense)
  * [Suspense Reveal “Train”](#suspense-reveal-train)
  * [Delaying a Pending Indicator](#delaying-a-pending-indicator)
  * [Recap](#recap)

* [Other Patterns](#other-patterns)

  * [Splitting High and Low Priority State](#splitting-high-and-low-priority-state)
  * [Deferring a Value](#deferring-a-value)
  * [SuspenseList](#suspenselist)

* [Next Steps](#next-steps)

## [](#transitions)Transitions

Let’s revisit [this demo](https://codesandbox.io/s/sparkling-field-41z4r3) from the previous page about [Suspense for Data Fetching](/docs/concurrent-mode-suspense.html).

When we click the “Next” button to switch the active profile, the existing page data immediately disappears, and we see the loading indicator for the whole page again. We can call this an “undesirable” loading state. **It would be nice if we could “skip” it and wait for some content to load before transitioning to the new screen.**

React offers a new built-in `useTransition()` Hook to help with this.

We can use it in three steps.

First, we’ll make sure that we’re actually using Concurrent Mode. We’ll talk more about [adopting Concurrent Mode](/docs/concurrent-mode-adoption.html) later, but for now it’s sufficient to know that we need to use `ReactDOM.createRoot()` rather than `ReactDOM.render()` for this feature to work:

```
const rootElement = document.getElementById("root");
// Opt into Concurrent Mode
ReactDOM.createRoot(rootElement).render(<App />);
```

Next, we’ll add an import for the `useTransition` Hook from React:

```
import React, { useState, useTransition, Suspense } from "react";
```

Finally, we’ll use it inside the `App` component:

```
function App() {
  const [resource, setResource] = useState(initialResource);
  const [isPending, startTransition] = useTransition();  // ...
```

**By itself, this code doesn’t do anything yet.** We will need to use this Hook’s return values to set up our state transition. There are two values returned from `useTransition`:

* `isPending` is a boolean. It’s React telling us whether that transition is ongoing at the moment.
* `startTransition` is a function. We’ll use it to tell React *which* state update we want to defer.

We will use them right below.

> Caution:
>
> In earlier experimental releases and demos, the order of the return values was reversed.

### [](#wrapping-setstate-in-a-transition)Wrapping setState in a Transition

Our “Next” button click handler sets the state that switches the current profile in the state:

```
<button
  onClick={() => {
    const nextUserId = getNextId(resource.userId);
    setResource(fetchProfileData(nextUserId));  }}
>
```

We’ll wrap that state update into `startTransition`. That’s how we tell React **we don’t mind React delaying that state update** if it leads to an undesirable loading state:

```
<button
  onClick={() => {
    startTransition(() => {      const nextUserId = getNextId(resource.userId);
      setResource(fetchProfileData(nextUserId));
    });  }}
>
```

**[Try it on CodeSandbox](https://codesandbox.io/s/elastic-vaughan-ykzsi0?file=/src/index.js)**

Press “Next” a few times. Notice it already feels very different. **Instead of immediately seeing an empty screen on click, we now keep seeing the previous page for a while.** When the data has loaded, React transitions us to the new screen.

React only “waits” for `<Suspense>` boundaries that are already displayed. If you mount a new `<Suspense>` boundary as a part of transition, React will display its fallback immediately.

> Caution:
>
> In earlier experimental releases and demos, there was a configurable timeout. It was removed.

### [](#adding-a-pending-indicator)Adding a Pending Indicator

There’s still something that feels broken about [our last example](https://codesandbox.io/s/vigilant-feynman-kpjy8w). Sure, it’s nice not to see a “bad” loading state. **But having no indication of progress at all feels even worse!** When we click “Next”, nothing happens and it feels like the app is broken.

Our `useTransition()` call returns two values: `startTransition` and `isPending`.

```
  const [isPending, startTransition] = useTransition();
```

We’ve already used `startTransition` to wrap the state update. Now we’re going to use `isPending` too. React gives this boolean to us so we can tell whether **we’re currently waiting for this transition to finish**. We’ll use it to indicate that something is happening:

```
return (
  <>
    <button
      disabled={isPending}      onClick={() => {
        startTransition(() => {
          const nextUserId = getNextId(resource.userId);
          setResource(fetchProfileData(nextUserId));
        });
      }}
    >
      Next
    </button>
    {isPending ? " Loading..." : null}    <ProfilePage resource={resource} />
  </>
);
```

**[Try it on CodeSandbox](https://codesandbox.io/s/serverless-fast-isjkvt)**

Now, this feels a lot better! When we click Next, it gets disabled because clicking it multiple times doesn’t make sense. And the new “Loading…” tells the user that the app didn’t freeze.

### [](#reviewing-the-changes)Reviewing the Changes

Let’s take another look at all the changes we’ve made since the [original example](https://codesandbox.io/s/nice-shadow-zvosx0):

```
function App() {
  const [resource, setResource] = useState(initialResource);
  const [isPending, startTransition] = useTransition();  return (
    <>
      <button
        disabled={isPending}
        onClick={() => {
          startTransition(() => {            const nextUserId = getNextId(resource.userId);            setResource(fetchProfileData(nextUserId));          });        }}
      >
        Next
      </button>
      {isPending ? " Loading..." : null}      <ProfilePage resource={resource} />
    </>
  );
}
```

**[Try it on CodeSandbox](https://codesandbox.io/s/serverless-fast-isjkvt)**

It took us only seven lines of code to add this transition:

* We’ve imported the `useTransition` Hook and used it in the component that updates the state.
* We’ve wrapped our state update into `startTransition` to tell React it’s okay to delay it.
* We’re using `isPending` to communicate the state transition progress to the user and to disable the button.

As a result, clicking “Next” doesn’t perform an immediate state transition to an “undesirable” loading state, but instead stays on the previous screen and communicates progress there.

### [](#where-does-the-update-happen)Where Does the Update Happen?

This wasn’t very difficult to implement. However, if you start thinking about how this could possibly work, it might become a little mindbending. If we set the state, how come we don’t see the result right away? *Where* is the next `<ProfilePage>` rendering?

Clearly, both “versions” of `<ProfilePage>` exist at the same time. We know the old one exists because we see it on the screen and even display a progress indicator on it. And we know the new version also exists *somewhere*, because it’s the one that we’re waiting for!

**But how can two versions of the same component exist at the same time?**

This gets at the root of what Concurrent Mode is. We’ve [previously said](/docs/concurrent-mode-intro.html#intentional-loading-sequences) it’s a bit like React working on state update on a “branch”. Another way we can conceptualize is that wrapping a state update in `startTransition` begins rendering it *“in a different universe”*, much like in science fiction movies. We don’t “see” that universe directly — but we can get a signal from it that tells us something is happening (`isPending`). When the update is ready, our “universes” merge back together, and we see the result on the screen!

Play a bit more with the [demo](https://codesandbox.io/s/frosty-haslett-ds0h9h), and try to imagine it happening.

Of course, two versions of the tree rendering *at the same time* is an illusion, just like the idea that all programs run on your computer at the same time is an illusion. An operating system switches between different applications very fast. Similarly, React can switch between the version of the tree you see on the screen and the version that it’s “preparing” to show next.

An API like `useTransition` lets you focus on the desired user experience, and not think about the mechanics of how it’s implemented. Still, it can be a helpful metaphor to imagine that updates wrapped in `startTransition` happen “on a branch” or “in a different world”.

### [](#transitions-are-everywhere)Transitions Are Everywhere

As we learned from the [Suspense walkthrough](/docs/concurrent-mode-suspense.html), any component can “suspend” any time if some data it needs is not ready yet. We can strategically place `<Suspense>` boundaries in different parts of the tree to handle this, but it won’t always be enough.

Let’s get back to our [first Suspense demo](https://codesandbox.io/s/frosty-hermann-bztrp) where there was just one profile. Currently, it fetches the data only once. We’ll add a “Refresh” button to check for server updates.

Our first attempt might look like this:

```
const initialResource = fetchUserAndPosts();

function ProfilePage() {
  const [resource, setResource] = useState(initialResource);

  function handleRefreshClick() {    setResource(fetchUserAndPosts());  }
  return (
    <Suspense fallback={<h1>Loading profile...</h1>}>
      <ProfileDetails resource={resource} />
      <button onClick={handleRefreshClick}>        Refresh      </button>      <Suspense fallback={<h1>Loading posts...</h1>}>
        <ProfileTimeline resource={resource} />
      </Suspense>
    </Suspense>
  );
}
```

**[Try it on CodeSandbox](https://codesandbox.io/s/trusting-brown-6hj0m0)**

In this example, we start data fetching at the load *and* every time you press “Refresh”. We put the result of calling `fetchUserAndPosts()` into state so that components below can start reading the new data from the request we just kicked off.

We can see in [this example](https://codesandbox.io/s/trusting-brown-6hj0m0) that pressing “Refresh” works. The `<ProfileDetails>` and `<ProfileTimeline>` components receive a new `resource` prop that represents the fresh data, they “suspend” because we don’t have a response yet, and we see the fallbacks. When the response loads, we can see the updated posts (our fake API adds them every 3 seconds).

However, the experience feels really jarring. We were browsing a page, but it got replaced by a loading state right as we were interacting with it. It’s disorienting. **Just like before, to avoid showing an undesirable loading state, we can wrap the state update in a transition:**

```
function ProfilePage() {
  const [isPending, startTransition] = useTransition();  const [resource, setResource] = useState(initialResource);

  function handleRefreshClick() {
    startTransition(() => {      setResource(fetchProfileData());    });  }

  return (
    <Suspense fallback={<h1>Loading profile...</h1>}>
      <ProfileDetails resource={resource} />
      <button
        onClick={handleRefreshClick}
        disabled={isPending}
      >
        {isPending ? "Refreshing..." : "Refresh"}      </button>
      <Suspense fallback={<h1>Loading posts...</h1>}>
        <ProfileTimeline resource={resource} />
      </Suspense>
    </Suspense>
  );
}
```

**[Try it on CodeSandbox](https://codesandbox.io/s/inspiring-dawn-vho1yg?file=/src/index.js)**

This feels a lot better! Clicking “Refresh” doesn’t pull us away from the page we’re browsing anymore. We see something is loading “inline”, and when the data is ready, it’s displayed.

## [](#the-three-steps)The Three Steps

By now we have discussed all of the different visual states that an update may go through. In this section, we will give them names and talk about the progression between them.

[](/static/46bf8ed031b93548272a405e1fb0f1ed/a878e/cm-steps-simple.png)

> Caution:
>
> The “timeout” case that switches from Pending to Receded has been removed.

At the very end, we have the **Complete** state. That’s where we want to eventually get to. It represents the moment when the next screen is fully rendered and isn’t loading more data.

But before our screen can be Complete, we might need to load some data or code. When we’re on the next screen, but some parts of it are still loading, we call that a **Skeleton** state.

Finally, there are two primary ways that lead us to the Skeleton state. We will illustrate the difference between them with a concrete example.

### [](#default-receded-skeleton-complete)Default: Receded → Skeleton → Complete

Open [this example](https://codesandbox.io/s/xenodochial-breeze-khk2fh) and click “Open Profile”. You will see several visual states one by one:

* **Receded**: For a second, you will see the `<h1>Loading the app...</h1>` fallback.
* **Skeleton:** You will see the `<ProfilePage>` component with `<h2>Loading posts...</h2>` inside.
* **Complete:** You will see the `<ProfilePage>` component with no fallbacks inside. Everything was fetched.

How do we separate the Receded and the Skeleton states? The difference between them is that the **Receded** state feels like “taking a step back” to the user, while the **Skeleton** state feels like “taking a step forward” in our progress to show more content.

In this example, we started our journey on the `<HomePage>`:

```
<Suspense fallback={...}>
  {/* previous screen */}
  <HomePage />
</Suspense>
```

After the click, React started rendering the next screen:

```
<Suspense fallback={...}>
  {/* next screen */}
  <ProfilePage>
    <ProfileDetails />
    <Suspense fallback={...}>
      <ProfileTimeline />
    </Suspense>
  </ProfilePage>
</Suspense>
```

Both `<ProfileDetails>` and `<ProfileTimeline>` need data to render, so they suspend:

```
<Suspense fallback={...}>
  {/* next screen */}
  <ProfilePage>
    <ProfileDetails /> {/* suspends! */}    <Suspense fallback={<h2>Loading posts...</h2>}>
      <ProfileTimeline /> {/* suspends! */}    </Suspense>
  </ProfilePage>
</Suspense>
```

When a component suspends, React needs to show the closest fallback. But the closest fallback to `<ProfileDetails>` is at the top level:

```
<Suspense fallback={
  // We see this fallback now because of <ProfileDetails>  <h1>Loading the app...</h1>}>
  {/* next screen */}
  <ProfilePage>
    <ProfileDetails /> {/* suspends! */}    <Suspense fallback={...}>
      <ProfileTimeline />
    </Suspense>
  </ProfilePage>
</Suspense>
```

This is why when we click the button, it feels like we’ve “taken a step back”. The `<Suspense>` boundary which was previously showing useful content (`<HomePage />`) had to “recede” to showing the fallback (`<h1>Loading the app...</h1>`). We call that a **Receded** state.

As we load more data, React will retry rendering, and `<ProfileDetails>` can render successfully. Finally, we’re in the **Skeleton** state. We see the new page with missing parts:

```
<Suspense fallback={...}>
  {/* next screen */}
  <ProfilePage>
    <ProfileDetails />
    <Suspense fallback={
      // We see this fallback now because of <ProfileTimeline>      <h2>Loading posts...</h2>    }>
      <ProfileTimeline /> {/* suspends! */}    </Suspense>
  </ProfilePage>
</Suspense>
```

Eventually, they load too, and we get to the **Complete** state.

This scenario (Receded → Skeleton → Complete) is the default one. However, the Receded state is not very pleasant because it “hides” existing information. This is why React lets us opt into a different sequence (**Pending** → Skeleton → Complete) with `useTransition`.

### [](#preferred-pending-skeleton-complete)Preferred: Pending → Skeleton → Complete

When we `useTransition`, React will let us “stay” on the previous screen — and show a progress indicator there. We call that a **Pending** state. It feels much better than the Receded state because none of our existing content disappears, and the page stays interactive.

You can compare these two examples to feel the difference:

* Default: [Receded → Skeleton → Complete](https://codesandbox.io/s/xenodochial-breeze-khk2fh)
* **Preferred: [Pending → Skeleton → Complete](https://codesandbox.io/s/serene-pascal-w3no1l)**

The only difference between these two examples is that the first uses regular `<button>`s, but the second one uses our custom `<Button>` component with `useTransition`.

### [](#wrap-lazy-features-in-suspense)Wrap Lazy Features in `<Suspense>`

Open [this example](https://codesandbox.io/s/mystifying-tamas-1f2xjg). When you press a button, you’ll see the Pending state for a second before moving on. This transition feels nice and fluid.

We will now add a brand new feature to the profile page — a list of fun facts about a person:

```
function ProfilePage({ resource }) {
  return (
    <>
      <ProfileDetails resource={resource} />
      <Suspense fallback={<h2>Loading posts...</h2>}>
        <ProfileTimeline resource={resource} />
      </Suspense>
      <ProfileTrivia resource={resource} />    </>
  );
}

function ProfileTrivia({ resource }) {  const trivia = resource.trivia.read();  return (    <>      <h2>Fun Facts</h2>      <ul>        {trivia.map(fact => (          <li key={fact.id}>{fact.text}</li>        ))}      </ul>    </>  );}
```

**[Try it on CodeSandbox](https://codesandbox.io/s/blue-shape-lqwc82)**

If you press “Open Profile” now, you can tell something is wrong. It takes a whole seven seconds to make the transition now! This is because our trivia API is too slow. Let’s say we can’t make the API faster. How can we improve the user experience with this constraint?

Let’s “disconnect” the slow component from the transition by wrapping it into `<Suspense>`:

```
function ProfilePage({ resource }) {
  return (
    <>
      <ProfileDetails resource={resource} />
      <Suspense fallback={<h2>Loading posts...</h2>}>
        <ProfileTimeline resource={resource} />
      </Suspense>
      <Suspense fallback={<h2>Loading fun facts...</h2>}>        <ProfileTrivia resource={resource} />
      </Suspense>    </>
  );
}
```

**[Try it on CodeSandbox](https://codesandbox.io/s/nice-shaw-k6t10j)**

**If some feature isn’t a vital part of the next screen, wrap it in `<Suspense>` and let it load lazily.** This ensures we can show the rest of the content as soon as possible. Conversely, if a screen is *not worth showing* without some component, such as `<ProfileDetails>` in our example, do *not* wrap it in `<Suspense>`. Then the transitions will “wait” for it to be ready.

### [](#suspense-reveal-train)Suspense Reveal “Train”

When we’re already on the next screen, sometimes the data needed to “unlock” different `<Suspense>` boundaries arrives in quick succession. For example, two different responses might arrive after 1000ms and 1050ms, respectively. If you’ve already waited for a second, waiting another 50ms is not going to be perceptible. This is why React reveals `<Suspense>` boundaries on a schedule, like a “train” that arrives periodically. This trades a small delay for reducing the layout thrashing and the number of visual changes presented to the user.

You can see a demo of this [here](https://codesandbox.io/s/great-sea-3d788s). The “posts” and “fun facts” responses come within 100ms of each other. But React coalesces them and “reveals” their Suspense boundaries together.

### [](#delaying-a-pending-indicator)Delaying a Pending Indicator

Our `Button` component will immediately show the Pending state indicator on click:

```
function Button({ children, onClick }) {
  const [startTransition, isPending] = useTransition();
  // ...

  return (
    <>
      <button onClick={handleClick} disabled={isPending}>
        {children}
      </button>
      {isPending ? spinner : null}
    </>
  );}
```

**[Try it on CodeSandbox](https://codesandbox.io/s/happy-cloud-2m8lxg)**

This signals to the user that some work is happening. However, if the transition is relatively short (less than 200ms), it might be too distracting and make the transition itself feel *slower*.

The recommended solution is to use CSS to *reveal the spinner gradually and delay it*:

```
return (
  <>
    <button onClick={handleClick}>{children}</button>
    <span
      style={{
        transition: isPending
          ? "opacity 0.3s 0.2s linear"
          : "opacity 0s 0s linear",
        opacity: isPending ? 1 : 0
      }}
    >
      {/* ... */}
    </span>
  </>
);
```

**[Try it on CodeSandbox](https://codesandbox.io/s/great-feistel-xb5ic7)**

With this change, even though we’re in the Pending state, we don’t display any indication to the user until 200ms has passed, and even after that, it takes a while to become fully visible. In cases where you expect the transition to be short, you might want to not use spinners at all, and instead display the button itself in an “active” state similar to being pressed.

### [](#recap)Recap

The most important things we learned so far are:

* By default, our loading sequence is Receded → Skeleton → Complete.
* The Receded state doesn’t feel very nice because it hides existing content.
* With `useTransition`, we can opt into showing a Pending state first instead. This will keep us on the previous screen while the next screen is being prepared.
* If we don’t want some component to delay the transition, we can wrap it in its own `<Suspense>` boundary.

## [](#other-patterns)Other Patterns

Transitions are probably the most common Concurrent Mode pattern you’ll encounter, but there are a few more patterns you might find useful.

### [](#splitting-high-and-low-priority-state)Splitting High and Low Priority State

When you design React components, it is usually best to find the “minimal representation” of state. For example, instead of keeping `firstName`, `lastName`, and `fullName` in state, it’s usually better keep only `firstName` and `lastName`, and then calculate `fullName` during rendering. This lets us avoid mistakes where we update one state but forget the other state.

However, in Concurrent Mode there are cases where you might *want* to “duplicate” some data in different state variables. Consider this tiny translation app:

```
const initialQuery = "Hello, world";
const initialResource = fetchTranslation(initialQuery);

function App() {
  const [query, setQuery] = useState(initialQuery);
  const [resource, setResource] = useState(initialResource);

  function handleChange(e) {
    const value = e.target.value;
    setQuery(value);
    setResource(fetchTranslation(value));
  }

  return (
    <>
      <input
        value={query}
        onChange={handleChange}
      />
      <Suspense fallback={<p>Loading...</p>}>
        <Translation resource={resource} />
      </Suspense>
    </>
  );
}

function Translation({ resource }) {
  return (
    <p>
      <b>{resource.read()}</b>
    </p>
  );
}
```

**[Try it on CodeSandbox](https://codesandbox.io/s/nervous-sunset-zuxrid)**

Notice how when you type into the input, the `<Translation>` component suspends, and we see the `<p>Loading...</p>` fallback until we get fresh results. This is not ideal. It would be better if we could see the *previous* translation for a bit while we’re fetching the next one.

As we mentioned earlier, if some state update causes a component to suspend, that state update should be wrapped in a transition. Let’s add `useTransition` to our component:

```
function App() {
  const [query, setQuery] = useState(initialQuery);
  const [resource, setResource] = useState(initialResource);
  const [startTransition, isPending] = useTransition();
  function handleChange(e) {
    const value = e.target.value;
    startTransition(() => {      setQuery(value);
      setResource(fetchTranslation(value));
    });  }
  // ...
}
```

**[Try it on CodeSandbox](https://codesandbox.io/s/relaxed-sanne-23nrn7)**

Try typing into the input now. Something’s wrong! The input is updating very slowly.

We’ve fixed the first problem (suspending outside of a transition). But now because of the transition, our state doesn’t update immediately, and it can’t “drive” a controlled input!

The answer to this problem **is to split the state in two parts:** a “high priority” part that updates immediately, and a “low priority” part that may wait for a transition.

In our example, we already have two state variables. The input text is in `query`, and we read the translation from `resource`. We want changes to the `query` state to happen immediately, but changes to the `resource` (i.e. fetching a new translation) should trigger a transition.

So the correct fix is to put `setQuery` (which doesn’t suspend) *outside* the transition, but `setResource` (which will suspend) *inside* of it.

```
function handleChange(e) {
  const value = e.target.value;
  
  // Outside the transition (urgent)  setQuery(value);
  startTransition(() => {
    // Inside the transition (may be delayed)
    setResource(fetchTranslation(value));
  });
}
```

**[Try it on CodeSandbox](https://codesandbox.io/s/muddy-sun-lg10ks)**

With this change, it works as expected. We can type into the input immediately, and the translation later “catches up” to what we have typed.

### [](#deferring-a-value)Deferring a Value

By default, React always renders a consistent UI. Consider code like this:

```
<>
  <ProfileDetails user={user} />
  <ProfileTimeline user={user} />
</>
```

React guarantees that whenever we look at these components on the screen, they will reflect data from the same `user`. If a different `user` is passed down because of a state update, you would see them changing together. You can’t ever record a screen and find a frame where they would show values from different `user`s. (If you ever run into a case like this, file a bug!)

This makes sense in the vast majority of situations. Inconsistent UI is confusing and can mislead users. (For example, it would be terrible if a messenger’s Send button and the conversation picker pane “disagreed” about which thread is currently selected.)

However, sometimes it might be helpful to intentionally introduce an inconsistency. We could do it manually by “splitting” the state like above, but React also offers a built-in Hook for this:

```
import { useDeferredValue } from 'react';

const deferredValue = useDeferredValue(value);
```

To demonstrate this feature, we’ll use [the profile switcher example](https://codesandbox.io/s/serene-roman-9t9njd). Click the “Next” button and notice how it takes 1 second to do a transition.

Let’s say that fetching the user details is very fast and only takes 300 milliseconds. Currently, we’re waiting a whole second because we need both user details and posts to display a consistent profile page. But what if we want to show the details faster?

If we’re willing to sacrifice consistency, we could **pass potentially stale data to the components that delay our transition**. That’s what `useDeferredValue()` lets us do:

```
function ProfilePage({ resource }) {
  const deferredResource = useDeferredValue(resource);  return (    <Suspense fallback={<h1>Loading profile...</h1>}>      <ProfileDetails resource={resource} />
      <Suspense fallback={<h1>Loading posts...</h1>}>
        <ProfileTimeline
          resource={deferredResource}
          isStale={deferredResource !== resource}
        />      </Suspense>    </Suspense>
  );
}

function ProfileTimeline({ isStale, resource }) {
  const posts = resource.posts.read();
  return (
    <ul style={{ opacity: isStale ? 0.7 : 1 }}>
      {posts.map(post => (
        <li key={post.id}>{post.text}</li>      ))}
    </ul>
  );
}
```

**[Try it on CodeSandbox](https://codesandbox.io/s/zealous-sun-3k3uhe)**

The tradeoff we’re making here is that `<ProfileTimeline>` will be inconsistent with other components and potentially show an older item. Click “Next” a few times, and you’ll notice it. But thanks to that, we were able to cut down the transition time from 1000ms to 300ms.

Whether or not it’s an appropriate tradeoff depends on the situation. But it’s a handy tool, especially when the content doesn’t change noticeably between items, and the user might not even realize they were looking at a stale version for a second.

It’s worth noting that `useDeferredValue` is not *only* useful for data fetching. It also helps when an expensive component tree causes an interaction (e.g. typing in an input) to be sluggish. Just like we can “defer” a value that takes too long to fetch (and show its old value despite other components updating), we can do this with trees that take too long to render.

For example, consider a filterable list like this:

```
function App() {
  const [text, setText] = useState("hello");

  function handleChange(e) {
    setText(e.target.value);
  }

  return (
    <div className="App">
      <label>
        Type into the input:{" "}
        <input value={text} onChange={handleChange} />
      </label>
      ...
      <MySlowList text={text} />
    </div>
  );
}
```

**[Try it on CodeSandbox](https://codesandbox.io/s/agitated-glitter-ybnfni)**

In this example, **every item in `<MySlowList>` has an artificial slowdown — each of them blocks the thread for a few milliseconds**. We’d never do this in a real app, but this helps us simulate what can happen in a deep component tree with no single obvious place to optimize.

We can see how typing in the input causes stutter. Now let’s add `useDeferredValue`:

```
function App() {
  const [text, setText] = useState("hello");
  const deferredText = useDeferredValue(text);
  function handleChange(e) {
    setText(e.target.value);
  }

  return (
    <div className="App">
      <label>
        Type into the input:{" "}
        <input value={text} onChange={handleChange} />
      </label>
      ...
      <MySlowList text={deferredText} />    </div>
  );
}
```

**[Try it on CodeSandbox](https://codesandbox.io/s/jovial-frost-30embe)**

Now typing has a lot less stutter — although we pay for this by showing the results with a lag.

How is this different from debouncing? Our example has a fixed artificial delay (3ms for every one of 80 items), so there is always a delay, no matter how fast our computer is. However, the `useDeferredValue` value only “lags behind” if the rendering takes a while. There is no minimal lag imposed by React. With a more realistic workload, you can expect the lag to adjust to the user’s device. On fast machines, the lag would be smaller or non-existent, and on slow machines, it would be more noticeable. In both cases, the app would remain responsive. That’s the advantage of this mechanism over debouncing or throttling, which always impose a minimal delay and can’t avoid blocking the thread while rendering.

Even though there is an improvement in responsiveness, this example isn’t as compelling yet because Concurrent Mode is missing some crucial optimizations for this use case. Still, it is interesting to see that features like `useDeferredValue` (or `useTransition`) are useful regardless of whether we’re waiting for network or for computational work to finish.

### [](#suspenselist)SuspenseList

> Caution:
>
> `<SuspenseList>` is not a part of React 18 and will be included in a future release.

`<SuspenseList>` is the last pattern that’s related to orchestrating loading states.

Consider this example:

```
function ProfilePage({ resource }) {
  return (
    <>
      <ProfileDetails resource={resource} />
      <Suspense fallback={<h2>Loading posts...</h2>}>        <ProfileTimeline resource={resource} />      </Suspense>      <Suspense fallback={<h2>Loading fun facts...</h2>}>        <ProfileTrivia resource={resource} />      </Suspense>    </>
  );
}
```

**[Try it on CodeSandbox](https://codesandbox.io/s/hardcore-river-14ecuq)**

The API call duration in this example is randomized. If you keep refreshing it, you will notice that sometimes the posts arrive first, and sometimes the “fun facts” arrive first.

This presents a problem. If the response for fun facts arrives first, we’ll see the fun facts below the `<h2>Loading posts...</h2>` fallback for posts. We might start reading them, but then the *posts* response will come back, and shift all the facts down. This is jarring.

One way we could fix it is by putting them both in a single boundary:

```
<Suspense fallback={<h2>Loading posts and fun facts...</h2>}>
  <ProfileTimeline resource={resource} />
  <ProfileTrivia resource={resource} />
</Suspense>
```

**[Try it on CodeSandbox](https://codesandbox.io/s/quirky-meadow-w1c61p)**

The problem with this is that now we *always* wait for both of them to be fetched. However, if it’s the *posts* that came back first, there’s no reason to delay showing them. When fun facts load later, they won’t shift the layout because they’re already below the posts.

Other approaches to this, such as composing Promises in a special way, are increasingly difficult to pull off when the loading states are located in different components down the tree.

To solve this, we will import `SuspenseList`:

```
import { SuspenseList } from 'react';
```

`<SuspenseList>` coordinates the “reveal order” of the closest `<Suspense>` nodes below it:

```
function ProfilePage({ resource }) {
  return (
    <SuspenseList revealOrder="forwards">      <ProfileDetails resource={resource} />
      <Suspense fallback={<h2>Loading posts...</h2>}>
        <ProfileTimeline resource={resource} />
      </Suspense>
      <Suspense fallback={<h2>Loading fun facts...</h2>}>
        <ProfileTrivia resource={resource} />
      </Suspense>
    </SuspenseList>  );
}
```

**[Try it on CodeSandbox](https://codesandbox.io/s/empty-leaf-lp7eom)**

The `revealOrder="forwards"` option means that the closest `<Suspense>` nodes inside this list **will only “reveal” their content in the order they appear in the tree — even if the data for them arrives in a different order**. `<SuspenseList>` has other interesting modes: try changing `"forwards"` to `"backwards"` or `"together"` and see what happens.

You can control how many loading states are visible at once with the `tail` prop. If we specify `tail="collapsed"`, we’ll see *at most one* fallback at a time. You can play with it [here](https://codesandbox.io/s/keen-leaf-gccxd8).

Keep in mind that `<SuspenseList>` is composable, like anything in React. For example, you can create a grid by putting several `<SuspenseList>` rows inside a `<SuspenseList>` table.

## [](#next-steps)Next Steps

Concurrent Mode offers a powerful UI programming model and a set of new composable primitives to help you orchestrate delightful user experiences.

It’s a result of several years of research and development, but it’s not finished. In the section on [adopting Concurrent Mode](/docs/concurrent-mode-adoption.html), we’ll describe how you can try it and what you can expect.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/concurrent-mode-patterns.md)

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/concurrent-mode-patterns.md)

----
url: https://react.dev/reference/react-dom/createPortal
----

[API Reference](/reference/react)

[APIs](/reference/react-dom)

# createPortal[](#undefined "Link for this heading")

`createPortal` lets you render some children into a different part of the DOM.

```
<div>

  <SomeComponent />

  {createPortal(children, domNode, key?)}

</div>
```

***

## Reference[](#reference "Link for Reference ")

### `createPortal(children, domNode, key?)`[](#createportal "Link for this heading")

To create a portal, call `createPortal`, passing some JSX, and the DOM node where it should be rendered:

```
import { createPortal } from 'react-dom';



// ...



<div>

  <p>This child is placed in the parent div.</p>

  {createPortal(

    <p>This child is placed in the document body.</p>,

    document.body

  )}

</div>
```

***

## Usage[](#usage "Link for Usage ")

### Rendering to a different part of the DOM[](#rendering-to-a-different-part-of-the-dom "Link for Rendering to a different part of the DOM ")

*Portals* let your components render some of their children into a different place in the DOM. This lets a part of your component “escape” from whatever containers it may be in. For example, a component can display a modal dialog or a tooltip that appears above and outside of the rest of the page.

To create a portal, render the result of `createPortal` with some JSX and the DOM node where it should go:

```
import { createPortal } from 'react-dom';



function MyComponent() {

  return (

    <div style={{ border: '2px solid black' }}>

      <p>This child is placed in the parent div.</p>

      {createPortal(

        <p>This child is placed in the document body.</p>,

        document.body

      )}

    </div>

  );

}
```

React will put the DOM nodes for the JSX you passed inside of the DOM node you provided.

Without a portal, the second `<p>` would be placed inside the parent `<div>`, but the portal “teleported” it into the [`document.body`:](https://developer.mozilla.org/en-US/docs/Web/API/Document/body)

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { createPortal } from 'react-dom';

export default function MyComponent() {
  return (
    <div style={{ border: '2px solid black' }}>
      <p>This child is placed in the parent div.</p>
      {createPortal(
        <p>This child is placed in the document body.</p>,
        document.body
      )}
    </div>
  );
}
```

Notice how the second paragraph visually appears outside the parent `<div>` with the border. If you inspect the DOM structure with developer tools, you’ll see that the second `<p>` got placed directly into the `<body>`:

```
<body>

  <div id="root">

    ...

      <div style="border: 2px solid black">

        <p>This child is placed inside the parent div.</p>

      </div>

    ...

  </div>

  <p>This child is placed in the document body.</p>

</body>
```

A portal only changes the physical placement of the DOM node. In every other way, the JSX you render into a portal acts as a child node of the React component that renders it. For example, the child can access the context provided by the parent tree, and events still bubble up from children to parents according to the React tree.

***

### Rendering a modal dialog with a portal[](#rendering-a-modal-dialog-with-a-portal "Link for Rendering a modal dialog with a portal ")

You can use a portal to create a modal dialog that floats above the rest of the page, even if the component that summons the dialog is inside a container with `overflow: hidden` or other styles that interfere with the dialog.

In this example, the two containers have styles that disrupt the modal dialog, but the one rendered into a portal is unaffected because, in the DOM, the modal is not contained within the parent JSX elements.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import NoPortalExample from './NoPortalExample';
import PortalExample from './PortalExample';

export default function App() {
  return (
    <>
      <div className="clipping-container">
        <NoPortalExample  />
      </div>
      <div className="clipping-container">
        <PortalExample />
      </div>
    </>
  );
}
```

### Pitfall

It’s important to make sure that your app is accessible when using portals. For instance, you may need to manage keyboard focus so that the user can move the focus in and out of the portal in a natural way.

Follow the [WAI-ARIA Modal Authoring Practices](https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal) when creating modals. If you use a community package, ensure that it is accessible and follows these guidelines.

***

### Rendering React components into non-React server markup[](#rendering-react-components-into-non-react-server-markup "Link for Rendering React components into non-React server markup ")

Portals can be useful if your React root is only part of a static or server-rendered page that isn’t built with React. For example, if your page is built with a server framework like Rails, you can create areas of interactivity within static areas such as sidebars. Compared with having [multiple separate React roots,](/reference/react-dom/client/createRoot#rendering-a-page-partially-built-with-react) portals let you treat the app as a single React tree with shared state even though its parts render to different parts of the DOM.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { createPortal } from 'react-dom';

const sidebarContentEl = document.getElementById('sidebar-content');

export default function App() {
  return (
    <>
      <MainContent />
      {createPortal(
        <SidebarContent />,
        sidebarContentEl
      )}
    </>
  );
}

function MainContent() {
  return <p>This part is rendered by React</p>;
}

function SidebarContent() {
  return <p>This part is also rendered by React!</p>;
}
```

***

### Rendering React components into non-React DOM nodes[](#rendering-react-components-into-non-react-dom-nodes "Link for Rendering React components into non-React DOM nodes ")

You can also use a portal to manage the content of a DOM node that’s managed outside of React. For example, suppose you’re integrating with a non-React map widget and you want to render React content inside a popup. To do this, declare a `popupContainer` state variable to store the DOM node you’re going to render into:

```
const [popupContainer, setPopupContainer] = useState(null);
```

When you create the third-party widget, store the DOM node returned by the widget so you can render into it:

```
useEffect(() => {

  if (mapRef.current === null) {

    const map = createMapWidget(containerRef.current);

    mapRef.current = map;

    const popupDiv = addPopupToMapWidget(map);

    setPopupContainer(popupDiv);

  }

}, []);
```

This lets you use `createPortal` to render React content into `popupContainer` once it becomes available:

```
return (

  <div style={{ width: 250, height: 250 }} ref={containerRef}>

    {popupContainer !== null && createPortal(

      <p>Hello from React!</p>,

      popupContainer

    )}

  </div>

);
```

Here is a complete example you can play with:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useRef, useEffect, useState } from 'react';
import { createPortal } from 'react-dom';
import { createMapWidget, addPopupToMapWidget } from './map-widget.js';

export default function Map() {
  const containerRef = useRef(null);
  const mapRef = useRef(null);
  const [popupContainer, setPopupContainer] = useState(null);

  useEffect(() => {
    if (mapRef.current === null) {
      const map = createMapWidget(containerRef.current);
      mapRef.current = map;
      const popupDiv = addPopupToMapWidget(map);
      setPopupContainer(popupDiv);
    }
  }, []);

  return (
    <div style={{ width: 250, height: 250 }} ref={containerRef}>
      {popupContainer !== null && createPortal(
        <p>Hello from React!</p>,
        popupContainer
      )}
    </div>
  );
}
```

[PreviousAPIs](/reference/react-dom)

[NextflushSync](/reference/react-dom/flushSync)

***

----
url: https://react.dev/reference/eslint-plugin-react-hooks/lints/use-memo
----

[API Reference](/reference/react)

[Lints](/reference/eslint-plugin-react-hooks)

# use-memo[](#undefined "Link for this heading")

Validates that the `useMemo` hook is used with a return value. See [`useMemo` docs](/reference/react/useMemo) for more information.

## Rule Details[](#rule-details "Link for Rule Details ")

`useMemo` is for computing and caching expensive values, not for side effects. Without a return value, `useMemo` returns `undefined`, which defeats its purpose and likely indicates you’re using the wrong hook.

### Invalid[](#invalid "Link for Invalid ")

Examples of incorrect code for this rule:

```
// ❌ No return value

function Component({ data }) {

  const processed = useMemo(() => {

    data.forEach(item => console.log(item));

    // Missing return!

  }, [data]);



  return <div>{processed}</div>; // Always undefined

}
```

### Valid[](#valid "Link for Valid ")

Examples of correct code for this rule:

```
// ✅ Returns computed value

function Component({ data }) {

  const processed = useMemo(() => {

    return data.map(item => item * 2);

  }, [data]);



  return <div>{processed}</div>;

}
```

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### I need to run side effects when dependencies change[](#side-effects "Link for I need to run side effects when dependencies change ")

You might try to use `useMemo` for side effects:

```
// ❌ Wrong: Side effects in useMemo

function Component({user}) {

  // No return value, just side effect

  useMemo(() => {

    analytics.track('UserViewed', {userId: user.id});

  }, [user.id]);



  // Not assigned to a variable

  useMemo(() => {

    return analytics.track('UserViewed', {userId: user.id});

  }, [user.id]);

}
```

If the side effect needs to happen in response to user interaction, it’s best to colocate the side effect with the event:

```
// ✅ Good: Side effects in event handlers

function Component({user}) {

  const handleClick = () => {

    analytics.track('ButtonClicked', {userId: user.id});

    // Other click logic...

  };



  return <button onClick={handleClick}>Click me</button>;

}
```

If the side effect sychronizes React state with some external state (or vice versa), use `useEffect`:

```
// ✅ Good: Synchronization in useEffect

function Component({theme}) {

  useEffect(() => {

    localStorage.setItem('preferredTheme', theme);

    document.body.className = theme;

  }, [theme]);



  return <div>Current theme: {theme}</div>;

}
```

[Previousunsupported-syntax](/reference/eslint-plugin-react-hooks/lints/unsupported-syntax)

***

----
url: https://legacy.reactjs.org/versions
----

# React Versions

A complete release history for React is available [on GitHub](https://github.com/facebook/react/releases).\
Changelogs for recent releases can also be found below.

> Note
>
> The current docs are for React 18. For React 17, see [https://17.reactjs.org.](https://17.reactjs.org)

See our FAQ for information about [our versioning policy and commitment to stability](/docs/faq-versioning.html).

### 18.2.0

* [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md#1820-june-14-2022)

### 18.1.0

* [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md#1810-april-26-2022)

### 18.0.0

* [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md#1800-march-29-2022)

### 17.0.2

* [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md#1702-march-22-2021)

### 17.0.1

* [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md#1701-october-22-2020)

### 17.0.0

* [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md#1700-october-20-2020)

### 16.14.0

* [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md#16140-october-14-2020)

### 16.13.1

* [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md#16131-march-19-2020)

### 16.13.0

* [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md#16130-february-26-2020)

### 16.12.0

* [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md#16120-november-14-2019)

### 16.11

* [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md#16110-october-22-2019)

### 16.10.2

* [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md#16102-october-3-2019)

### 16.10.1

* [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md#16101-september-28-2019)

### 16.10

* [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md#16100-september-27-2019)

### 16.9

* [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md#1690-august-8-2019)

### 16.8

* [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md#1680-february-6-2019)

### 16.7

* [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md#1670-december-19-2018)

### 16.6

* [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md#1660-october-23-2018)

### 16.5

* [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md#1650-september-5-2018)

### 16.4

* [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md#1640-may-23-2018)

### 16.3

* [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md#1632-april-16-2018)

### 16.2

* [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md#1620-november-28-2017)

### 16.1

* [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md#1611-november-13-2017)

### 16.0

* [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md#1600-september-26-2017)

### 15.6

* [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md#1562-september-25-2017)

----
url: https://legacy.reactjs.org/
----

### Declarative

React makes it painless to create interactive UIs. Design simple views for each state in your application, and React will efficiently update and render just the right components when your data changes.

Declarative views make your code more predictable and easier to debug.

### Component-Based

Build encapsulated components that manage their own state, then compose them to make complex UIs.

Since component logic is written in JavaScript instead of templates, you can easily pass rich data through your app and keep state out of the DOM.

### Learn Once, Write Anywhere

We don’t make assumptions about the rest of your technology stack, so you can develop new features in React without rewriting existing code.

React can also render on the server using Node and power mobile apps using [React Native](https://reactnative.dev/).

***

### A Simple Component

React components implement a `render()` method that takes input data and returns what to display. This example uses an XML-like syntax called JSX. Input data that is passed into the component can be accessed by `render()` via `this.props`.

**JSX is optional and not required to use React.** Try the [Babel REPL](https://babeljs.io/repl/#?presets=react\&code_lz=MYewdgzgLgBApgGzgWzmWBeGAeAFgRgD4AJRBEAGhgHcQAnBAEwEJsB6AwgbgChRJY_KAEMAlmDh0YWRiGABXVOgB0AczhQAokiVQAQgE8AkowAUAcjogQUcwEpeAJTjDgUACIB5ALLK6aRklTRBQ0KCohMQk6Bx4gA) to see the raw JavaScript code produced by the JSX compilation step.

#### Loading code example...

### A Stateful Component

In addition to taking input data (accessed via `this.props`), a component can maintain internal state data (accessed via `this.state`). When a component’s state data changes, the rendered markup will be updated by re-invoking `render()`.

#### Loading code example...

### An Application

Using `props` and `state`, we can put together a small Todo application. This example uses `state` to track the current list of items as well as the text that the user has entered. Although event handlers appear to be rendered inline, they will be collected and implemented using event delegation.

#### Loading code example...

### A Component Using External Plugins

React allows you to interface with other libraries and frameworks. This example uses **remarkable**, an external Markdown library, to convert the `<textarea>`’s value in real time.

#### Loading code example...

[Get Started](/docs/getting-started.html)

[Take the Tutorial](/tutorial/tutorial.html)

----
url: https://18.react.dev/learn/preserving-and-resetting-state
----

```
import { useState } from 'react';

export default function App() {
  const counter = <Counter />;
  return (
    <div>
      {counter}
      {counter}
    </div>
  );
}

function Counter() {
  const [score, setScore] = useState(0);
  const [hover, setHover] = useState(false);

  let className = 'counter';
  if (hover) {
    className += ' hover';
  }

  return (
    <div
      className={className}
      onPointerEnter={() => setHover(true)}
      onPointerLeave={() => setHover(false)}
    >
      <h1>{score}</h1>
      <button onClick={() => setScore(score + 1)}>
        Add one
      </button>
    </div>
  );
}
```

Here’s how these look as a tree:

React tree

**These are two separate counters because each is rendered at its own position in the tree.** You don’t usually have to think about these positions to use React, but it can be useful to understand how it works.

In React, each component on the screen has fully isolated state. For example, if you render two `Counter` components side by side, each of them will get its own, independent, `score` and `hover` states.

Try clicking both counters and notice they don’t affect each other:

```
import { useState } from 'react';

export default function App() {
  return (
    <div>
      <Counter />
      <Counter />
    </div>
  );
}

function Counter() {
  const [score, setScore] = useState(0);
  const [hover, setHover] = useState(false);

  let className = 'counter';
  if (hover) {
    className += ' hover';
  }

  return (
    <div
      className={className}
      onPointerEnter={() => setHover(true)}
      onPointerLeave={() => setHover(false)}
    >
      <h1>{score}</h1>
      <button onClick={() => setScore(score + 1)}>
        Add one
      </button>
    </div>
  );
}
```

As you can see, when one counter is updated, only the state for that component is updated:

Updating state

React will keep the state around for as long as you render the same component at the same position in the tree. To see this, increment both counters, then remove the second component by unchecking “Render the second counter” checkbox, and then add it back by ticking it again:

```
import { useState } from 'react';

export default function App() {
  const [showB, setShowB] = useState(true);
  return (
    <div>
      <Counter />
      {showB && <Counter />} 
      <label>
        <input
          type="checkbox"
          checked={showB}
          onChange={e => {
            setShowB(e.target.checked)
          }}
        />
        Render the second counter
      </label>
    </div>
  );
}

function Counter() {
  const [score, setScore] = useState(0);
  const [hover, setHover] = useState(false);

  let className = 'counter';
  if (hover) {
    className += ' hover';
  }

  return (
    <div
      className={className}
      onPointerEnter={() => setHover(true)}
      onPointerLeave={() => setHover(false)}
    >
      <h1>{score}</h1>
      <button onClick={() => setScore(score + 1)}>
        Add one
      </button>
    </div>
  );
}
```

```
import { useState } from 'react';

export default function App() {
  const [isFancy, setIsFancy] = useState(false);
  return (
    <div>
      {isFancy ? (
        <Counter isFancy={true} /> 
      ) : (
        <Counter isFancy={false} /> 
      )}
      <label>
        <input
          type="checkbox"
          checked={isFancy}
          onChange={e => {
            setIsFancy(e.target.checked)
          }}
        />
        Use fancy styling
      </label>
    </div>
  );
}

function Counter({ isFancy }) {
  const [score, setScore] = useState(0);
  const [hover, setHover] = useState(false);

  let className = 'counter';
  if (hover) {
    className += ' hover';
  }
  if (isFancy) {
    className += ' fancy';
  }

  return (
    <div
      className={className}
      onPointerEnter={() => setHover(true)}
      onPointerLeave={() => setHover(false)}
    >
      <h1>{score}</h1>
      <button onClick={() => setScore(score + 1)}>
        Add one
      </button>
    </div>
  );
}
```

When you tick or clear the checkbox, the counter state does not get reset. Whether `isFancy` is `true` or `false`, you always have a `<Counter />` as the first child of the `div` returned from the root `App` component:

Updating the `App` state does not reset the `Counter` because `Counter` stays in the same position

It’s the same component at the same position, so from React’s perspective, it’s the same counter.

### Pitfall

Remember that **it’s the position in the UI tree—not in the JSX markup—that matters to React!** This component has two `return` clauses with different `<Counter />` JSX tags inside and outside the `if`:

```
import { useState } from 'react';

export default function App() {
  const [isFancy, setIsFancy] = useState(false);
  if (isFancy) {
    return (
      <div>
        <Counter isFancy={true} />
        <label>
          <input
            type="checkbox"
            checked={isFancy}
            onChange={e => {
              setIsFancy(e.target.checked)
            }}
          />
          Use fancy styling
        </label>
      </div>
    );
  }
  return (
    <div>
      <Counter isFancy={false} />
      <label>
        <input
          type="checkbox"
          checked={isFancy}
          onChange={e => {
            setIsFancy(e.target.checked)
          }}
        />
        Use fancy styling
      </label>
    </div>
  );
}

function Counter({ isFancy }) {
  const [score, setScore] = useState(0);
  const [hover, setHover] = useState(false);

  let className = 'counter';
  if (hover) {
    className += ' hover';
  }
  if (isFancy) {
    className += ' fancy';
  }

  return (
    <div
      className={className}
      onPointerEnter={() => setHover(true)}
      onPointerLeave={() => setHover(false)}
    >
      <h1>{score}</h1>
      <button onClick={() => setScore(score + 1)}>
        Add one
      </button>
    </div>
  );
}
```

You might expect the state to reset when you tick checkbox, but it doesn’t! This is because **both of these `<Counter />` tags are rendered at the same position.** React doesn’t know where you place the conditions in your function. All it “sees” is the tree you return.

In both cases, the `App` component returns a `<div>` with `<Counter />` as a first child. To React, these two counters have the same “address”: the first child of the first child of the root. This is how React matches them up between the previous and next renders, regardless of how you structure your logic.

## Different components at the same position reset state[](#different-components-at-the-same-position-reset-state "Link for Different components at the same position reset state ")

In this example, ticking the checkbox will replace `<Counter>` with a `<p>`:

```
import { useState } from 'react';

export default function App() {
  const [isPaused, setIsPaused] = useState(false);
  return (
    <div>
      {isPaused ? (
        <p>See you later!</p> 
      ) : (
        <Counter /> 
      )}
      <label>
        <input
          type="checkbox"
          checked={isPaused}
          onChange={e => {
            setIsPaused(e.target.checked)
          }}
        />
        Take a break
      </label>
    </div>
  );
}

function Counter() {
  const [score, setScore] = useState(0);
  const [hover, setHover] = useState(false);

  let className = 'counter';
  if (hover) {
    className += ' hover';
  }

  return (
    <div
      className={className}
      onPointerEnter={() => setHover(true)}
      onPointerLeave={() => setHover(false)}
    >
      <h1>{score}</h1>
      <button onClick={() => setScore(score + 1)}>
        Add one
      </button>
    </div>
  );
}
```

Here, you switch between *different* component types at the same position. Initially, the first child of the `<div>` contained a `Counter`. But when you swapped in a `p`, React removed the `Counter` from the UI tree and destroyed its state.

When `Counter` changes to `p`, the `Counter` is deleted and the `p` is added

When switching back, the `p` is deleted and the `Counter` is added

Also, **when you render a different component in the same position, it resets the state of its entire subtree.** To see how this works, increment the counter and then tick the checkbox:

```
import { useState } from 'react';

export default function App() {
  const [isFancy, setIsFancy] = useState(false);
  return (
    <div>
      {isFancy ? (
        <div>
          <Counter isFancy={true} /> 
        </div>
      ) : (
        <section>
          <Counter isFancy={false} />
        </section>
      )}
      <label>
        <input
          type="checkbox"
          checked={isFancy}
          onChange={e => {
            setIsFancy(e.target.checked)
          }}
        />
        Use fancy styling
      </label>
    </div>
  );
}

function Counter({ isFancy }) {
  const [score, setScore] = useState(0);
  const [hover, setHover] = useState(false);

  let className = 'counter';
  if (hover) {
    className += ' hover';
  }
  if (isFancy) {
    className += ' fancy';
  }

  return (
    <div
      className={className}
      onPointerEnter={() => setHover(true)}
      onPointerLeave={() => setHover(false)}
    >
      <h1>{score}</h1>
      <button onClick={() => setScore(score + 1)}>
        Add one
      </button>
    </div>
  );
}
```

The counter state gets reset when you click the checkbox. Although you render a `Counter`, the first child of the `div` changes from a `div` to a `section`. When the child `div` was removed from the DOM, the whole tree below it (including the `Counter` and its state) was destroyed as well.

When `section` changes to `div`, the `section` is deleted and the new `div` is added

When switching back, the `div` is deleted and the new `section` is added

As a rule of thumb, **if you want to preserve the state between re-renders, the structure of your tree needs to “match up”** from one render to another. If the structure is different, the state gets destroyed because React destroys state when it removes a component from the tree.

### Pitfall

This is why you should not nest component function definitions.

Here, the `MyTextField` component function is defined *inside* `MyComponent`:

```
import { useState } from 'react';

export default function MyComponent() {
  const [counter, setCounter] = useState(0);

  function MyTextField() {
    const [text, setText] = useState('');

    return (
      <input
        value={text}
        onChange={e => setText(e.target.value)}
      />
    );
  }

  return (
    <>
      <MyTextField />
      <button onClick={() => {
        setCounter(counter + 1)
      }}>Clicked {counter} times</button>
    </>
  );
}
```

Every time you click the button, the input state disappears! This is because a *different* `MyTextField` function is created for every render of `MyComponent`. You’re rendering a *different* component in the same position, so React resets all state below. This leads to bugs and performance problems. To avoid this problem, **always declare component functions at the top level, and don’t nest their definitions.**

## Resetting state at the same position[](#resetting-state-at-the-same-position "Link for Resetting state at the same position ")

By default, React preserves state of a component while it stays at the same position. Usually, this is exactly what you want, so it makes sense as the default behavior. But sometimes, you may want to reset a component’s state. Consider this app that lets two players keep track of their scores during each turn:

```
import { useState } from 'react';

export default function Scoreboard() {
  const [isPlayerA, setIsPlayerA] = useState(true);
  return (
    <div>
      {isPlayerA ? (
        <Counter person="Taylor" />
      ) : (
        <Counter person="Sarah" />
      )}
      <button onClick={() => {
        setIsPlayerA(!isPlayerA);
      }}>
        Next player!
      </button>
    </div>
  );
}

function Counter({ person }) {
  const [score, setScore] = useState(0);
  const [hover, setHover] = useState(false);

  let className = 'counter';
  if (hover) {
    className += ' hover';
  }

  return (
    <div
      className={className}
      onPointerEnter={() => setHover(true)}
      onPointerLeave={() => setHover(false)}
    >
      <h1>{person}'s score: {score}</h1>
      <button onClick={() => setScore(score + 1)}>
        Add one
      </button>
    </div>
  );
}
```

```
import { useState } from 'react';

export default function Scoreboard() {
  const [isPlayerA, setIsPlayerA] = useState(true);
  return (
    <div>
      {isPlayerA &&
        <Counter person="Taylor" />
      }
      {!isPlayerA &&
        <Counter person="Sarah" />
      }
      <button onClick={() => {
        setIsPlayerA(!isPlayerA);
      }}>
        Next player!
      </button>
    </div>
  );
}

function Counter({ person }) {
  const [score, setScore] = useState(0);
  const [hover, setHover] = useState(false);

  let className = 'counter';
  if (hover) {
    className += ' hover';
  }

  return (
    <div
      className={className}
      onPointerEnter={() => setHover(true)}
      onPointerLeave={() => setHover(false)}
    >
      <h1>{person}'s score: {score}</h1>
      <button onClick={() => setScore(score + 1)}>
        Add one
      </button>
    </div>
  );
}
```

```
import { useState } from 'react';

export default function Scoreboard() {
  const [isPlayerA, setIsPlayerA] = useState(true);
  return (
    <div>
      {isPlayerA ? (
        <Counter key="Taylor" person="Taylor" />
      ) : (
        <Counter key="Sarah" person="Sarah" />
      )}
      <button onClick={() => {
        setIsPlayerA(!isPlayerA);
      }}>
        Next player!
      </button>
    </div>
  );
}

function Counter({ person }) {
  const [score, setScore] = useState(0);
  const [hover, setHover] = useState(false);

  let className = 'counter';
  if (hover) {
    className += ' hover';
  }

  return (
    <div
      className={className}
      onPointerEnter={() => setHover(true)}
      onPointerLeave={() => setHover(false)}
    >
      <h1>{person}'s score: {score}</h1>
      <button onClick={() => setScore(score + 1)}>
        Add one
      </button>
    </div>
  );
}
```

Switching between Taylor and Sarah does not preserve the state. This is because **you gave them different `key`s:**

```
{isPlayerA ? (

  <Counter key="Taylor" person="Taylor" />

) : (

  <Counter key="Sarah" person="Sarah" />

)}
```

Specifying a `key` tells React to use the `key` itself as part of the position, instead of their order within the parent. This is why, even though you render them in the same place in JSX, React sees them as two different counters, and so they will never share state. Every time a counter appears on the screen, its state is created. Every time it is removed, its state is destroyed. Toggling between them resets their state over and over.

### Note

Remember that keys are not globally unique. They only specify the position *within the parent*.

### Resetting a form with a key[](#resetting-a-form-with-a-key "Link for Resetting a form with a key ")

Resetting state with a key is particularly useful when dealing with forms.

In this chat app, the `<Chat>` component contains the text input state:

```
import { useState } from 'react';
import Chat from './Chat.js';
import ContactList from './ContactList.js';

export default function Messenger() {
  const [to, setTo] = useState(contacts[0]);
  return (
    <div>
      <ContactList
        contacts={contacts}
        selectedContact={to}
        onSelect={contact => setTo(contact)}
      />
      <Chat contact={to} />
    </div>
  )
}

const contacts = [
  { id: 0, name: 'Taylor', email: 'taylor@mail.com' },
  { id: 1, name: 'Alice', email: 'alice@mail.com' },
  { id: 2, name: 'Bob', email: 'bob@mail.com' }
];
```

Try entering something into the input, and then press “Alice” or “Bob” to choose a different recipient. You will notice that the input state is preserved because the `<Chat>` is rendered at the same position in the tree.

**In many apps, this may be the desired behavior, but not in a chat app!** You don’t want to let the user send a message they already typed to a wrong person due to an accidental click. To fix it, add a `key`:

```
<Chat key={to.id} contact={to} />
```

This ensures that when you select a different recipient, the `Chat` component will be recreated from scratch, including any state in the tree below it. React will also re-create the DOM elements instead of reusing them.

Now switching the recipient always clears the text field:

```
import { useState } from 'react';
import Chat from './Chat.js';
import ContactList from './ContactList.js';

export default function Messenger() {
  const [to, setTo] = useState(contacts[0]);
  return (
    <div>
      <ContactList
        contacts={contacts}
        selectedContact={to}
        onSelect={contact => setTo(contact)}
      />
      <Chat key={to.id} contact={to} />
    </div>
  )
}

const contacts = [
  { id: 0, name: 'Taylor', email: 'taylor@mail.com' },
  { id: 1, name: 'Alice', email: 'alice@mail.com' },
  { id: 2, name: 'Bob', email: 'bob@mail.com' }
];
```

```
import { useState } from 'react';

export default function App() {
  const [showHint, setShowHint] = useState(false);
  if (showHint) {
    return (
      <div>
        <p><i>Hint: Your favorite city?</i></p>
        <Form />
        <button onClick={() => {
          setShowHint(false);
        }}>Hide hint</button>
      </div>
    );
  }
  return (
    <div>
      <Form />
      <button onClick={() => {
        setShowHint(true);
      }}>Show hint</button>
    </div>
  );
}

function Form() {
  const [text, setText] = useState('');
  return (
    <textarea
      value={text}
      onChange={e => setText(e.target.value)}
    />
  );
}
```

[PreviousSharing State Between Components](/learn/sharing-state-between-components)

[NextExtracting State Logic into a Reducer](/learn/extracting-state-logic-into-a-reducer)

***

----
url: https://react.dev/learn/installation
----

[Learn React](/learn)

# Installation[](#undefined "Link for this heading")

React has been designed from the start for gradual adoption. You can use as little or as much React as you need. Whether you want to get a taste of React, add some interactivity to an HTML page, or start a complex React-powered app, this section will help you get started.

## Try React[](#try-react "Link for Try React ")

You don’t need to install anything to play with React. Try editing this sandbox!

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
function Greeting({ name }) {
  return <h1>Hello, {name}</h1>;
}

export default function App() {
  return <Greeting name="world" />
}
```

You can edit it directly or open it in a new tab by pressing the “Fork” button in the upper right corner.

Most pages in the React documentation contain sandboxes like this. Outside of the React documentation, there are many online sandboxes that support React: for example, [CodeSandbox](https://codesandbox.io/s/new), [StackBlitz](https://stackblitz.com/fork/react), or [CodePen.](https://codepen.io/pen?template=QWYVwWN)

To try React locally on your computer, [download this HTML page.](https://gist.githubusercontent.com/gaearon/0275b1e1518599bbeafcde4722e79ed1/raw/db72dcbf3384ee1708c4a07d3be79860db04bff0/example.html) Open it in your editor and in your browser!

## Creating a React App[](#creating-a-react-app "Link for Creating a React App ")

If you want to start a new React app, you can [create a React app](/learn/creating-a-react-app) using a recommended framework.

## Build a React App from Scratch[](#build-a-react-app-from-scratch "Link for Build a React App from Scratch ")

If a framework is not a good fit for your project, you prefer to build your own framework, or you just want to learn the basics of a React app you can [build a React app from scratch](/learn/build-a-react-app-from-scratch).

## Add React to an existing project[](#add-react-to-an-existing-project "Link for Add React to an existing project ")

If want to try using React in your existing app or a website, you can [add React to an existing project.](/learn/add-react-to-an-existing-project)

### Note

#### Should I use Create React App?[](#should-i-use-create-react-app "Link for Should I use Create React App? ")

No. Create React App has been deprecated. For more information, see [Sunsetting Create React App](/blog/2025/02/14/sunsetting-create-react-app).

## Next steps[](#next-steps "Link for Next steps ")

Head to the [Quick Start](/learn) guide for a tour of the most important React concepts you will encounter every day.

[PreviousThinking in React](/learn/thinking-in-react)

[NextCreating a React App](/learn/creating-a-react-app)

***

----
url: https://react.dev/blog/2024/12/05/react-19
----

[Blog](/blog)

# React v19[](#undefined "Link for this heading")

December 05, 2024 by [The React Team](/community/team)

***

### Note

### React 19 is now stable\![](#react-19-is-now-stable "Link for React 19 is now stable! ")

Additions since this post was originally shared with the React 19 RC in April:

* **Pre-warming for suspended trees**: see [Improvements to Suspense](/blog/2024/04/25/react-19-upgrade-guide#improvements-to-suspense).
* **React DOM static APIs**: see [New React DOM Static APIs](#new-react-dom-static-apis).

*The date for this post has been updated to reflect the stable release date.*

React v19 is now available on npm!

In our [React 19 Upgrade Guide](/blog/2024/04/25/react-19-upgrade-guide), we shared step-by-step instructions for upgrading your app to React 19. In this post, we’ll give an overview of the new features in React 19, and how you can adopt them.

* [What’s new in React 19](#whats-new-in-react-19)
* [Improvements in React 19](#improvements-in-react-19)
* [How to upgrade](#how-to-upgrade)

For a list of breaking changes, see the [Upgrade Guide](/blog/2024/04/25/react-19-upgrade-guide).

***

## What’s new in React 19[](#whats-new-in-react-19 "Link for What’s new in React 19 ")

### Actions[](#actions "Link for Actions ")

A common use case in React apps is to perform a data mutation and then update state in response. For example, when a user submits a form to change their name, you will make an API request, and then handle the response. In the past, you would need to handle pending states, errors, optimistic updates, and sequential requests manually.

For example, you could handle the pending and error state in `useState`:

```
// Before Actions

function UpdateName({}) {

  const [name, setName] = useState("");

  const [error, setError] = useState(null);

  const [isPending, setIsPending] = useState(false);



  const handleSubmit = async () => {

    setIsPending(true);

    const error = await updateName(name);

    setIsPending(false);

    if (error) {

      setError(error);

      return;

    }

    redirect("/path");

  };



  return (

    <div>

      <input value={name} onChange={(event) => setName(event.target.value)} />

      <button onClick={handleSubmit} disabled={isPending}>

        Update

      </button>

      {error && <p>{error}</p>}

    </div>

  );

}
```

In React 19, we’re adding support for using async functions in transitions to handle pending states, errors, forms, and optimistic updates automatically.

For example, you can use `useTransition` to handle the pending state for you:

```
// Using pending state from Actions

function UpdateName({}) {

  const [name, setName] = useState("");

  const [error, setError] = useState(null);

  const [isPending, startTransition] = useTransition();



  const handleSubmit = () => {

    startTransition(async () => {

      const error = await updateName(name);

      if (error) {

        setError(error);

        return;

      }

      redirect("/path");

    })

  };



  return (

    <div>

      <input value={name} onChange={(event) => setName(event.target.value)} />

      <button onClick={handleSubmit} disabled={isPending}>

        Update

      </button>

      {error && <p>{error}</p>}

    </div>

  );

}
```

The async transition will immediately set the `isPending` state to true, make the async request(s), and switch `isPending` to false after any transitions. This allows you to keep the current UI responsive and interactive while the data is changing.

### Note

#### By convention, functions that use async transitions are called “Actions”.[](#by-convention-functions-that-use-async-transitions-are-called-actions "Link for By convention, functions that use async transitions are called “Actions”. ")

Actions automatically manage submitting data for you:

* **Pending state**: Actions provide a pending state that starts at the beginning of a request and automatically resets when the final state update is committed.
* **Optimistic updates**: Actions support the new [`useOptimistic`](#new-hook-optimistic-updates) hook so you can show users instant feedback while the requests are submitting.
* **Error handling**: Actions provide error handling so you can display Error Boundaries when a request fails, and revert optimistic updates to their original value automatically.
* **Forms**: `<form>` elements now support passing functions to the `action` and `formAction` props. Passing functions to the `action` props use Actions by default and reset the form automatically after submission.

Building on top of Actions, React 19 introduces [`useOptimistic`](#new-hook-optimistic-updates) to manage optimistic updates, and a new hook [`React.useActionState`](#new-hook-useactionstate) to handle common cases for Actions. In `react-dom` we’re adding [`<form>` Actions](#form-actions) to manage forms automatically and [`useFormStatus`](#new-hook-useformstatus) to support the common cases for Actions in forms.

In React 19, the above example can be simplified to:

```
// Using <form> Actions and useActionState

function ChangeName({ name, setName }) {

  const [error, submitAction, isPending] = useActionState(

    async (previousState, formData) => {

      const error = await updateName(formData.get("name"));

      if (error) {

        return error;

      }

      redirect("/path");

      return null;

    },

    null,

  );



  return (

    <form action={submitAction}>

      <input type="text" name="name" />

      <button type="submit" disabled={isPending}>Update</button>

      {error && <p>{error}</p>}

    </form>

  );

}
```

In the next section, we’ll break down each of the new Action features in React 19.

### New hook: `useActionState`[](#new-hook-useactionstate "Link for this heading")

To make the common cases easier for Actions, we’ve added a new hook called `useActionState`:

```
const [error, submitAction, isPending] = useActionState(

  async (previousState, newName) => {

    const error = await updateName(newName);

    if (error) {

      // You can return any result of the action.

      // Here, we return only the error.

      return error;

    }



    // handle success

    return null;

  },

  null,

);
```

`useActionState` accepts a function (the “Action”), and returns a wrapped Action to call. This works because Actions compose. When the wrapped Action is called, `useActionState` will return the last result of the Action as `data`, and the pending state of the Action as `pending`.

### Note

`React.useActionState` was previously called `ReactDOM.useFormState` in the Canary releases, but we’ve renamed it and deprecated `useFormState`.

See [#28491](https://github.com/facebook/react/pull/28491) for more info.

For more information, see the docs for [`useActionState`](/reference/react/useActionState).

### React DOM: `<form>` Actions[](#form-actions "Link for this heading")

Actions are also integrated with React 19’s new `<form>` features for `react-dom`. We’ve added support for passing functions as the `action` and `formAction` props of `<form>`, `<input>`, and `<button>` elements to automatically submit forms with Actions:

```
<form action={actionFunction}>
```

When a `<form>` Action succeeds, React will automatically reset the form for uncontrolled components. If you need to reset the `<form>` manually, you can call the new `requestFormReset` React DOM API.

For more information, see the `react-dom` docs for [`<form>`](/reference/react-dom/components/form), [`<input>`](/reference/react-dom/components/input), and `<button>`.

### React DOM: New hook: `useFormStatus`[](#new-hook-useformstatus "Link for this heading")

In design systems, it’s common to write design components that need access to information about the `<form>` they’re in, without drilling props down to the component. This can be done via Context, but to make the common case easier, we’ve added a new hook `useFormStatus`:

```
import {useFormStatus} from 'react-dom';



function DesignButton() {

  const {pending} = useFormStatus();

  return <button type="submit" disabled={pending} />

}
```

`useFormStatus` reads the status of the parent `<form>` as if the form was a Context provider.

For more information, see the `react-dom` docs for [`useFormStatus`](/reference/react-dom/hooks/useFormStatus).

### New hook: `useOptimistic`[](#new-hook-optimistic-updates "Link for this heading")

Another common UI pattern when performing a data mutation is to show the final state optimistically while the async request is underway. In React 19, we’re adding a new hook called `useOptimistic` to make this easier:

```
function ChangeName({currentName, onUpdateName}) {

  const [optimisticName, setOptimisticName] = useOptimistic(currentName);



  const submitAction = async formData => {

    const newName = formData.get("name");

    setOptimisticName(newName);

    const updatedName = await updateName(newName);

    onUpdateName(updatedName);

  };



  return (

    <form action={submitAction}>

      <p>Your name is: {optimisticName}</p>

      <p>

        <label>Change Name:</label>

        <input

          type="text"

          name="name"

          disabled={currentName !== optimisticName}

        />

      </p>

    </form>

  );

}
```

The `useOptimistic` hook will immediately render the `optimisticName` while the `updateName` request is in progress. When the update finishes or errors, React will automatically switch back to the `currentName` value.

For more information, see the docs for [`useOptimistic`](/reference/react/useOptimistic).

### New API: `use`[](#new-feature-use "Link for this heading")

In React 19 we’re introducing a new API to read resources in render: `use`.

For example, you can read a promise with `use`, and React will Suspend until the promise resolves:

```
import {use} from 'react';



function Comments({commentsPromise}) {

  // `use` will suspend until the promise resolves.

  const comments = use(commentsPromise);

  return comments.map(comment => <p key={comment.id}>{comment}</p>);

}



function Page({commentsPromise}) {

  // When `use` suspends in Comments,

  // this Suspense boundary will be shown.

  return (

    <Suspense fallback={<div>Loading...</div>}>

      <Comments commentsPromise={commentsPromise} />

    </Suspense>

  )

}
```

### Note

#### `use` does not support promises created in render.[](#use-does-not-support-promises-created-in-render "Link for this heading")

If you try to pass a promise created in render to `use`, React will warn:

Console

A component was suspended by an uncached promise. Creating promises inside a Client Component or hook is not yet supported, except via a Suspense-compatible library or framework.

To fix, you need to pass a promise from a Suspense powered library or framework that supports caching for promises. In the future we plan to ship features to make it easier to cache promises in render.

You can also read context with `use`, allowing you to read Context conditionally such as after early returns:

```
import {use} from 'react';

import ThemeContext from './ThemeContext'



function Heading({children}) {

  if (children == null) {

    return null;

  }



  // This would not work with useContext

  // because of the early return.

  const theme = use(ThemeContext);

  return (

    <h1 style={{color: theme.color}}>

      {children}

    </h1>

  );

}
```

The `use` API can only be called in render, similar to hooks. Unlike hooks, `use` can be called conditionally. In the future we plan to support more ways to consume resources in render with `use`.

For more information, see the docs for [`use`](/reference/react/use).

## New React DOM Static APIs[](#new-react-dom-static-apis "Link for New React DOM Static APIs ")

We’ve added two new APIs to `react-dom/static` for static site generation:

* [`prerender`](/reference/react-dom/static/prerender)
* [`prerenderToNodeStream`](/reference/react-dom/static/prerenderToNodeStream)

These new APIs improve on `renderToString` by waiting for data to load for static HTML generation. They are designed to work with streaming environments like Node.js Streams and Web Streams. For example, in a Web Stream environment, you can prerender a React tree to static HTML with `prerender`:

```
import { prerender } from 'react-dom/static';



async function handler(request) {

  const {prelude} = await prerender(<App />, {

    bootstrapScripts: ['/main.js']

  });

  return new Response(prelude, {

    headers: { 'content-type': 'text/html' },

  });

}
```

Prerender APIs will wait for all data to load before returning the static HTML stream. Streams can be converted to strings, or sent with a streaming response. They do not support streaming content as it loads, which is supported by the existing [React DOM server rendering APIs](/reference/react-dom/server).

For more information, see [React DOM Static APIs](/reference/react-dom/static).

## React Server Components[](#react-server-components "Link for React Server Components ")

### Server Components[](#server-components "Link for Server Components ")

Server Components are a new option that allows rendering components ahead of time, before bundling, in an environment separate from your client application or SSR server. This separate environment is the “server” in React Server Components. Server Components can run once at build time on your CI server, or they can be run for each request using a web server.

React 19 includes all of the React Server Components features included from the Canary channel. This means libraries that ship with Server Components can now target React 19 as a peer dependency with a `react-server` [export condition](https://github.com/reactjs/rfcs/blob/main/text/0227-server-module-conventions.md#react-server-conditional-exports) for use in frameworks that support the [Full-stack React Architecture](/learn/creating-a-react-app#which-features-make-up-the-react-teams-full-stack-architecture-vision).

### Note

#### How do I build support for Server Components?[](#how-do-i-build-support-for-server-components "Link for How do I build support for Server Components? ")

While React Server Components in React 19 are stable and will not break between minor versions, the underlying APIs used to implement a React Server Components bundler or framework do not follow semver and may break between minors in React 19.x.

To support React Server Components as a bundler or framework, we recommend pinning to a specific React version, or using the Canary release. We will continue working with bundlers and frameworks to stabilize the APIs used to implement React Server Components in the future.

For more, see the docs for [React Server Components](/reference/rsc/server-components).

### Server Actions[](#server-actions "Link for Server Actions ")

Server Actions allow Client Components to call async functions executed on the server.

When a Server Action is defined with the `"use server"` directive, your framework will automatically create a reference to the server function, and pass that reference to the Client Component. When that function is called on the client, React will send a request to the server to execute the function, and return the result.

### Note

#### There is no directive for Server Components.[](#there-is-no-directive-for-server-components "Link for There is no directive for Server Components. ")

A common misunderstanding is that Server Components are denoted by `"use server"`, but there is no directive for Server Components. The `"use server"` directive is used for Server Actions.

For more info, see the docs for [Directives](/reference/rsc/directives).

Server Actions can be created in Server Components and passed as props to Client Components, or they can be imported and used in Client Components.

For more, see the docs for [React Server Actions](/reference/rsc/server-actions).

## Improvements in React 19[](#improvements-in-react-19 "Link for Improvements in React 19 ")

### `ref` as a prop[](#ref-as-a-prop "Link for this heading")

Starting in React 19, you can now access `ref` as a prop for function components:

```
function MyInput({placeholder, ref}) {

  return <input placeholder={placeholder} ref={ref} />

}



//...

<MyInput ref={ref} />
```

New function components will no longer need `forwardRef`, and we will be publishing a codemod to automatically update your components to use the new `ref` prop. In future versions we will deprecate and remove `forwardRef`.

### Note

`ref`s passed to classes are not passed as props since they reference the component instance.

### Diffs for hydration errors[](#diffs-for-hydration-errors "Link for Diffs for hydration errors ")

We also improved error reporting for hydration errors in `react-dom`. For example, instead of logging multiple errors in DEV without any information about the mismatch:

Console

Warning: Text content did not match. Server: “Server” Client: “Client” at span at App

Warning: An error occurred during hydration. The server HTML was replaced with client content in \<div>.

Warning: Text content did not match. Server: “Server” Client: “Client” at span at App

Warning: An error occurred during hydration. The server HTML was replaced with client content in \<div>.

Uncaught Error: Text content does not match server-rendered HTML. at checkForUnmatchedText …

We now log a single message with a diff of the mismatch:

Console

Uncaught Error: Hydration failed because the server rendered HTML didn’t match the client. As a result this tree will be regenerated on the client. This can happen if an SSR-ed Client Component used: - A server/client branch `if (typeof window !== 'undefined')`. - Variable input such as `Date.now()` or `Math.random()` which changes each time it’s called. - Date formatting in a user’s locale which doesn’t match the server. - External changing data without sending a snapshot of it along with the HTML. - Invalid HTML tag nesting. It can also happen if the client has a browser extension installed which messes with the HTML before React loaded. <https://react.dev/link/hydration-mismatch> \<App> \<span> + Client - Server at throwOnHydrationMismatch …

### `<Context>` as a provider[](#context-as-a-provider "Link for this heading")

In React 19, you can render `<Context>` as a provider instead of `<Context.Provider>`:

```
const ThemeContext = createContext('');



function App({children}) {

  return (

    <ThemeContext value="dark">

      {children}

    </ThemeContext>

  );

}
```

New Context providers can use `<Context>` and we will be publishing a codemod to convert existing providers. In future versions we will deprecate `<Context.Provider>`.

### Cleanup functions for refs[](#cleanup-functions-for-refs "Link for Cleanup functions for refs ")

We now support returning a cleanup function from `ref` callbacks:

```
<input

  ref={(ref) => {

    // ref created



    // NEW: return a cleanup function to reset

    // the ref when element is removed from DOM.

    return () => {

      // ref cleanup

    };

  }}

/>
```

When the component unmounts, React will call the cleanup function returned from the `ref` callback. This works for DOM refs, refs to class components, and `useImperativeHandle`.

### Note

Previously, React would call `ref` functions with `null` when unmounting the component. If your `ref` returns a cleanup function, React will now skip this step.

In future versions, we will deprecate calling refs with `null` when unmounting components.

Due to the introduction of ref cleanup functions, returning anything else from a `ref` callback will now be rejected by TypeScript. The fix is usually to stop using implicit returns, for example:

```
- <div ref={current => (instance = current)} />

+ <div ref={current => {instance = current}} />
```

The original code returned the instance of the `HTMLDivElement` and TypeScript wouldn’t know if this was *supposed* to be a cleanup function or if you didn’t want to return a cleanup function.

You can codemod this pattern with [`no-implicit-ref-callback-return`](https://github.com/eps1lon/types-react-codemod/#no-implicit-ref-callback-return).

### `useDeferredValue` initial value[](#use-deferred-value-initial-value "Link for this heading")

We’ve added an `initialValue` option to `useDeferredValue`:

```
function Search({deferredValue}) {

  // On initial render the value is ''.

  // Then a re-render is scheduled with the deferredValue.

  const value = useDeferredValue(deferredValue, '');



  return (

    <Results query={value} />

  );

}
```

When initialValue is provided, `useDeferredValue` will return it as `value` for the initial render of the component, and schedules a re-render in the background with the deferredValue returned.

For more, see [`useDeferredValue`](/reference/react/useDeferredValue).

### Support for Document Metadata[](#support-for-metadata-tags "Link for Support for Document Metadata ")

In HTML, document metadata tags like `<title>`, `<link>`, and `<meta>` are reserved for placement in the `<head>` section of the document. In React, the component that decides what metadata is appropriate for the app may be very far from the place where you render the `<head>` or React does not render the `<head>` at all. In the past, these elements would need to be inserted manually in an effect, or by libraries like [`react-helmet`](https://github.com/nfl/react-helmet), and required careful handling when server rendering a React application.

In React 19, we’re adding support for rendering document metadata tags in components natively:

```
function BlogPost({post}) {

  return (

    <article>

      <h1>{post.title}</h1>

      <title>{post.title}</title>

      <meta name="author" content="Josh" />

      <link rel="author" href="https://twitter.com/joshcstory/" />

      <meta name="keywords" content={post.keywords} />

      <p>

        Eee equals em-see-squared...

      </p>

    </article>

  );

}
```

When React renders this component, it will see the `<title>` `<link>` and `<meta>` tags, and automatically hoist them to the `<head>` section of document. By supporting these metadata tags natively, we’re able to ensure they work with client-only apps, streaming SSR, and Server Components.

### Note

#### You may still want a Metadata library[](#you-may-still-want-a-metadata-library "Link for You may still want a Metadata library ")

For simple use cases, rendering Document Metadata as tags may be suitable, but libraries can offer more powerful features like overriding generic metadata with specific metadata based on the current route. These features make it easier for frameworks and libraries like [`react-helmet`](https://github.com/nfl/react-helmet) to support metadata tags, rather than replace them.

For more info, see the docs for [`<title>`](/reference/react-dom/components/title), [`<link>`](/reference/react-dom/components/link), and [`<meta>`](/reference/react-dom/components/meta).

### Support for stylesheets[](#support-for-stylesheets "Link for Support for stylesheets ")

Stylesheets, both externally linked (`<link rel="stylesheet" href="...">`) and inline (`<style>...</style>`), require careful positioning in the DOM due to style precedence rules. Building a stylesheet capability that allows for composability within components is hard, so users often end up either loading all of their styles far from the components that may depend on them, or they use a style library which encapsulates this complexity.

In React 19, we’re addressing this complexity and providing even deeper integration into Concurrent Rendering on the Client and Streaming Rendering on the Server with built in support for stylesheets. If you tell React the `precedence` of your stylesheet it will manage the insertion order of the stylesheet in the DOM and ensure that the stylesheet (if external) is loaded before revealing content that depends on those style rules.

```
function ComponentOne() {

  return (

    <Suspense fallback="loading...">

      <link rel="stylesheet" href="foo" precedence="default" />

      <link rel="stylesheet" href="bar" precedence="high" />

      <article class="foo-class bar-class">

        {...}

      </article>

    </Suspense>

  )

}



function ComponentTwo() {

  return (

    <div>

      <p>{...}</p>

      <link rel="stylesheet" href="baz" precedence="default" />  <-- will be inserted between foo & bar

    </div>

  )

}
```

During Server Side Rendering React will include the stylesheet in the `<head>`, which ensures that the browser will not paint until it has loaded. If the stylesheet is discovered late after we’ve already started streaming, React will ensure that the stylesheet is inserted into the `<head>` on the client before revealing the content of a Suspense boundary that depends on that stylesheet.

During Client Side Rendering React will wait for newly rendered stylesheets to load before committing the render. If you render this component from multiple places within your application React will only include the stylesheet once in the document:

```
function App() {

  return <>

    <ComponentOne />

    ...

    <ComponentOne /> // won't lead to a duplicate stylesheet link in the DOM

  </>

}
```

For users accustomed to loading stylesheets manually this is an opportunity to locate those stylesheets alongside the components that depend on them allowing for better local reasoning and an easier time ensuring you only load the stylesheets that you actually depend on.

Style libraries and style integrations with bundlers can also adopt this new capability so even if you don’t directly render your own stylesheets, you can still benefit as your tools are upgraded to use this feature.

For more details, read the docs for [`<link>`](/reference/react-dom/components/link) and [`<style>`](/reference/react-dom/components/style).

### Support for async scripts[](#support-for-async-scripts "Link for Support for async scripts ")

In HTML normal scripts (`<script src="...">`) and deferred scripts (`<script defer="" src="...">`) load in document order which makes rendering these kinds of scripts deep within your component tree challenging. Async scripts (`<script async="" src="...">`) however will load in arbitrary order.

In React 19 we’ve included better support for async scripts by allowing you to render them anywhere in your component tree, inside the components that actually depend on the script, without having to manage relocating and deduplicating script instances.

```
function MyComponent() {

  return (

    <div>

      <script async={true} src="..." />

      Hello World

    </div>

  )

}



function App() {

  <html>

    <body>

      <MyComponent>

      ...

      <MyComponent> // won't lead to duplicate script in the DOM

    </body>

  </html>

}
```

In all rendering environments, async scripts will be deduplicated so that React will only load and execute the script once even if it is rendered by multiple different components.

In Server Side Rendering, async scripts will be included in the `<head>` and prioritized behind more critical resources that block paint such as stylesheets, fonts, and image preloads.

For more details, read the docs for [`<script>`](/reference/react-dom/components/script).

### Support for preloading resources[](#support-for-preloading-resources "Link for Support for preloading resources ")

During initial document load and on client side updates, telling the Browser about resources that it will likely need to load as early as possible can have a dramatic effect on page performance.

React 19 includes a number of new APIs for loading and preloading Browser resources to make it as easy as possible to build great experiences that aren’t held back by inefficient resource loading.

```
import { prefetchDNS, preconnect, preload, preinit } from 'react-dom'

function MyComponent() {

  preinit('https://.../path/to/some/script.js', {as: 'script' }) // loads and executes this script eagerly

  preload('https://.../path/to/font.woff', { as: 'font' }) // preloads this font

  preload('https://.../path/to/stylesheet.css', { as: 'style' }) // preloads this stylesheet

  prefetchDNS('https://...') // when you may not actually request anything from this host

  preconnect('https://...') // when you will request something but aren't sure what

}
```

```
<!-- the above would result in the following DOM/HTML -->

<html>

  <head>

    <!-- links/scripts are prioritized by their utility to early loading, not call order -->

    <link rel="prefetch-dns" href="https://...">

    <link rel="preconnect" href="https://...">

    <link rel="preload" as="font" href="https://.../path/to/font.woff">

    <link rel="preload" as="style" href="https://.../path/to/stylesheet.css">

    <script async="" src="https://.../path/to/some/script.js"></script>

  </head>

  <body>

    ...

  </body>

</html>
```

These APIs can be used to optimize initial page loads by moving discovery of additional resources like fonts out of stylesheet loading. They can also make client updates faster by prefetching a list of resources used by an anticipated navigation and then eagerly preloading those resources on click or even on hover.

For more details see [Resource Preloading APIs](/reference/react-dom#resource-preloading-apis).

### Compatibility with third-party scripts and extensions[](#compatibility-with-third-party-scripts-and-extensions "Link for Compatibility with third-party scripts and extensions ")

We’ve improved hydration to account for third-party scripts and browser extensions.

When hydrating, if an element that renders on the client doesn’t match the element found in the HTML from the server, React will force a client re-render to fix up the content. Previously, if an element was inserted by third-party scripts or browser extensions, it would trigger a mismatch error and client render.

In React 19, unexpected tags in the `<head>` and `<body>` will be skipped over, avoiding the mismatch errors. If React needs to re-render the entire document due to an unrelated hydration mismatch, it will leave in place stylesheets inserted by third-party scripts and browser extensions.

### Better error reporting[](#error-handling "Link for Better error reporting ")

We improved error handling in React 19 to remove duplication and provide options for handling caught and uncaught errors. For example, when there’s an error in render caught by an Error Boundary, previously React would throw the error twice (once for the original error, then again after failing to automatically recover), and then call `console.error` with info about where the error occurred.

This resulted in three errors for every caught error:

Console

Uncaught Error: hit at Throws at renderWithHooks …

Uncaught Error: hit <-- Duplicate at Throws at renderWithHooks …

The above error occurred in the Throws component: at Throws at ErrorBoundary at App React will try to recreate this component tree from scratch using the error boundary you provided, ErrorBoundary.

In React 19, we log a single error with all the error information included:

Console

Error: hit at Throws at renderWithHooks … The above error occurred in the Throws component: at Throws at ErrorBoundary at App React will try to recreate this component tree from scratch using the error boundary you provided, ErrorBoundary. at ErrorBoundary at App

Additionally, we’ve added two new root options to complement `onRecoverableError`:

* `onCaughtError`: called when React catches an error in an Error Boundary.
* `onUncaughtError`: called when an error is thrown and not caught by an Error Boundary.
* `onRecoverableError`: called when an error is thrown and automatically recovered.

For more info and examples, see the docs for [`createRoot`](/reference/react-dom/client/createRoot) and [`hydrateRoot`](/reference/react-dom/client/hydrateRoot).

### Support for Custom Elements[](#support-for-custom-elements "Link for Support for Custom Elements ")

React 19 adds full support for custom elements and passes all tests on [Custom Elements Everywhere](https://custom-elements-everywhere.com/).

In past versions, using Custom Elements in React has been difficult because React treated unrecognized props as attributes rather than properties. In React 19, we’ve added support for properties that works on the client and during SSR with the following strategy:

* **Server Side Rendering**: props passed to a custom element will render as attributes if their type is a primitive value like `string`, `number`, or the value is `true`. Props with non-primitive types like `object`, `symbol`, `function`, or value `false` will be omitted.
* **Client Side Rendering**: props that match a property on the Custom Element instance will be assigned as properties, otherwise they will be assigned as attributes.

Thanks to [Joey Arhar](https://github.com/josepharhar) for driving the design and implementation of Custom Element support in React.

#### How to upgrade[](#how-to-upgrade "Link for How to upgrade ")

See the [React 19 Upgrade Guide](/blog/2024/04/25/react-19-upgrade-guide) for step-by-step instructions and a full list of breaking and notable changes.

*Note: this post was originally published 04/25/2024 and has been updated to 12/05/2024 with the stable release.*

[PreviousSunsetting Create React App](/blog/2025/02/14/sunsetting-create-react-app)

[NextReact Compiler Beta Release and Roadmap](/blog/2024/10/21/react-compiler-beta-release)

***

----
url: https://18.react.dev/reference/react/startTransition
----

[API Reference](/reference/react)

[APIs](/reference/react/apis)

# startTransition[](#undefined "Link for this heading")

`startTransition` lets you update the state without blocking the UI.

```
startTransition(scope)
```

* [Reference](#reference)
  * [`startTransition(scope)`](#starttransitionscope)
* [Usage](#usage)
  * [Marking a state update as a non-blocking Transition](#marking-a-state-update-as-a-non-blocking-transition)

***

## Reference[](#reference "Link for Reference ")

### `startTransition(scope)`[](#starttransitionscope "Link for this heading")

The `startTransition` function lets you mark a state update as a Transition.

```
import { startTransition } from 'react';



function TabContainer() {

  const [tab, setTab] = useState('about');



  function selectTab(nextTab) {

    startTransition(() => {

      setTab(nextTab);

    });

  }

  // ...

}
```

[See more examples below.](#usage)

#### Parameters[](#parameters "Link for Parameters ")

* `scope`: A function that updates some state by calling one or more [`set` functions.](/reference/react/useState#setstate) React immediately calls `scope` with no arguments and marks all state updates scheduled synchronously during the `scope` function call as Transitions. They will be [non-blocking](/reference/react/useTransition#marking-a-state-update-as-a-non-blocking-transition) and [will not display unwanted loading indicators.](/reference/react/useTransition#preventing-unwanted-loading-indicators)

#### Returns[](#returns "Link for Returns ")

`startTransition` does not return anything.

#### Caveats[](#caveats "Link for Caveats ")

* `startTransition` does not provide a way to track whether a Transition is pending. To show a pending indicator while the Transition is ongoing, you need [`useTransition`](/reference/react/useTransition) instead.

* You can wrap an update into a Transition only if you have access to the `set` function of that state. If you want to start a Transition in response to some prop or a custom Hook return value, try [`useDeferredValue`](/reference/react/useDeferredValue) instead.

* The function you pass to `startTransition` must be synchronous. React immediately executes this function, marking all state updates that happen while it executes as Transitions. If you try to perform more state updates later (for example, in a timeout), they won’t be marked as Transitions.

* A state update marked as a Transition will be interrupted by other state updates. For example, if you update a chart component inside a Transition, but then start typing into an input while the chart is in the middle of a re-render, React will restart the rendering work on the chart component after handling the input state update.

* Transition updates can’t be used to control text inputs.

* If there are multiple ongoing Transitions, React currently batches them together. This is a limitation that will likely be removed in a future release.

***

## Usage[](#usage "Link for Usage ")

### Marking a state update as a non-blocking Transition[](#marking-a-state-update-as-a-non-blocking-transition "Link for Marking a state update as a non-blocking Transition ")

You can mark a state update as a *Transition* by wrapping it in a `startTransition` call:

```
import { startTransition } from 'react';



function TabContainer() {

  const [tab, setTab] = useState('about');



  function selectTab(nextTab) {

    startTransition(() => {

      setTab(nextTab);

    });

  }

  // ...

}
```

***

----
url: https://18.react.dev/learn/installation
----

[Learn React](/learn)

# Installation[](#undefined "Link for this heading")

React has been designed from the start for gradual adoption. You can use as little or as much React as you need. Whether you want to get a taste of React, add some interactivity to an HTML page, or start a complex React-powered app, this section will help you get started.

### In this chapter

* [How to start a new React project](/learn/start-a-new-react-project)
* [How to add React to an existing project](/learn/add-react-to-an-existing-project)
* [How to set up your editor](/learn/editor-setup)
* [How to install React Developer Tools](/learn/react-developer-tools)

## Try React[](#try-react "Link for Try React ")

You don’t need to install anything to play with React. Try editing this sandbox!

[Fork](https://codesandbox.io/api/v1/sandboxes/define?parameters=N4IgZglgNgpgziAXKOAnAxgeggOwCYwAeAdAFYLIjoD2OALjPUiBALYAO1qdABAEowAhujoAaHsB4BlOqggiAstQI8AvjzCpqrHgB0QqISP0BuXTjaduEnukOCGfatV7rN2vQaN0AtHm2Y6FAQjHSm5pZcvPrEmHB0AJ6wcMTocHDhOBEcUTwAguzsGlo6MZgF7JnmNDjxPFouPAC8tvaOznQAFP7oAK6socQA5jB0AKKwA_QAQgkAknid-g1hIACUa2Y4K8SG-DCoSzg8PAA8MnKKyjAAfOYnJ6cVPJh3x2eYF_J0SgRvmyBRCw4NNcIJUAkkGBBFA4DBVED2MIANaCEZkOC0JCgGoMJiIEDAe6eHCCAb6RCeewiYgEABu-lExP0dIOcAgtApngADMRedzGcyQKxBLgufo4hhsPsSORBe99HA7BB2HQMkgJMSToq6ODVpTlt4fEq5Kq4Dx4nr5Q9PAAjXrQPDirzCXwmlVqnj2x3Wh76BjxZ3Ut3Ks08AO8Hw-Rh0prkfysX3akAwUgwYwaw2u42hz2p9OrYkIoUEdiMAg4dAhdWUonvZPB50APQAjAAOPl8pNUo0J5vtzsCwFanvZ91m5sAVkH-iLTIVIHpABEYGX9pXq1zgKpzKpAcDQaSIVCYXCESB2L1bcEsLgCCQABZ0VhQbFUWh4ujMU4AQiXAHkAGEABUAE0AAUxh4J8XzeU4YKgHgoEEHAhiafRGH0OCHyEPA3keAZdVsB9wThOh0JAABVYCADEfDbLDiVOQjBB4UkBgoukQgAdysVZbA_UIKO4iA8DoB8mnpeQYB8ESxIfcRcAgOgIBhHMYRgJoWy7EB8LOFS6FgG4l2oPopjoU5MAMozzEsnDBDw2zbWUBI9NOPAIDpHhRIolYsMsjy6TgzBnLwVzbMwBCbn3CAQTBY9EGhWF4SBNAsAqDE31xUJmDAXpKxU2geAAcUMUZcCGTpJHYmA1DWTV3kMOhelQY54JbG4AAkYCgKBqHEYAatUOyOq2HcshwIg-J4AhoV6KBeDygqOWOCpOnqusTialq2tKmBytQtiyU0_RuK4KAnRAF43nGmK4qPSFEtPFKQDSuJEmSVJ0iywT8RAAAqBqTmcwhjQgAAvCrKWc1ACFQHwQbG8xzFChIgY0D8fGhVhoASSk4BQuBjQOCAwC2E4RVQIZcEpAAmbl2EIcmeCRPAPNQyluSRiaHxbdHKepnAfDoah2E55mwEx9lwZgOnacZ7nzAfWn-fBQXhdF8XiUl-gwZlumGaZ3dkZwB8AGZVap3ANbFngue1qWIdlnh2wV42eYAFkt9WRdt-33h1t0ncpFsADY3Zwcalcnb3rd9rWA8d_WXY9iOo9N0PY6F-O7YlpPnZbeWjcjk2aBUTaMd16WC-IWmYFYRWcHm9HWfZoYfFwYJJuNXVuANtOTbuw9wUepKz3PBgOGQhhmDsIQGB8YMfEEQoQFUIA\&query=file%3D%252Fsrc%252FApp.js%26utm_medium%3Dsandpack\&environment=create-react-app "Open in CodeSandbox")

```
function Greeting({ name }) {
  return <h1>Hello, {name}</h1>;
}

export default function App() {
  return <Greeting name="world" />
}
```

You can edit it directly or open it in a new tab by pressing the “Fork” button in the upper right corner.

Most pages in the React documentation contain sandboxes like this. Outside of the React documentation, there are many online sandboxes that support React: for example, [CodeSandbox](https://codesandbox.io/s/new), [StackBlitz](https://stackblitz.com/fork/react), or [CodePen.](https://codepen.io/pen?template=QWYVwWN)

### Try React locally[](#try-react-locally "Link for Try React locally ")

To try React locally on your computer, [download this HTML page.](https://gist.githubusercontent.com/gaearon/0275b1e1518599bbeafcde4722e79ed1/raw/db72dcbf3384ee1708c4a07d3be79860db04bff0/example.html) Open it in your editor and in your browser!

## Start a new React project[](#start-a-new-react-project "Link for Start a new React project ")

If you want to build an app or a website fully with React, [start a new React project.](/learn/start-a-new-react-project)

## Add React to an existing project[](#add-react-to-an-existing-project "Link for Add React to an existing project ")

If want to try using React in your existing app or a website, [add React to an existing project.](/learn/add-react-to-an-existing-project)

## Next steps[](#next-steps "Link for Next steps ")

Head to the [Quick Start](/learn) guide for a tour of the most important React concepts you will encounter every day.

[PreviousThinking in React](/learn/thinking-in-react)

[NextStart a New React Project](/learn/start-a-new-react-project)

***

----
url: https://legacy.reactjs.org/blog/2017/07/26/error-handling-in-react-16.html
----

July 26, 2017 by [Dan Abramov](https://twitter.com/dan_abramov)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

As React 16 release is getting closer, we would like to announce a few changes to how React handles JavaScript errors inside components. These changes are included in React 16 beta versions, and will be a part of React 16.

**By the way, [we just released the first beta of React 16 for you to try!](https://github.com/facebook/react/issues/10294)**

## [](#behavior-in-react-15-and-earlier)Behavior in React 15 and Earlier

In the past, JavaScript errors inside components used to corrupt React’s internal state and cause it to [emit](https://github.com/facebook/react/issues/4026) [cryptic](https://github.com/facebook/react/issues/6895) [errors](https://github.com/facebook/react/issues/8579) on next renders. These errors were always caused by an earlier error in the application code, but React did not provide a way to handle them gracefully in components, and could not recover from them.

## [](#introducing-error-boundaries)Introducing Error Boundaries

A JavaScript error in a part of the UI shouldn’t break the whole app. To solve this problem for React users, React 16 introduces a new concept of an “error boundary”.

Error boundaries are React components that **catch JavaScript errors anywhere in their child component tree, log those errors, and display a fallback UI** instead of the component tree that crashed. Error boundaries catch errors during rendering, in lifecycle methods, and in constructors of the whole tree below them.

A class component becomes an error boundary if it defines a new lifecycle method called `componentDidCatch(error, info)`:

```
class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  componentDidCatch(error, info) {    // Display fallback UI    this.setState({ hasError: true });    // You can also log the error to an error reporting service    logErrorToMyService(error, info);  }
  render() {
    if (this.state.hasError) {      // You can render any custom fallback UI      return <h1>Something went wrong.</h1>;    }    return this.props.children;
  }
}
```

Then you can use it as a regular component:

```
<ErrorBoundary>
  <MyWidget />
</ErrorBoundary>
```

The `componentDidCatch()` method works like a JavaScript `catch {}` block, but for components. Only class components can be error boundaries. In practice, most of the time you’ll want to declare an error boundary component once and use it throughout your application.

Note that **error boundaries only catch errors in the components below them in the tree**. An error boundary can’t catch an error within itself. If an error boundary fails trying to render the error message, the error will propagate to the closest error boundary above it. This, too, is similar to how `catch {}` block works in JavaScript.

## [](#live-demo)Live Demo

Check out [this example of declaring and using an error boundary](https://codepen.io/gaearon/pen/wqvxGa?editors=0010) with [React 16 beta](https://github.com/facebook/react/issues/10294).

## [](#where-to-place-error-boundaries)Where to Place Error Boundaries

The granularity of error boundaries is up to you. You may wrap top-level route components to display a “Something went wrong” message to the user, just like server-side frameworks often handle crashes. You may also wrap individual widgets in an error boundary to protect them from crashing the rest of the application.

If you don’t use Create React App, you can add [this plugin](https://www.npmjs.com/package/babel-plugin-transform-react-jsx-source) manually to your Babel configuration. Note that it’s intended only for development and **must be disabled in production**.

## [](#why-not-use-try--catch)Why Not Use `try` / `catch`?

`try` / `catch` is great but it only works for imperative code:

```
try {
  showButton();
} catch (error) {
  // ...
}
```

However, React components are declarative and specify *what* should be rendered:

```
<Button />
```

Error boundaries preserve the declarative nature of React, and behave as you would expect. For example, even if an error occurs in a `componentDidUpdate` method caused by a `setState` somewhere deep in the tree, it will still correctly propagate to the closest error boundary.

## [](#naming-changes-from-react-15)Naming Changes from React 15

React 15 included a very limited support for error boundaries under a different method name: `unstable_handleError`. This method no longer works, and you will need to change it to `componentDidCatch` in your code starting from the first 16 beta release.

For this change, we’ve provided a [codemod](https://github.com/reactjs/react-codemod#error-boundaries) to automatically migrate your code.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2017-07-26-error-handling-in-react-16.md)

----
url: https://react.dev/reference/react/useTransition
----

[API Reference](/reference/react)

[Hooks](/reference/react/hooks)

# useTransition[](#undefined "Link for this heading")

`useTransition` is a React Hook that lets you render a part of the UI in the background.

```
const [isPending, startTransition] = useTransition()
```

* [Reference](#reference)

  * [`useTransition()`](#usetransition)
  * [`startTransition(action)`](#starttransition)

* [Usage](#usage)

  * [Perform non-blocking updates with Actions](#perform-non-blocking-updates-with-actions)
  * [Exposing `action` prop from components](#exposing-action-props-from-components)
  * [Displaying a pending visual state](#displaying-a-pending-visual-state)
  * [Preventing unwanted loading indicators](#preventing-unwanted-loading-indicators)
  * [Building a Suspense-enabled router](#building-a-suspense-enabled-router)
  * [Displaying an error to users with an error boundary](#displaying-an-error-to-users-with-error-boundary)

* [Troubleshooting](#troubleshooting)

  * [Updating an input in a Transition doesn’t work](#updating-an-input-in-a-transition-doesnt-work)
  * [React doesn’t treat my state update as a Transition](#react-doesnt-treat-my-state-update-as-a-transition)
  * [React doesn’t treat my state update after `await` as a Transition](#react-doesnt-treat-my-state-update-after-await-as-a-transition)
  * [I want to call `useTransition` from outside a component](#i-want-to-call-usetransition-from-outside-a-component)
  * [The function I pass to `startTransition` executes immediately](#the-function-i-pass-to-starttransition-executes-immediately)
  * [My state updates in Transitions are out of order](#my-state-updates-in-transitions-are-out-of-order)

***

## Reference[](#reference "Link for Reference ")

### `useTransition()`[](#usetransition "Link for this heading")

Call `useTransition` at the top level of your component to mark some state updates as Transitions.

```
import { useTransition } from 'react';



function TabContainer() {

  const [isPending, startTransition] = useTransition();

  // ...

}
```

[See more examples below.](#usage)

#### Parameters[](#parameters "Link for Parameters ")

`useTransition` does not take any parameters.

#### Returns[](#returns "Link for Returns ")

`useTransition` returns an array with exactly two items:

1. The `isPending` flag that tells you whether there is a pending Transition.
2. The [`startTransition` function](#starttransition) that lets you mark updates as a Transition.

***

### `startTransition(action)`[](#starttransition "Link for this heading")

The `startTransition` function returned by `useTransition` lets you mark an update as a Transition.

```
function TabContainer() {

  const [isPending, startTransition] = useTransition();

  const [tab, setTab] = useState('about');



  function selectTab(nextTab) {

    startTransition(() => {

      setTab(nextTab);

    });

  }

  // ...

}
```

### Note

#### Functions called in `startTransition` are called “Actions”.[](#functions-called-in-starttransition-are-called-actions "Link for this heading")

The function passed to `startTransition` is called an “Action”. By convention, any callback called inside `startTransition` (such as a callback prop) should be named `action` or include the “Action” suffix:

```
function SubmitButton({ submitAction }) {

  const [isPending, startTransition] = useTransition();



  return (

    <button

      disabled={isPending}

      onClick={() => {

        startTransition(async () => {

          await submitAction();

        });

      }}

    >

      Submit

    </button>

  );

}
```

#### Parameters[](#starttransition-parameters "Link for Parameters ")

* `action`: A function that updates some state by calling one or more [`set` functions](/reference/react/useState#setstate). React calls `action` immediately with no parameters and marks all state updates scheduled synchronously during the `action` function call as Transitions. Any async calls that are awaited in the `action` will be included in the Transition, but currently require wrapping any `set` functions after the `await` in an additional `startTransition` (see [Troubleshooting](#react-doesnt-treat-my-state-update-after-await-as-a-transition)). State updates marked as Transitions will be [non-blocking](#perform-non-blocking-updates-with-actions) and [will not display unwanted loading indicators](#preventing-unwanted-loading-indicators).

#### Returns[](#starttransition-returns "Link for Returns ")

`startTransition` does not return anything.

#### Caveats[](#starttransition-caveats "Link for Caveats ")

* `useTransition` is a Hook, so it can only be called inside components or custom Hooks. If you need to start a Transition somewhere else (for example, from a data library), call the standalone [`startTransition`](/reference/react/startTransition) instead.

* You can wrap an update into a Transition only if you have access to the `set` function of that state. If you want to start a Transition in response to some prop or a custom Hook value, try [`useDeferredValue`](/reference/react/useDeferredValue) instead.

* The function you pass to `startTransition` is called immediately, marking all state updates that happen while it executes as Transitions. If you try to perform state updates in a `setTimeout`, for example, they won’t be marked as Transitions.

* You must wrap any state updates after any async requests in another `startTransition` to mark them as Transitions. This is a known limitation that we will fix in the future (see [Troubleshooting](#react-doesnt-treat-my-state-update-after-await-as-a-transition)).

* The `startTransition` function has a stable identity, so you will often see it omitted from Effect dependencies, but including it will not cause the Effect to fire. If the linter lets you omit a dependency without errors, it is safe to do. [Learn more about removing Effect dependencies.](/learn/removing-effect-dependencies#move-dynamic-objects-and-functions-inside-your-effect)

* A state update marked as a Transition will be interrupted by other state updates. For example, if you update a chart component inside a Transition, but then start typing into an input while the chart is in the middle of a re-render, React will restart the rendering work on the chart component after handling the input update.

* Transition updates can’t be used to control text inputs.

* If there are multiple ongoing Transitions, React currently batches them together. This is a limitation that may be removed in a future release.

## Usage[](#usage "Link for Usage ")

### Perform non-blocking updates with Actions[](#perform-non-blocking-updates-with-actions "Link for Perform non-blocking updates with Actions ")

Call `useTransition` at the top of your component to create Actions, and access the pending state:

```
import {useState, useTransition} from 'react';



function CheckoutForm() {

  const [isPending, startTransition] = useTransition();

  // ...

}
```

`useTransition` returns an array with exactly two items:

1. The `isPending` flag that tells you whether there is a pending Transition.
2. The `startTransition` function that lets you create an Action.

To start a Transition, pass a function to `startTransition` like this:

```
import {useState, useTransition} from 'react';

import {updateQuantity} from './api';



function CheckoutForm() {

  const [isPending, startTransition] = useTransition();

  const [quantity, setQuantity] = useState(1);



  function onSubmit(newQuantity) {

    startTransition(async function () {

      const savedQuantity = await updateQuantity(newQuantity);

      startTransition(() => {

        setQuantity(savedQuantity);

      });

    });

  }

  // ...

}
```

The function passed to `startTransition` is called the “Action”. You can update state and (optionally) perform side effects within an Action, and the work will be done in the background without blocking user interactions on the page. A Transition can include multiple Actions, and while a Transition is in progress, your UI stays responsive. For example, if the user clicks a tab but then changes their mind and clicks another tab, the second click will be immediately handled without waiting for the first update to finish.

To give the user feedback about in-progress Transitions, the `isPending` state switches to `true` at the first call to `startTransition`, and stays `true` until all Actions complete and the final state is shown to the user. Transitions ensure side effects in Actions to complete in order to [prevent unwanted loading indicators](#preventing-unwanted-loading-indicators), and you can provide immediate feedback while the Transition is in progress with `useOptimistic`.

#### The difference between Actions and regular event handling[](#examples "Link for The difference between Actions and regular event handling")

#### Example 1 of 2:Updating the quantity in an Action[](#updating-the-quantity-in-an-action "Link for this heading")

In this example, the `updateQuantity` function simulates a request to the server to update the item’s quantity in the cart. This function is *artificially slowed down* so that it takes at least a second to complete the request.

Update the quantity multiple times quickly. Notice that the pending “Total” state is shown while any requests are in progress, and the “Total” updates only after the final request is complete. Because the update is in an Action, the “quantity” can continue to be updated while the request is in progress.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useTransition } from "react";
import { updateQuantity } from "./api";
import Item from "./Item";
import Total from "./Total";

export default function App({}) {
  const [quantity, setQuantity] = useState(1);
  const [isPending, startTransition] = useTransition();

  const updateQuantityAction = async newQuantity => {
    // To access the pending state of a transition,
    // call startTransition again.
    startTransition(async () => {
      const savedQuantity = await updateQuantity(newQuantity);
      startTransition(() => {
        setQuantity(savedQuantity);
      });
    });
  };

  return (
    <div>
      <h1>Checkout</h1>
      <Item action={updateQuantityAction}/>
      <hr />
      <Total quantity={quantity} isPending={isPending} />
    </div>
  );
}
```

This is a basic example to demonstrate how Actions work, but this example does not handle requests completing out of order. When updating the quantity multiple times, it’s possible for the previous requests to finish after later requests causing the quantity to update out of order. This is a known limitation that we will fix in the future (see [Troubleshooting](#my-state-updates-in-transitions-are-out-of-order) below).

For common use cases, React provides built-in abstractions such as:

* [`useActionState`](/reference/react/useActionState)
* [`<form>` actions](/reference/react-dom/components/form)
* [Server Functions](/reference/rsc/server-functions)

These solutions handle request ordering for you. When using Transitions to build your own custom hooks or libraries that manage async state transitions, you have greater control over the request ordering, but you must handle it yourself.

***

### Exposing `action` prop from components[](#exposing-action-props-from-components "Link for this heading")

You can expose an `action` prop from a component to allow a parent to call an Action.

For example, this `TabButton` component wraps its `onClick` logic in an `action` prop:

```
export default function TabButton({ action, children, isActive }) {

  const [isPending, startTransition] = useTransition();

  if (isActive) {

    return <b>{children}</b>

  }

  return (

    <button onClick={() => {

      startTransition(async () => {

        // await the action that's passed in.

        // This allows it to be either sync or async.

        await action();

      });

    }}>

      {children}

    </button>

  );

}
```

Because the parent component updates its state inside the `action`, that state update gets marked as a Transition. This means you can click on “Posts” and then immediately click “Contact” and it does not block user interactions:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useTransition } from 'react';

export default function TabButton({ action, children, isActive }) {
  const [isPending, startTransition] = useTransition();
  if (isActive) {
    return <b>{children}</b>
  }
  if (isPending) {
    return <b className="pending">{children}</b>;
  }
  return (
    <button onClick={async () => {
      startTransition(async () => {
        // await the action that's passed in.
        // This allows it to be either sync or async.
        await action();
      });
    }}>
      {children}
    </button>
  );
}
```

### Note

When exposing an `action` prop from a component, you should `await` it inside the transition.

This allows the `action` callback to be either synchronous or asynchronous without requiring an additional `startTransition` to wrap the `await` in the action.

***

### Displaying a pending visual state[](#displaying-a-pending-visual-state "Link for Displaying a pending visual state ")

You can use the `isPending` boolean value returned by `useTransition` to indicate to the user that a Transition is in progress. For example, the tab button can have a special “pending” visual state:

```
function TabButton({ action, children, isActive }) {

  const [isPending, startTransition] = useTransition();

  // ...

  if (isPending) {

    return <b className="pending">{children}</b>;

  }

  // ...
```

Notice how clicking “Posts” now feels more responsive because the tab button itself updates right away:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useTransition } from 'react';

export default function TabButton({ action, children, isActive }) {
  const [isPending, startTransition] = useTransition();
  if (isActive) {
    return <b>{children}</b>
  }
  if (isPending) {
    return <b className="pending">{children}</b>;
  }
  return (
    <button onClick={() => {
      startTransition(async () => {
        await action();
      });
    }}>
      {children}
    </button>
  );
}
```

***

### Preventing unwanted loading indicators[](#preventing-unwanted-loading-indicators "Link for Preventing unwanted loading indicators ")

In this example, the `PostsTab` component fetches some data using [use](/reference/react/use). When you click the “Posts” tab, the `PostsTab` component *suspends*, causing the closest loading fallback to appear:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { Suspense, useState } from 'react';
import TabButton from './TabButton.js';
import AboutTab from './AboutTab.js';
import PostsTab from './PostsTab.js';
import ContactTab from './ContactTab.js';

export default function TabContainer() {
  const [tab, setTab] = useState('about');
  return (
    <Suspense fallback={<h1>🌀 Loading...</h1>}>
      <TabButton
        isActive={tab === 'about'}
        action={() => setTab('about')}
      >
        About
      </TabButton>
      <TabButton
        isActive={tab === 'posts'}
        action={() => setTab('posts')}
      >
        Posts
      </TabButton>
      <TabButton
        isActive={tab === 'contact'}
        action={() => setTab('contact')}
      >
        Contact
      </TabButton>
      <hr />
      {tab === 'about' && <AboutTab />}
      {tab === 'posts' && <PostsTab />}
      {tab === 'contact' && <ContactTab />}
    </Suspense>
  );
}
```

Hiding the entire tab container to show a loading indicator leads to a jarring user experience. If you add `useTransition` to `TabButton`, you can instead display the pending state in the tab button instead.

Notice that clicking “Posts” no longer replaces the entire tab container with a spinner:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useTransition } from 'react';

export default function TabButton({ action, children, isActive }) {
  const [isPending, startTransition] = useTransition();
  if (isActive) {
    return <b>{children}</b>
  }
  if (isPending) {
    return <b className="pending">{children}</b>;
  }
  return (
    <button onClick={() => {
      startTransition(async () => {
        await action();
      });
    }}>
      {children}
    </button>
  );
}
```

[Read more about using Transitions with Suspense.](/reference/react/Suspense#preventing-already-revealed-content-from-hiding)

### Note

Transitions only “wait” long enough to avoid hiding *already revealed* content (like the tab container). If the Posts tab had a [nested `<Suspense>` boundary,](/reference/react/Suspense#revealing-nested-content-as-it-loads) the Transition would not “wait” for it.

***

### Building a Suspense-enabled router[](#building-a-suspense-enabled-router "Link for Building a Suspense-enabled router ")

If you’re building a React framework or a router, we recommend marking page navigations as Transitions.

```
function Router() {

  const [page, setPage] = useState('/');

  const [isPending, startTransition] = useTransition();



  function navigate(url) {

    startTransition(() => {

      setPage(url);

    });

  }

  // ...
```

This is recommended for three reasons:

* [Transitions are interruptible,](#perform-non-blocking-updates-with-actions) which lets the user click away without waiting for the re-render to complete.
* [Transitions prevent unwanted loading indicators,](#preventing-unwanted-loading-indicators) which lets the user avoid jarring jumps on navigation.
* [Transitions wait for all pending actions](#perform-non-blocking-updates-with-actions) which lets the user wait for side effects to complete before the new page is shown.

Here is a simplified router example using Transitions for navigations.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { Suspense, useState, useTransition } from 'react';
import IndexPage from './IndexPage.js';
import ArtistPage from './ArtistPage.js';
import Layout from './Layout.js';

export default function App() {
  return (
    <Suspense fallback={<BigSpinner />}>
      <Router />
    </Suspense>
  );
}

function Router() {
  const [page, setPage] = useState('/');
  const [isPending, startTransition] = useTransition();

  function navigate(url) {
    startTransition(() => {
      setPage(url);
    });
  }

  let content;
  if (page === '/') {
    content = (
      <IndexPage navigate={navigate} />
    );
  } else if (page === '/the-beatles') {
    content = (
      <ArtistPage
        artist={{
          id: 'the-beatles',
          name: 'The Beatles',
        }}
      />
    );
  }
  return (
    <Layout isPending={isPending}>
      {content}
    </Layout>
  );
}

function BigSpinner() {
  return <h2>🌀 Loading...</h2>;
}
```

### Note

[Suspense-enabled](/reference/react/Suspense) routers are expected to wrap the navigation updates into Transitions by default.

***

### Displaying an error to users with an error boundary[](#displaying-an-error-to-users-with-error-boundary "Link for Displaying an error to users with an error boundary ")

If a function passed to `startTransition` throws an error, you can display an error to your user with an [error boundary](/reference/react/Component#catching-rendering-errors-with-an-error-boundary). To use an error boundary, wrap the component where you are calling the `useTransition` in an error boundary. Once the function passed to `startTransition` errors, the fallback for the error boundary will be displayed.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useTransition } from "react";
import { ErrorBoundary } from "react-error-boundary";

export function AddCommentContainer() {
  return (
    <ErrorBoundary fallback={<p>⚠️Something went wrong</p>}>
      <AddCommentButton />
    </ErrorBoundary>
  );
}

function addComment(comment) {
  // For demonstration purposes to show Error Boundary
  if (comment == null) {
    throw new Error("Example Error: An error thrown to trigger error boundary");
  }
}

function AddCommentButton() {
  const [pending, startTransition] = useTransition();

  return (
    <button
      disabled={pending}
      onClick={() => {
        startTransition(() => {
          // Intentionally not passing a comment
          // so error gets thrown
          addComment();
        });
      }}
    >
      Add comment
    </button>
  );
}
```

***

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### Updating an input in a Transition doesn’t work[](#updating-an-input-in-a-transition-doesnt-work "Link for Updating an input in a Transition doesn’t work ")

You can’t use a Transition for a state variable that controls an input:

```
const [text, setText] = useState('');

// ...

function handleChange(e) {

  // ❌ Can't use Transitions for controlled input state

  startTransition(() => {

    setText(e.target.value);

  });

}

// ...

return <input value={text} onChange={handleChange} />;
```

This is because Transitions are non-blocking, but updating an input in response to the change event should happen synchronously. If you want to run a Transition in response to typing, you have two options:

1. You can declare two separate state variables: one for the input state (which always updates synchronously), and one that you will update in a Transition. This lets you control the input using the synchronous state, and pass the Transition state variable (which will “lag behind” the input) to the rest of your rendering logic.
2. Alternatively, you can have one state variable, and add [`useDeferredValue`](/reference/react/useDeferredValue) which will “lag behind” the real value. It will trigger non-blocking re-renders to “catch up” with the new value automatically.

***

### React doesn’t treat my state update as a Transition[](#react-doesnt-treat-my-state-update-as-a-transition "Link for React doesn’t treat my state update as a Transition ")

When you wrap a state update in a Transition, make sure that it happens *during* the `startTransition` call:

```
startTransition(() => {

  // ✅ Setting state *during* startTransition call

  setPage('/about');

});
```

The function you pass to `startTransition` must be synchronous. You can’t mark an update as a Transition like this:

```
startTransition(() => {

  // ❌ Setting state *after* startTransition call

  setTimeout(() => {

    setPage('/about');

  }, 1000);

});
```

Instead, you could do this:

```
setTimeout(() => {

  startTransition(() => {

    // ✅ Setting state *during* startTransition call

    setPage('/about');

  });

}, 1000);
```

***

### React doesn’t treat my state update after `await` as a Transition[](#react-doesnt-treat-my-state-update-after-await-as-a-transition "Link for this heading")

When you use `await` inside a `startTransition` function, the state updates that happen after the `await` are not marked as Transitions. You must wrap state updates after each `await` in a `startTransition` call:

```
startTransition(async () => {

  await someAsyncFunction();

  // ❌ Not using startTransition after await

  setPage('/about');

});
```

However, this works instead:

```
startTransition(async () => {

  await someAsyncFunction();

  // ✅ Using startTransition *after* await

  startTransition(() => {

    setPage('/about');

  });

});
```

This is a JavaScript limitation due to React losing the scope of the async context. In the future, when [AsyncContext](https://github.com/tc39/proposal-async-context) is available, this limitation will be removed.

***

### I want to call `useTransition` from outside a component[](#i-want-to-call-usetransition-from-outside-a-component "Link for this heading")

You can’t call `useTransition` outside a component because it’s a Hook. In this case, use the standalone [`startTransition`](/reference/react/startTransition) method instead. It works the same way, but it doesn’t provide the `isPending` indicator.

***

### The function I pass to `startTransition` executes immediately[](#the-function-i-pass-to-starttransition-executes-immediately "Link for this heading")

If you run this code, it will print 1, 2, 3:

```
console.log(1);

startTransition(() => {

  console.log(2);

  setPage('/about');

});

console.log(3);
```

**It is expected to print 1, 2, 3.** The function you pass to `startTransition` does not get delayed. Unlike with the browser `setTimeout`, it does not run the callback later. React executes your function immediately, but any state updates scheduled *while it is running* are marked as Transitions. You can imagine that it works like this:

```
// A simplified version of how React works



let isInsideTransition = false;



function startTransition(scope) {

  isInsideTransition = true;

  scope();

  isInsideTransition = false;

}



function setState() {

  if (isInsideTransition) {

    // ... schedule a Transition state update ...

  } else {

    // ... schedule an urgent state update ...

  }

}
```

### My state updates in Transitions are out of order[](#my-state-updates-in-transitions-are-out-of-order "Link for My state updates in Transitions are out of order ")

If you `await` inside `startTransition`, you might see the updates happen out of order.

In this example, the `updateQuantity` function simulates a request to the server to update the item’s quantity in the cart. This function *artificially returns every other request after the previous* to simulate race conditions for network requests.

Try updating the quantity once, then update it quickly multiple times. You might see the incorrect total:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useTransition } from "react";
import { updateQuantity } from "./api";
import Item from "./Item";
import Total from "./Total";

export default function App({}) {
  const [quantity, setQuantity] = useState(1);
  const [isPending, startTransition] = useTransition();
  // Store the actual quantity in separate state to show the mismatch.
  const [clientQuantity, setClientQuantity] = useState(1);

  const updateQuantityAction = newQuantity => {
    setClientQuantity(newQuantity);

    // Access the pending state of the transition,
    // by wrapping in startTransition again.
    startTransition(async () => {
      const savedQuantity = await updateQuantity(newQuantity);
      startTransition(() => {
        setQuantity(savedQuantity);
      });
    });
  };

  return (
    <div>
      <h1>Checkout</h1>
      <Item action={updateQuantityAction}/>
      <hr />
      <Total clientQuantity={clientQuantity} savedQuantity={quantity} isPending={isPending} />
    </div>
  );
}
```

When clicking multiple times, it’s possible for previous requests to finish after later requests. When this happens, React currently has no way to know the intended order. This is because the updates are scheduled asynchronously, and React loses context of the order across the async boundary.

This is expected, because Actions within a Transition do not guarantee execution order. For common use cases, React provides higher-level abstractions like [`useActionState`](/reference/react/useActionState) and [`<form>` actions](/reference/react-dom/components/form) that handle ordering for you. For advanced use cases, you’ll need to implement your own queuing and abort logic to handle this.

Example of `useActionState` handling execution order:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useActionState } from "react";
import { updateQuantity } from "./api";
import Item from "./Item";
import Total from "./Total";

export default function App({}) {
  // Store the actual quantity in separate state to show the mismatch.
  const [clientQuantity, setClientQuantity] = useState(1);
  const [quantity, updateQuantityAction, isPending] = useActionState(
    async (prevState, payload) => {
      setClientQuantity(payload);
      const savedQuantity = await updateQuantity(payload);
      return savedQuantity; // Return the new quantity to update the state
    },
    1 // Initial quantity
  );

  return (
    <div>
      <h1>Checkout</h1>
      <Item action={updateQuantityAction}/>
      <hr />
      <Total clientQuantity={clientQuantity} savedQuantity={quantity} isPending={isPending} />
    </div>
  );
}
```

[PrevioususeSyncExternalStore](/reference/react/useSyncExternalStore)

[NextComponents](/reference/react/components)

***

----
url: https://react.dev/reference/react-dom/preconnect
----

[API Reference](/reference/react)

[APIs](/reference/react-dom)

# preconnect[](#undefined "Link for this heading")

`preconnect` lets you eagerly connect to a server that you expect to load resources from.

```
preconnect("https://example.com");
```

* [Reference](#reference)
  * [`preconnect(href)`](#preconnect)

* [Usage](#usage)

  * [Preconnecting when rendering](#preconnecting-when-rendering)
  * [Preconnecting in an event handler](#preconnecting-in-an-event-handler)

***

## Reference[](#reference "Link for Reference ")

### `preconnect(href)`[](#preconnect "Link for this heading")

To preconnect to a host, call the `preconnect` function from `react-dom`.

```
import { preconnect } from 'react-dom';



function AppRoot() {

  preconnect("https://example.com");

  // ...

}
```

***

## Usage[](#usage "Link for Usage ")

### Preconnecting when rendering[](#preconnecting-when-rendering "Link for Preconnecting when rendering ")

Call `preconnect` when rendering a component if you know that its children will load external resources from that host.

```
import { preconnect } from 'react-dom';



function AppRoot() {

  preconnect("https://example.com");

  return ...;

}
```

### Preconnecting in an event handler[](#preconnecting-in-an-event-handler "Link for Preconnecting in an event handler ")

Call `preconnect` in an event handler before transitioning to a page or state where external resources will be needed. This gets the process started earlier than if you call it during the rendering of the new page or state.

```
import { preconnect } from 'react-dom';



function CallToAction() {

  const onClick = () => {

    preconnect('http://example.com');

    startWizard();

  }

  return (

    <button onClick={onClick}>Start Wizard</button>

  );

}
```

[PreviousflushSync](/reference/react-dom/flushSync)

[NextprefetchDNS](/reference/react-dom/prefetchDNS)

***

----
url: https://react.dev/reference/react-dom/client/hydrateRoot
----

[API Reference](/reference/react)

[Client APIs](/reference/react-dom/client)

# hydrateRoot[](#undefined "Link for this heading")

`hydrateRoot` lets you display React components inside a browser DOM node whose HTML content was previously generated by [`react-dom/server`.](/reference/react-dom/server)

```
const root = hydrateRoot(domNode, reactNode, options?)
```

  * [Error logging in production](#error-logging-in-production)

* [Troubleshooting](#troubleshooting)
  * [I’m getting an error: “You passed a second argument to root.render”](#im-getting-an-error-you-passed-a-second-argument-to-root-render)

***

## Reference[](#reference "Link for Reference ")

### `hydrateRoot(domNode, reactNode, options?)`[](#hydrateroot "Link for this heading")

Call `hydrateRoot` to “attach” React to existing HTML that was already rendered by React in a server environment.

```
import { hydrateRoot } from 'react-dom/client';



const domNode = document.getElementById('root');

const root = hydrateRoot(domNode, reactNode);
```

React will attach to the HTML that exists inside the `domNode`, and take over managing the DOM inside it. An app fully built with React will usually only have one `hydrateRoot` call with its root component.

[See more examples below.](#usage)

#### Parameters[](#parameters "Link for Parameters ")

* `domNode`: A [DOM element](https://developer.mozilla.org/en-US/docs/Web/API/Element) that was rendered as the root element on the server.

* `reactNode`: The “React node” used to render the existing HTML. This will usually be a piece of JSX like `<App />` which was rendered with a `ReactDOM Server` method such as `renderToPipeableStream(<App />)`.

* **optional** `options`: An object with options for this React root.

  * **optional** `onCaughtError`: Callback called when React catches an error in an Error Boundary. Called with the `error` caught by the Error Boundary, and an `errorInfo` object containing the `componentStack`.
  * **optional** `onUncaughtError`: Callback called when an error is thrown and not caught by an Error Boundary. Called with the `error` that was thrown and an `errorInfo` object containing the `componentStack`.

***

### `root.render(reactNode)`[](#root-render "Link for this heading")

Call `root.render` to update a React component inside a hydrated React root for a browser DOM element.

```
root.render(<App />);
```

***

### `root.unmount()`[](#root-unmount "Link for this heading")

Call `root.unmount` to destroy a rendered tree inside a React root.

```
root.unmount();
```

***

## Usage[](#usage "Link for Usage ")

### Hydrating server-rendered HTML[](#hydrating-server-rendered-html "Link for Hydrating server-rendered HTML ")

If your app’s HTML was generated by [`react-dom/server`](/reference/react-dom/client/createRoot), you need to *hydrate* it on the client.

```
import { hydrateRoot } from 'react-dom/client';



hydrateRoot(document.getElementById('root'), <App />);
```

This will hydrate the server HTML inside the browser DOM node with the React component for your app. Usually, you will do it once at startup. If you use a framework, it might do this behind the scenes for you.

To hydrate your app, React will “attach” your components’ logic to the initial generated HTML from the server. Hydration turns the initial HTML snapshot from the server into a fully interactive app that runs in the browser.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import './styles.css';
import { hydrateRoot } from 'react-dom/client';
import App from './App.js';

hydrateRoot(
  document.getElementById('root'),
  <App />
);
```

***

### Hydrating an entire document[](#hydrating-an-entire-document "Link for Hydrating an entire document ")

Apps fully built with React can render the entire document as JSX, including the [`<html>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/html) tag:

```
function App() {

  return (

    <html>

      <head>

        <meta charSet="utf-8" />

        <meta name="viewport" content="width=device-width, initial-scale=1" />

        <link rel="stylesheet" href="/styles.css"></link>

        <title>My app</title>

      </head>

      <body>

        <Router />

      </body>

    </html>

  );

}
```

To hydrate the entire document, pass the [`document`](https://developer.mozilla.org/en-US/docs/Web/API/Window/document) global as the first argument to `hydrateRoot`:

```
import { hydrateRoot } from 'react-dom/client';

import App from './App.js';



hydrateRoot(document, <App />);
```

***

### Suppressing unavoidable hydration mismatch errors[](#suppressing-unavoidable-hydration-mismatch-errors "Link for Suppressing unavoidable hydration mismatch errors ")

If a single element’s attribute or text content is unavoidably different between the server and the client (for example, a timestamp), you may silence the hydration mismatch warning.

To silence hydration warnings on an element, add `suppressHydrationWarning={true}`:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
export default function App() {
  return (
    <h1 suppressHydrationWarning={true}>
      Current Date: {new Date().toLocaleDateString()}
    </h1>
  );
}
```

This only works one level deep, and is intended to be an escape hatch. Don’t overuse it. React will **not** attempt to patch mismatched text content.

***

### Handling different client and server content[](#handling-different-client-and-server-content "Link for Handling different client and server content ")

If you intentionally need to render something different on the server and the client, you can do a two-pass rendering. Components that render something different on the client can read a [state variable](/reference/react/useState) like `isClient`, which you can set to `true` in an [Effect](/reference/react/useEffect):

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useEffect } from "react";

export default function App() {
  const [isClient, setIsClient] = useState(false);

  useEffect(() => {
    setIsClient(true);
  }, []);

  return (
    <h1>
      {isClient ? 'Is Client' : 'Is Server'}
    </h1>
  );
}
```

This way the initial render pass will render the same content as the server, avoiding mismatches, but an additional pass will happen synchronously right after hydration.

### Pitfall

This approach makes hydration slower because your components have to render twice. Be mindful of the user experience on slow connections. The JavaScript code may load significantly later than the initial HTML render, so rendering a different UI immediately after hydration may also feel jarring to the user.

***

### Updating a hydrated root component[](#updating-a-hydrated-root-component "Link for Updating a hydrated root component ")

After the root has finished hydrating, you can call [`root.render`](#root-render) to update the root React component. **Unlike with [`createRoot`](/reference/react-dom/client/createRoot), you don’t usually need to do this because the initial content was already rendered as HTML.**

If you call `root.render` at some point after hydration, and the component tree structure matches up with what was previously rendered, React will [preserve the state.](/learn/preserving-and-resetting-state) Notice how you can type in the input, which means that the updates from repeated `render` calls every second in this example are not destructive:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { hydrateRoot } from 'react-dom/client';
import './styles.css';
import App from './App.js';

const root = hydrateRoot(
  document.getElementById('root'),
  <App counter={0} />
);

let i = 0;
setInterval(() => {
  root.render(<App counter={i} />);
  i++;
}, 1000);
```

It is uncommon to call [`root.render`](#root-render) on a hydrated root. Usually, you’ll [update state](/reference/react/useState) inside one of the components instead.

### Error logging in production[](#error-logging-in-production "Link for Error logging in production ")

By default, React will log all errors to the console. To implement your own error reporting, you can provide the optional error handler root options `onUncaughtError`, `onCaughtError` and `onRecoverableError`:

```
import { hydrateRoot } from "react-dom/client";

import App from "./App.js";

import { reportCaughtError } from "./reportError";



const container = document.getElementById("root");

const root = hydrateRoot(container, <App />, {

  onCaughtError: (error, errorInfo) => {

    if (error.message !== "Known error") {

      reportCaughtError({

        error,

        componentStack: errorInfo.componentStack,

      });

    }

  },

});
```

The onCaughtError option is a function called with two arguments:

1. The error that was thrown.
2. An errorInfo object that contains the componentStack of the error.

Together with `onUncaughtError` and `onRecoverableError`, you can implement your own error reporting system:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { hydrateRoot } from "react-dom/client";
import App from "./App.js";
import {
  onCaughtErrorProd,
  onRecoverableErrorProd,
  onUncaughtErrorProd,
} from "./reportError";

const container = document.getElementById("root");
hydrateRoot(container, <App />, {
  // Keep in mind to remove these options in development to leverage
  // React's default handlers or implement your own overlay for development.
  // The handlers are only specfied unconditionally here for demonstration purposes.
  onCaughtError: onCaughtErrorProd,
  onRecoverableError: onRecoverableErrorProd,
  onUncaughtError: onUncaughtErrorProd,
});
```

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### I’m getting an error: “You passed a second argument to root.render”[](#im-getting-an-error-you-passed-a-second-argument-to-root-render "Link for I’m getting an error: “You passed a second argument to root.render” ")

A common mistake is to pass the options for `hydrateRoot` to `root.render(...)`:

Console

Warning: You passed a second argument to root.render(…) but it only accepts one argument.

To fix, pass the root options to `hydrateRoot(...)`, not `root.render(...)`:

```
// 🚩 Wrong: root.render only takes one argument.

root.render(App, {onUncaughtError});



// ✅ Correct: pass options to createRoot.

const root = hydrateRoot(container, <App />, {onUncaughtError});
```

[PreviouscreateRoot](/reference/react-dom/client/createRoot)

[NextServer APIs](/reference/react-dom/server)

***

----
url: https://react.dev/reference/react-compiler/gating
----

[API Reference](/reference/react)

[Configuration](/reference/react-compiler/configuration)

# gating[](#undefined "Link for this heading")

The `gating` option enables conditional compilation, allowing you to control when optimized code is used at runtime.

```
{

  gating: {

    source: 'my-feature-flags',

    importSpecifierName: 'shouldUseCompiler'

  }

}
```

* [Reference](#reference)
  * [`gating`](#gating)

* [Usage](#usage)
  * [Basic feature flag setup](#basic-setup)

* [Troubleshooting](#troubleshooting)

  * [Feature flag not working](#flag-not-working)
  * [Import errors](#import-errors)

***

## Reference[](#reference "Link for Reference ")

### `gating`[](#gating "Link for this heading")

Configures runtime feature flag gating for compiled functions.

#### Type[](#type "Link for Type ")

```
{

  source: string;

  importSpecifierName: string;

} | null
```

#### Default value[](#default-value "Link for Default value ")

`null`

#### Properties[](#properties "Link for Properties ")

* **`source`**: Module path to import the feature flag from
* **`importSpecifierName`**: Name of the exported function to import

#### Caveats[](#caveats "Link for Caveats ")

* The gating function must return a boolean
* Both compiled and original versions increase bundle size
* The import is added to every file with compiled functions

***

## Usage[](#usage "Link for Usage ")

### Basic feature flag setup[](#basic-setup "Link for Basic feature flag setup ")

1. Create a feature flag module:

```
// src/utils/feature-flags.js

export function shouldUseCompiler() {

  // your logic here

  return getFeatureFlag('react-compiler-enabled');

}
```

2. Configure the compiler:

```
{

  gating: {

    source: './src/utils/feature-flags',

    importSpecifierName: 'shouldUseCompiler'

  }

}
```

3. The compiler generates gated code:

```
// Input

function Button(props) {

  return <button>{props.label}</button>;

}



// Output (simplified)

import { shouldUseCompiler } from './src/utils/feature-flags';



const Button = shouldUseCompiler()

  ? function Button_optimized(props) { /* compiled version */ }

  : function Button_original(props) { /* original version */ };
```

Note that the gating function is evaluated once at module time, so once the JS bundle has been parsed and evaluated the choice of component stays static for the rest of the browser session.

***

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### Feature flag not working[](#flag-not-working "Link for Feature flag not working ")

Verify your flag module exports the correct function:

```
// ❌ Wrong: Default export

export default function shouldUseCompiler() {

  return true;

}



// ✅ Correct: Named export matching importSpecifierName

export function shouldUseCompiler() {

  return true;

}
```

### Import errors[](#import-errors "Link for Import errors ")

Ensure the source path is correct:

```
// ❌ Wrong: Relative to babel.config.js

{

  source: './src/flags',

  importSpecifierName: 'flag'

}



// ✅ Correct: Module resolution path

{

  source: '@myapp/feature-flags',

  importSpecifierName: 'flag'

}



// ✅ Also correct: Absolute path from project root

{

  source: './src/utils/flags',

  importSpecifierName: 'flag'

}
```

[PreviouscompilationMode](/reference/react-compiler/compilationMode)

[Nextlogger](/reference/react-compiler/logger)

***

----
url: https://legacy.reactjs.org/blog/2017/09/08/dom-attributes-in-react-16.html
----

September 08, 2017 by [Dan Abramov](https://twitter.com/dan_abramov)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

In the past, React used to ignore unknown DOM attributes. If you wrote JSX with an attribute that React doesn’t recognize, React would just skip it. For example, this:

```
// Your code:
<div mycustomattribute="something" />
```

would render an empty div to the DOM with React 15:

```
// React 15 output:
<div />
```

In React 16, we are making a change. Now, any unknown attributes will end up in the DOM:

```
// React 16 output:
<div mycustomattribute="something" />
```

## [](#why-are-we-changing-this)Why Are We Changing This?

React has always provided a JavaScript-centric API to the DOM. Since React components often take both custom and DOM-related props, it makes sense for React to use the `camelCase` convention just like the DOM APIs:

```
<div tabIndex={-1} />
```

This has not changed. However, the way we enforced it in the past forced us to maintain an allowlist of all valid React DOM attributes in the bundle:

```
// ...
summary: 'summary',
tabIndex: 'tabindex'
target: 'target',
title: 'title',
// ...
```

This had two downsides:

* You could not [pass a custom attribute](https://github.com/facebook/react/issues/140). This is useful for supplying browser-specific non-standard attributes, trying new DOM APIs, and integrating with opinionated third-party libraries.
* The attribute list kept growing over time, but most React canonical attribute names are already valid in the DOM. Removing most of the allowlist helped us reduce the bundle size a little bit.

With the new approach, both of these problems are solved. With React 16, you can now pass custom attributes to all HTML and SVG elements, and React doesn’t have to include the whole attribute allowlist in the production version.

**Note that you should still use the canonical React naming for known attributes:**

```
// Yes, please
<div tabIndex={-1} />

// Warning: Invalid DOM property `tabindex`. Did you mean `tabIndex`?
<div tabindex={-1} />
```

In other words, the way you use DOM components in React hasn’t changed, but now you have some new capabilities.

## [](#should-i-keep-data-in-custom-attributes)Should I Keep Data in Custom Attributes?

No. We don’t encourage you to keep data in DOM attributes. Even if you have to, `data-` attributes are probably a better approach, but in most cases data should be kept in React component state or external stores.

However, the new feature is handy if you need to use a non-standard or a new DOM attribute, or if you need to integrate with a third-party library that relies on such attributes.

## [](#data-and-aria-attributes)Data and ARIA Attributes

Just like before, React lets you pass `data-` and `aria-` attributes freely:

```
<div data-foo="42" />
<button aria-label="Close" onClick={onClose} />
```

This has not changed.

[Accessibility](/docs/accessibility.html) is very important, so even though React 16 passes any attributes through, it still validates that `aria-` props have correct names in development mode, just like React 15 did.

## [](#migration-path)Migration Path

We have included [a warning about unknown attributes](/warnings/unknown-prop.html) since [React 15.2.0](https://github.com/facebook/react/releases/tag/v15.2.0) which came out more than a year ago. The vast majority of third-party libraries have already updated their code. If your app doesn’t produce warnings with React 15.2.0 or higher, this change should not require modifications in your application code.

If you still accidentally forward non-DOM props to DOM components, with React 16 you will start seeing those attributes in the DOM, for example:

```
<div myData='[Object object]' />
```

This is somewhat safe (the browser will just ignore them) but we recommend to fix these cases when you see them. One potential hazard is if you pass an object that implements a custom `toString()` or `valueOf()` method that throws. Another possible issue is that legacy HTML attributes like `align` and `valign` will now be passed to the DOM. They used to be stripped out because React didn’t support them.

To avoid these problems, we suggest to fix the warnings you see in React 15 before upgrading to React 16.

## [](#changes-in-detail)Changes in Detail

We’ve made a few other changes to make the behavior more predictable and help ensure you’re not making mistakes. We don’t anticipate that these changes are likely to break real-world applications.

**These changes only affect DOM components like `<div>`, not your own components.**

Below is a detailed list of them.

* **Unknown attributes with string, number, and object values:**

  ```
  <div mycustomattribute="value" />
  <div mycustomattribute={42} />
  <div mycustomattribute={myObject} />
  ```

  React 15: Warns and ignores them.\
  React 16: Converts values to strings and passes them through.

  *Note: attributes starting with `on` are not passed through as an exception because this could become a potential security hole.*

* **Known attributes with a different canonical React name:**

  ```
  <div tabindex={-1} />
  <div class="hi" />
  ```

  React 15: Warns and ignores them.\
  React 16: Warns but converts values to strings and passes them through.

  *Note: always use the canonical React naming for all supported attributes.*

* **Non-boolean attributes with boolean values:**

  ```
  <div className={false} />
  ```

  React 15: Converts booleans to strings and passes them through.\
  React 16: Warns and ignores them.

* **Non-event attributes with function values:**

  ```
  <div className={function() {}} />
  ```

  React 15: Converts functions to strings and passes them through.\
  React 16: Warns and ignores them.

* **Attributes with Symbol values:**

  ```
  <div className={Symbol('foo')} />
  ```

  React 15: Crashes.\
  React 16: Warns and ignores them.

* **Attributes with `NaN` values:**

  ```
  <div tabIndex={0 / 0} />
  ```

  React 15: Converts `NaN`s to strings and passes them through.\
  React 16: Converts `NaN`s to strings and passes them through with a warning.

While testing this release, we have also [created an automatically generated table](https://github.com/facebook/react/blob/main/fixtures/attribute-behavior/AttributeTableSnapshot.md) for all known attributes to track potential regressions.

## [](#try-it)Try It!

You can try the change in [this CodePen](https://codepen.io/gaearon/pen/gxNVdP?editors=0010).\
It uses React 16 RC, and you can [help us by testing the RC in your project!](https://github.com/facebook/react/issues/10294)

## [](#thanks)Thanks

This effort was largely driven by [Nathan Hunzaker](https://github.com/nhunzaker) who has been a [prolific outside contributor to React](https://github.com/facebook/react/pulls?q=is:pr+author:nhunzaker+is:closed).

You can find his work on this issue in several PRs over the course of last year: [#6459](https://github.com/facebook/react/pull/6459), [#7311](https://github.com/facebook/react/pull/7311), [#10229](https://github.com/facebook/react/pull/10229), [#10397](https://github.com/facebook/react/pull/10397), [#10385](https://github.com/facebook/react/pull/10385), and [#10470](https://github.com/facebook/react/pull/10470).

Major changes in a popular project can take a lot of time and research. Nathan demonstrated perseverance and commitment to getting this change through, and we are very thankful to him for this and other efforts.

We would also like to thank [Brandon Dail](https://github.com/aweary) and [Jason Quense](https://github.com/jquense) for their invaluable help maintaining React this year.

## [](#future-work)Future Work

We are not changing how [custom elements](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Custom_Elements) work in React 16, but there are [existing discussions](https://github.com/facebook/react/issues/7249) about setting properties instead of attributes, and we might revisit this in React 17. Feel free to chime in if you’d like to help!

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2017-09-08-dom-attributes-in-react-16.md)

----
url: https://legacy.reactjs.org/docs/optimizing-performance.html
----

> These docs are old and won’t be updated. Go to [react.dev](https://react.dev/) for the new React docs.
>
> These new documentation pages teach modern React:
>
> * [`memo`: Skipping re-rendering when props are unchanged](https://react.dev/reference/react/memo#skipping-re-rendering-when-props-are-unchanged)

Internally, React uses several clever techniques to minimize the number of costly DOM operations required to update the UI. For many applications, using React will lead to a fast user interface without doing much work to specifically optimize for performance. Nevertheless, there are several ways you can speed up your React application.

## [](#use-the-production-build)Use the Production Build

If you’re benchmarking or experiencing performance problems in your React apps, make sure you’re testing with the minified production build.

By default, React includes many helpful warnings. These warnings are very useful in development. However, they make React larger and slower so you should make sure to use the production version when you deploy the app.

If you aren’t sure whether your build process is set up correctly, you can check it by installing [React Developer Tools for Chrome](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi). If you visit a site with React in production mode, the icon will have a dark background:

[](/static/d0f767f80866431ccdec18f200ca58f1/0a47e/devtools-prod.png)

If you visit a site with React in development mode, the icon will have a red background:

[](/static/e434ce2f7e64f63e597edf03f4465694/0a47e/devtools-dev.png)

It is expected that you use the development mode when working on your app, and the production mode when deploying your app to the users.

You can find instructions for building your app for production below.

### [](#create-react-app)Create React App

If your project is built with [Create React App](https://github.com/facebookincubator/create-react-app), run:

```
npm run build
```

This will create a production build of your app in the `build/` folder of your project.

Remember that this is only necessary before deploying to production. For normal development, use `npm start`.

### [](#single-file-builds)Single-File Builds

We offer production-ready versions of React and React DOM as single files:

```
<script src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
```

Remember that only React files ending with `.production.min.js` are suitable for production.

### [](#brunch)Brunch

For the most efficient Brunch production build, install the [`terser-brunch`](https://github.com/brunch/terser-brunch) plugin:

```
# If you use npm
npm install --save-dev terser-brunch

# If you use Yarn
yarn add --dev terser-brunch
```

Then, to create a production build, add the `-p` flag to the `build` command:

```
brunch build -p
```

Remember that you only need to do this for production builds. You shouldn’t pass the `-p` flag or apply this plugin in development, because it will hide useful React warnings and make the builds much slower.

### [](#browserify)Browserify

For the most efficient Browserify production build, install a few plugins:

```
# If you use npm
npm install --save-dev envify terser uglifyify

# If you use Yarn
yarn add --dev envify terser uglifyify
```

To create a production build, make sure that you add these transforms **(the order matters)**:

* The [`envify`](https://github.com/hughsk/envify) transform ensures the right build environment is set. Make it global (`-g`).
* The [`uglifyify`](https://github.com/hughsk/uglifyify) transform removes development imports. Make it global too (`-g`).
* Finally, the resulting bundle is piped to [`terser`](https://github.com/terser-js/terser) for mangling ([read why](https://github.com/hughsk/uglifyify#motivationusage)).

For example:

```
browserify ./index.js \
  -g [ envify --NODE_ENV production ] \
  -g uglifyify \
  | terser --compress --mangle > ./bundle.js
```

Remember that you only need to do this for production builds. You shouldn’t apply these plugins in development because they will hide useful React warnings, and make the builds much slower.

### [](#rollup)Rollup

For the most efficient Rollup production build, install a few plugins:

```
# If you use npm
npm install --save-dev rollup-plugin-commonjs rollup-plugin-replace rollup-plugin-terser

# If you use Yarn
yarn add --dev rollup-plugin-commonjs rollup-plugin-replace rollup-plugin-terser
```

To create a production build, make sure that you add these plugins **(the order matters)**:

* The [`replace`](https://github.com/rollup/rollup-plugin-replace) plugin ensures the right build environment is set.
* The [`commonjs`](https://github.com/rollup/rollup-plugin-commonjs) plugin provides support for CommonJS in Rollup.
* The [`terser`](https://github.com/TrySound/rollup-plugin-terser) plugin compresses and mangles the final bundle.

```
plugins: [
  // ...
  require('rollup-plugin-replace')({
    'process.env.NODE_ENV': JSON.stringify('production')
  }),
  require('rollup-plugin-commonjs')(),
  require('rollup-plugin-terser')(),
  // ...
]
```

For a complete setup example [see this gist](https://gist.github.com/Rich-Harris/cb14f4bc0670c47d00d191565be36bf0).

Remember that you only need to do this for production builds. You shouldn’t apply the `terser` plugin or the `replace` plugin with `'production'` value in development because they will hide useful React warnings, and make the builds much slower.

### [](#webpack)webpack

> **Note:**
>
> If you’re using Create React App, please follow [the instructions above](#create-react-app).\
> This section is only relevant if you configure webpack directly.

Webpack v4+ will minify your code by default in production mode.

```
const TerserPlugin = require('terser-webpack-plugin');

module.exports = {
  mode: 'production',
  optimization: {
    minimizer: [new TerserPlugin({ /* additional options here */ })],
  },
};
```

You can learn more about this in [webpack documentation](https://webpack.js.org/guides/production/).

Remember that you only need to do this for production builds. You shouldn’t apply `TerserPlugin` in development because it will hide useful React warnings, and make the builds much slower.

## [](#profiling-components-with-the-devtools-profiler)Profiling Components with the DevTools Profiler

`react-dom` 16.5+ and `react-native` 0.57+ provide enhanced profiling capabilities in DEV mode with the React DevTools Profiler. An overview of the Profiler can be found in the blog post [“Introducing the React Profiler”](/blog/2018/09/10/introducing-the-react-profiler.html). A video walkthrough of the profiler is also [available on YouTube](https://www.youtube.com/watch?v=nySib7ipZdk).

If you haven’t yet installed the React DevTools, you can find them here:

* [Chrome Browser Extension](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?hl=en)
* [Firefox Browser Extension](https://addons.mozilla.org/en-GB/firefox/addon/react-devtools/)
* [Standalone Node Package](https://www.npmjs.com/package/react-devtools)

> Note
>
> A production profiling bundle of `react-dom` is also available as `react-dom/profiling`. Read more about how to use this bundle at [fb.me/react-profiling](https://fb.me/react-profiling)

> Note
>
> Before React 17, we use the standard [User Timing API](https://developer.mozilla.org/en-US/docs/Web/API/User_Timing_API) to profile components with the chrome performance tab. For a more detailed walkthrough, check out [this article by Ben Schwarz](https://calibreapp.com/blog/react-performance-profiling-optimization).

## [](#virtualize-long-lists)Virtualize Long Lists

If your application renders long lists of data (hundreds or thousands of rows), we recommend using a technique known as “windowing”. This technique only renders a small subset of your rows at any given time, and can dramatically reduce the time it takes to re-render the components as well as the number of DOM nodes created.

[react-window](https://react-window.now.sh/) and [react-virtualized](https://bvaughn.github.io/react-virtualized/) are popular windowing libraries. They provide several reusable components for displaying lists, grids, and tabular data. You can also create your own windowing component, like [Twitter did](https://medium.com/@paularmstrong/twitter-lite-and-high-performance-react-progressive-web-apps-at-scale-d28a00e780a3), if you want something more tailored to your application’s specific use case.

## [](#avoid-reconciliation)Avoid Reconciliation

React builds and maintains an internal representation of the rendered UI. It includes the React elements you return from your components. This representation lets React avoid creating DOM nodes and accessing existing ones beyond necessity, as that can be slower than operations on JavaScript objects. Sometimes it is referred to as a “virtual DOM”, but it works the same way on React Native.

When a component’s props or state change, React decides whether an actual DOM update is necessary by comparing the newly returned element with the previously rendered one. When they are not equal, React will update the DOM.

Even though React only updates the changed DOM nodes, re-rendering still takes some time. In many cases it’s not a problem, but if the slowdown is noticeable, you can speed all of this up by overriding the lifecycle function `shouldComponentUpdate`, which is triggered before the re-rendering process starts. The default implementation of this function returns `true`, leaving React to perform the update:

```
shouldComponentUpdate(nextProps, nextState) {
  return true;
}
```

If you know that in some situations your component doesn’t need to update, you can return `false` from `shouldComponentUpdate` instead, to skip the whole rendering process, including calling `render()` on this component and below.

In most cases, instead of writing `shouldComponentUpdate()` by hand, you can inherit from [`React.PureComponent`](/docs/react-api.html#reactpurecomponent). It is equivalent to implementing `shouldComponentUpdate()` with a shallow comparison of current and previous props and state.

## [](#shouldcomponentupdate-in-action)shouldComponentUpdate In Action

Here’s a subtree of components. For each one, `SCU` indicates what `shouldComponentUpdate` returned, and `vDOMEq` indicates whether the rendered React elements were equivalent. Finally, the circle’s color indicates whether the component had to be reconciled or not.

[](/static/5ee1bdf4779af06072a17b7a0654f6db/cd039/should-component-update.png)

Since `shouldComponentUpdate` returned `false` for the subtree rooted at C2, React did not attempt to render C2, and thus didn’t even have to invoke `shouldComponentUpdate` on C4 and C5.

For C1 and C3, `shouldComponentUpdate` returned `true`, so React had to go down to the leaves and check them. For C6 `shouldComponentUpdate` returned `true`, and since the rendered elements weren’t equivalent React had to update the DOM.

The last interesting case is C8. React had to render this component, but since the React elements it returned were equal to the previously rendered ones, it didn’t have to update the DOM.

Note that React only had to do DOM mutations for C6, which was inevitable. For C8, it bailed out by comparing the rendered React elements, and for C2’s subtree and C7, it didn’t even have to compare the elements as we bailed out on `shouldComponentUpdate`, and `render` was not called.

## [](#examples)Examples

If the only way your component ever changes is when the `props.color` or the `state.count` variable changes, you could have `shouldComponentUpdate` check that:

```
class CounterButton extends React.Component {
  constructor(props) {
    super(props);
    this.state = {count: 1};
  }

  shouldComponentUpdate(nextProps, nextState) {
    if (this.props.color !== nextProps.color) {
      return true;
    }
    if (this.state.count !== nextState.count) {
      return true;
    }
    return false;
  }

  render() {
    return (
      <button
        color={this.props.color}
        onClick={() => this.setState(state => ({count: state.count + 1}))}>
        Count: {this.state.count}
      </button>
    );
  }
}
```

In this code, `shouldComponentUpdate` is just checking if there is any change in `props.color` or `state.count`. If those values don’t change, the component doesn’t update. If your component got more complex, you could use a similar pattern of doing a “shallow comparison” between all the fields of `props` and `state` to determine if the component should update. This pattern is common enough that React provides a helper to use this logic - just inherit from `React.PureComponent`. So this code is a simpler way to achieve the same thing:

```
class CounterButton extends React.PureComponent {
  constructor(props) {
    super(props);
    this.state = {count: 1};
  }

  render() {
    return (
      <button
        color={this.props.color}
        onClick={() => this.setState(state => ({count: state.count + 1}))}>
        Count: {this.state.count}
      </button>
    );
  }
}
```

Most of the time, you can use `React.PureComponent` instead of writing your own `shouldComponentUpdate`. It only does a shallow comparison, so you can’t use it if the props or state may have been mutated in a way that a shallow comparison would miss.

This can be a problem with more complex data structures. For example, let’s say you want a `ListOfWords` component to render a comma-separated list of words, with a parent `WordAdder` component that lets you click a button to add a word to the list. This code does *not* work correctly:

```
class ListOfWords extends React.PureComponent {
  render() {
    return <div>{this.props.words.join(',')}</div>;
  }
}

class WordAdder extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      words: ['marklar']
    };
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    // This section is bad style and causes a bug
    const words = this.state.words;
    words.push('marklar');
    this.setState({words: words});
  }

  render() {
    return (
      <div>
        <button onClick={this.handleClick} />
        <ListOfWords words={this.state.words} />
      </div>
    );
  }
}
```

The problem is that `PureComponent` will do a simple comparison between the old and new values of `this.props.words`. Since this code mutates the `words` array in the `handleClick` method of `WordAdder`, the old and new values of `this.props.words` will compare as equal, even though the actual words in the array have changed. The `ListOfWords` will thus not update even though it has new words that should be rendered.

## [](#the-power-of-not-mutating-data)The Power Of Not Mutating Data

The simplest way to avoid this problem is to avoid mutating values that you are using as props or state. For example, the `handleClick` method above could be rewritten using `concat` as:

```
handleClick() {
  this.setState(state => ({
    words: state.words.concat(['marklar'])
  }));
}
```

ES6 supports a [spread syntax](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator) for arrays which can make this easier. If you’re using Create React App, this syntax is available by default.

```
handleClick() {
  this.setState(state => ({
    words: [...state.words, 'marklar'],
  }));
};
```

You can also rewrite code that mutates objects to avoid mutation, in a similar way. For example, let’s say we have an object named `colormap` and we want to write a function that changes `colormap.right` to be `'blue'`. We could write:

```
function updateColorMap(colormap) {
  colormap.right = 'blue';
}
```

To write this without mutating the original object, we can use [Object.assign](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) method:

```
function updateColorMap(colormap) {
  return Object.assign({}, colormap, {right: 'blue'});
}
```

`updateColorMap` now returns a new object, rather than mutating the old one. `Object.assign` is in ES6 and requires a polyfill.

[Object spread syntax](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax) makes it easier to update objects without mutation as well:

```
function updateColorMap(colormap) {
  return {...colormap, right: 'blue'};
}
```

This feature was added to JavaScript in ES2018.

If you’re using Create React App, both `Object.assign` and the object spread syntax are available by default.

When you deal with deeply nested objects, updating them in an immutable way can feel convoluted. If you run into this problem, check out [Immer](https://github.com/mweststrate/immer) or [immutability-helper](https://github.com/kolodny/immutability-helper). These libraries let you write highly readable code without losing the benefits of immutability.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/optimizing-performance.md)

----
url: https://legacy.reactjs.org/docs/faq-functions.html
----

### [](#how-do-i-pass-an-event-handler-like-onclick-to-a-component)How do I pass an event handler (like onClick) to a component?

Pass event handlers and other functions as props to child components:

```
<button onClick={this.handleClick}>
```

If you need to have access to the parent component in the handler, you also need to bind the function to the component instance (see below).

### [](#how-do-i-bind-a-function-to-a-component-instance)How do I bind a function to a component instance?

There are several ways to make sure functions have access to component attributes like `this.props` and `this.state`, depending on which syntax and build steps you are using.

#### [](#bind-in-constructor-es2015)Bind in Constructor (ES2015)

```
class Foo extends Component {
  constructor(props) {
    super(props);
    this.handleClick = this.handleClick.bind(this);
  }
  handleClick() {
    console.log('Click happened');
  }
  render() {
    return <button onClick={this.handleClick}>Click Me</button>;
  }
}
```

#### [](#class-properties-es2022)Class Properties (ES2022)

```
class Foo extends Component {
  handleClick = () => {
    console.log('Click happened');
  };
  render() {
    return <button onClick={this.handleClick}>Click Me</button>;
  }
}
```

#### [](#bind-in-render)Bind in Render

```
class Foo extends Component {
  handleClick() {
    console.log('Click happened');
  }
  render() {
    return <button onClick={this.handleClick.bind(this)}>Click Me</button>;
  }
}
```

> **Note:**
>
> Using `Function.prototype.bind` in render creates a new function each time the component renders, which may have performance implications (see below).

#### [](#arrow-function-in-render)Arrow Function in Render

```
class Foo extends Component {
  handleClick() {
    console.log('Click happened');
  }
  render() {
    return <button onClick={() => this.handleClick()}>Click Me</button>;
  }
}
```

> **Note:**
>
> Using an arrow function in render creates a new function each time the component renders, which may break optimizations based on strict identity comparison.

### [](#is-it-ok-to-use-arrow-functions-in-render-methods)Is it OK to use arrow functions in render methods?

Generally speaking, yes, it is OK, and it is often the easiest way to pass parameters to callback functions.

If you do have performance issues, by all means, optimize!

### [](#why-is-binding-necessary-at-all)Why is binding necessary at all?

In JavaScript, these two code snippets are **not** equivalent:

```
obj.method();
```

```
var method = obj.method;
method();
```

Binding methods helps ensure that the second snippet works the same way as the first one.

With React, typically you only need to bind the methods you *pass* to other components. For example, `<button onClick={this.handleClick}>` passes `this.handleClick` so you want to bind it. However, it is unnecessary to bind the `render` method or the lifecycle methods: we don’t pass them to other components.

[This post by Yehuda Katz](https://yehudakatz.com/2011/08/11/understanding-javascript-function-invocation-and-this/) explains what binding is, and how functions work in JavaScript, in detail.

### [](#why-is-my-function-being-called-every-time-the-component-renders)Why is my function being called every time the component renders?

Make sure you aren’t *calling the function* when you pass it to the component:

```
render() {
  // Wrong: handleClick is called instead of passed as a reference!
  return <button onClick={this.handleClick()}>Click Me</button>
}
```

Instead, *pass the function itself* (without parens):

```
render() {
  // Correct: handleClick is passed as a reference!
  return <button onClick={this.handleClick}>Click Me</button>
}
```

### [](#how-do-i-pass-a-parameter-to-an-event-handler-or-callback)How do I pass a parameter to an event handler or callback?

You can use an arrow function to wrap around an event handler and pass parameters:

```
<button onClick={() => this.handleClick(id)} />
```

This is equivalent to calling `.bind`:

```
<button onClick={this.handleClick.bind(this, id)} />
```

#### [](#example-passing-params-using-arrow-functions)Example: Passing params using arrow functions

```
const A = 65 // ASCII character code

class Alphabet extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      justClicked: null,
      letters: Array.from({length: 26}, (_, i) => String.fromCharCode(A + i))
    };
  }
  handleClick(letter) {
    this.setState({ justClicked: letter });
  }
  render() {
    return (
      <div>
        Just clicked: {this.state.justClicked}
        <ul>
          {this.state.letters.map(letter =>
            <li key={letter} onClick={() => this.handleClick(letter)}>
              {letter}
            </li>
          )}
        </ul>
      </div>
    )
  }
}
```

#### [](#example-passing-params-using-data-attributes)Example: Passing params using data-attributes

Alternately, you can use DOM APIs to store data needed for event handlers. Consider this approach if you need to optimize a large number of elements or have a render tree that relies on React.PureComponent equality checks.

```
const A = 65 // ASCII character code

class Alphabet extends React.Component {
  constructor(props) {
    super(props);
    this.handleClick = this.handleClick.bind(this);
    this.state = {
      justClicked: null,
      letters: Array.from({length: 26}, (_, i) => String.fromCharCode(A + i))
    };
  }

  handleClick(e) {
    this.setState({
      justClicked: e.target.dataset.letter
    });
  }

  render() {
    return (
      <div>
        Just clicked: {this.state.justClicked}
        <ul>
          {this.state.letters.map(letter =>
            <li key={letter} data-letter={letter} onClick={this.handleClick}>
              {letter}
            </li>
          )}
        </ul>
      </div>
    )
  }
}
```

### [](#how-can-i-prevent-a-function-from-being-called-too-quickly-or-too-many-times-in-a-row)How can I prevent a function from being called too quickly or too many times in a row?

If you have an event handler such as `onClick` or `onScroll` and want to prevent the callback from being fired too quickly, then you can limit the rate at which callback is executed. This can be done by using:

* **throttling**: sample changes based on a time based frequency (eg [`_.throttle`](https://lodash.com/docs#throttle))
* **debouncing**: publish changes after a period of inactivity (eg [`_.debounce`](https://lodash.com/docs#debounce))
* **`requestAnimationFrame` throttling**: sample changes based on [`requestAnimationFrame`](https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame) (eg [`raf-schd`](https://github.com/alexreardon/raf-schd))

See [this visualization](http://demo.nimius.net/debounce_throttle/) for a comparison of `throttle` and `debounce` functions.

> Note:
>
> `_.debounce`, `_.throttle` and `raf-schd` provide a `cancel` method to cancel delayed callbacks. You should either call this method from `componentWillUnmount` *or* check to ensure that the component is still mounted within the delayed function.

#### [](#throttle)Throttle

Throttling prevents a function from being called more than once in a given window of time. The example below throttles a “click” handler to prevent calling it more than once per second.

```
import throttle from 'lodash.throttle';

class LoadMoreButton extends React.Component {
  constructor(props) {
    super(props);
    this.handleClick = this.handleClick.bind(this);
    this.handleClickThrottled = throttle(this.handleClick, 1000);
  }

  componentWillUnmount() {
    this.handleClickThrottled.cancel();
  }

  render() {
    return <button onClick={this.handleClickThrottled}>Load More</button>;
  }

  handleClick() {
    this.props.loadMore();
  }
}
```

#### [](#debounce)Debounce

Debouncing ensures that a function will not be executed until after a certain amount of time has passed since it was last called. This can be useful when you have to perform some expensive calculation in response to an event that might dispatch rapidly (eg scroll or keyboard events). The example below debounces text input with a 250ms delay.

```
import debounce from 'lodash.debounce';

class Searchbox extends React.Component {
  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
    this.emitChangeDebounced = debounce(this.emitChange, 250);
  }

  componentWillUnmount() {
    this.emitChangeDebounced.cancel();
  }

  render() {
    return (
      <input
        type="text"
        onChange={this.handleChange}
        placeholder="Search..."
        defaultValue={this.props.value}
      />
    );
  }

  handleChange(e) {
    this.emitChangeDebounced(e.target.value);
  }

  emitChange(value) {
    this.props.onChange(value);
  }
}
```

#### [](#requestanimationframe-throttling)`requestAnimationFrame` throttling

[`requestAnimationFrame`](https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame) is a way of queuing a function to be executed in the browser at the optimal time for rendering performance. A function that is queued with `requestAnimationFrame` will fire in the next frame. The browser will work hard to ensure that there are 60 frames per second (60 fps). However, if the browser is unable to it will naturally *limit* the amount of frames in a second. For example, a device might only be able to handle 30 fps and so you will only get 30 frames in that second. Using `requestAnimationFrame` for throttling is a useful technique in that it prevents you from doing more than 60 updates in a second. If you are doing 100 updates in a second this creates additional work for the browser that the user will not see anyway.

> **Note:**
>
> Using this technique will only capture the last published value in a frame. You can see an example of how this optimization works on [`MDN`](https://developer.mozilla.org/en-US/docs/Web/Events/scroll)

```
import rafSchedule from 'raf-schd';

class ScrollListener extends React.Component {
  constructor(props) {
    super(props);

    this.handleScroll = this.handleScroll.bind(this);

    // Create a new function to schedule updates.
    this.scheduleUpdate = rafSchedule(
      point => this.props.onScroll(point)
    );
  }

  handleScroll(e) {
    // When we receive a scroll event, schedule an update.
    // If we receive many updates within a frame, we'll only publish the latest value.
    this.scheduleUpdate({ x: e.clientX, y: e.clientY });
  }

  componentWillUnmount() {
    // Cancel any pending updates since we're unmounting.
    this.scheduleUpdate.cancel();
  }

  render() {
    return (
      <div
        style={{ overflow: 'scroll' }}
        onScroll={this.handleScroll}
      >
        <img src="/my-huge-image.jpg" />
      </div>
    );
  }
}
```

#### [](#testing-your-rate-limiting)Testing your rate limiting

When testing your rate limiting code works correctly it is helpful to have the ability to fast forward time. If you are using [`jest`](https://facebook.github.io/jest/) then you can use [`mock timers`](https://facebook.github.io/jest/docs/en/timer-mocks.html) to fast forward time. If you are using `requestAnimationFrame` throttling then you may find [`raf-stub`](https://github.com/alexreardon/raf-stub) to be a useful tool to control the ticking of animation frames.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/faq-functions.md)

----
url: https://legacy.reactjs.org/blog/2015/02/24/react-v0.13-rc1.html
----

February 24, 2015 by [Paul O’Shannessy](https://twitter.com/zpao)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

Over the weekend we pushed out our first (and hopefully only) release candidate for React v0.13!

We’ve talked a little bit about the changes that are coming. The splashiest of these changes is support for ES6 Classes. You can read more about this in [our beta announcement](/blog/2015/01/27/react-v0.13.0-beta-1.html). We’re really excited about this! Sebastian also posted earlier this morning about [some of the other changes coming focused around ReactElement](/blog/2015/02/24/streamlining-react-elements.html). The changes we’ve been working on there will hopefully enable lots of improvements to performance and developer experience.

The release candidate is available for download:

* **React**\
  Dev build with warnings: <https://fb.me/react-0.13.0-rc1.js>\
  Minified build for production: <https://fb.me/react-0.13.0-rc1.min.js>
* **React with Add-Ons**\
  Dev build with warnings: <https://fb.me/react-with-addons-0.13.0-rc1.js>\
  Minified build for production: <https://fb.me/react-with-addons-0.13.0-rc1.min.js>
* **In-Browser JSX transformer**\
  <https://fb.me/JSXTransformer-0.13.0-rc1.js>

We’ve also published version `0.13.0-rc1` of the `react` and `react-tools` packages on npm and the `react` package on bower.

***

## [](#changelog)Changelog

### [](#react-core)React Core

#### [](#breaking-changes)Breaking Changes


* Support for using ES6 classes to build React components; see the [v0.13.0 beta 1 notes](/blog/2015/01/27/react-v0.13.0-beta-1.html) for details
* Added new top-level API `React.findDOMNode(component)`, which should be used in place of `component.getDOMNode()`. The base class for ES6-based components will not have `getDOMNode`. This change will enable some more patterns moving forward.
* New `ref` style, allowing a callback to be used in place of a name: `<Photo ref={(c) => this._photo = c} />` allows you to reference the component with `this._photo` (as opposed to `ref="photo"` which gives `this.refs.photo`)
* `this.setState()` can now take a function as the first argument for transactional state updates, such as `this.setState((state, props) => ({count: state.count + 1}));` — this means that you no longer need to use `this._pendingState`, which is now gone.
* Support for iterators and immutable-js sequences as children

#### [](#deprecations)Deprecations

* `ComponentClass.type` is deprecated. Just use `ComponentClass` (usually as `element.type === ComponentClass`)
* Some methods that are available on `createClass`-based components are removed or deprecated from ES6 classes (for example, `getDOMNode`, `setProps`, `replaceState`).

### [](#react-with-add-ons)React with Add-Ons

#### [](#deprecations-1)Deprecations

* `React.addons.classSet` is now deprecated. This functionality can be replaced with several freely available modules. [classnames](https://www.npmjs.com/package/classnames) is one such module.

### [](#react-tools)React Tools

#### [](#breaking-changes-1)Breaking Changes

* When transforming ES6 syntax, `class` methods are no longer enumerable by default, which requires `Object.defineProperty`; if you support browsers such as IE8, you can pass `--target es3` to mirror the old behavior

#### [](#new-features-1)New Features

* `--target` option is available on the jsx command, allowing users to specify and ECMAScript version to target.

  * `es5` is the default.
  * `es3` restored the previous default behavior. An additional transform is added here to ensure the use of reserved words as properties is safe (eg `this.static` will become `this['static']` for IE8 compatibility).

* The transform for the call spread syntax has also been enabled.

### [](#jsx)JSX

#### [](#breaking-changes-2)Breaking Changes

* A change was made to how some JSX was parsed, specifically around the use of `>` or `}` when inside an element. Previously it would be treated as a string but now it will be treated as a parse error. We will be releasing a standalone executable to find and fix potential issues in your JSX code.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2015-02-24-react-v0.13-rc1.md)

----
url: https://react.dev/blog/2022/03/08/react-18-upgrade-guide
----

[Blog](/blog)

# How to Upgrade to React 18[](#undefined "Link for this heading")

March 08, 2022 by [Rick Hanlon](https://twitter.com/rickhanlonii)

***

As we shared in the [release post](/blog/2022/03/29/react-v18), React 18 introduces features powered by our new concurrent renderer, with a gradual adoption strategy for existing applications. In this post, we will guide you through the steps for upgrading to React 18.

Please [report any issues](https://github.com/facebook/react/issues/new/choose) you encounter while upgrading to React 18.

### Note

For React Native users, React 18 will ship in a future version of React Native. This is because React 18 relies on the New React Native Architecture to benefit from the new capabilities presented in this blogpost. For more information, see the [React Conf keynote here](https://www.youtube.com/watch?v=FZ0cG47msEk\&t=1530s).

***

## Installing[](#installing "Link for Installing ")

To install the latest version of React:

```
npm install react react-dom
```

Or if you’re using yarn:

```
yarn add react react-dom
```

## Updates to Client Rendering APIs[](#updates-to-client-rendering-apis "Link for Updates to Client Rendering APIs ")

When you first install React 18, you will see a warning in the console:

Console

ReactDOM.render is no longer supported in React 18. Use createRoot instead. Until you switch to the new API, your app will behave as if it’s running React 17. Learn more: <https://reactjs.org/link/switch-to-createroot>

React 18 introduces a new root API which provides better ergonomics for managing roots. The new root API also enables the new concurrent renderer, which allows you to opt-into concurrent features.

```
// Before

import { render } from 'react-dom';

const container = document.getElementById('app');

render(<App tab="home" />, container);



// After

import { createRoot } from 'react-dom/client';

const container = document.getElementById('app');

const root = createRoot(container); // createRoot(container!) if you use TypeScript

root.render(<App tab="home" />);
```

We’ve also changed `unmountComponentAtNode` to `root.unmount`:

```
// Before

unmountComponentAtNode(container);



// After

root.unmount();
```

We’ve also removed the callback from render, since it usually does not have the expected result when using Suspense:

```
// Before

const container = document.getElementById('app');

render(<App tab="home" />, container, () => {

  console.log('rendered');

});



// After

function AppWithCallbackAfterRender() {

  useEffect(() => {

    console.log('rendered');

  });



  return <App tab="home" />

}



const container = document.getElementById('app');

const root = createRoot(container);

root.render(<AppWithCallbackAfterRender />);
```

### Note

There is no one-to-one replacement for the old render callback API — it depends on your use case. See the working group post for [Replacing render with createRoot](https://github.com/reactwg/react-18/discussions/5) for more information.

Finally, if your app uses server-side rendering with hydration, upgrade `hydrate` to `hydrateRoot`:

```
// Before

import { hydrate } from 'react-dom';

const container = document.getElementById('app');

hydrate(<App tab="home" />, container);



// After

import { hydrateRoot } from 'react-dom/client';

const container = document.getElementById('app');

const root = hydrateRoot(container, <App tab="home" />);

// Unlike with createRoot, you don't need a separate root.render() call here.
```

For more information, see the [working group discussion here](https://github.com/reactwg/react-18/discussions/5).

### Note

**If your app doesn’t work after upgrading, check whether it’s wrapped in `<StrictMode>`.** [Strict Mode has gotten stricter in React 18](#updates-to-strict-mode), and not all your components may be resilient to the new checks it adds in development mode. If removing Strict Mode fixes your app, you can remove it during the upgrade, and then add it back (either at the top or for a part of the tree) after you fix the issues that it’s pointing out.

## Updates to Server Rendering APIs[](#updates-to-server-rendering-apis "Link for Updates to Server Rendering APIs ")

## Updates to TypeScript definitions[](#updates-to-typescript-definitions "Link for Updates to TypeScript definitions ")

If your project uses TypeScript, you will need to update your `@types/react` and `@types/react-dom` dependencies to the latest versions. The new types are safer and catch issues that used to be ignored by the type checker. The most notable change is that the `children` prop now needs to be listed explicitly when defining props, for example:

```
interface MyButtonProps {

  color: string;

  children?: React.ReactNode;

}
```

See the [React 18 typings pull request](https://github.com/DefinitelyTyped/DefinitelyTyped/pull/56210) for a full list of type-only changes. It links to example fixes in library types so you can see how to adjust your code. You can use the [automated migration script](https://github.com/eps1lon/types-react-codemod) to help port your application code to the new and safer typings faster.

If you find a bug in the typings, please [file an issue](https://github.com/DefinitelyTyped/DefinitelyTyped/discussions/new?category=issues-with-a-types-package) in the DefinitelyTyped repo.

## Automatic Batching[](#automatic-batching "Link for Automatic Batching ")

React 18 adds out-of-the-box performance improvements by doing more batching by default. Batching is when React groups multiple state updates into a single re-render for better performance. Before React 18, we only batched updates inside React event handlers. Updates inside of promises, setTimeout, native event handlers, or any other event were not batched in React by default:

```
// Before React 18 only React events were batched



function handleClick() {

  setCount(c => c + 1);

  setFlag(f => !f);

  // React will only re-render once at the end (that's batching!)

}



setTimeout(() => {

  setCount(c => c + 1);

  setFlag(f => !f);

  // React will render twice, once for each state update (no batching)

}, 1000);
```

Starting in React 18 with `createRoot`, all updates will be automatically batched, no matter where they originate from. This means that updates inside of timeouts, promises, native event handlers or any other event will batch the same way as updates inside of React events:

```
// After React 18 updates inside of timeouts, promises,

// native event handlers or any other event are batched.



function handleClick() {

  setCount(c => c + 1);

  setFlag(f => !f);

  // React will only re-render once at the end (that's batching!)

}



setTimeout(() => {

  setCount(c => c + 1);

  setFlag(f => !f);

  // React will only re-render once at the end (that's batching!)

}, 1000);
```

This is a breaking change, but we expect this to result in less work rendering, and therefore better performance in your applications. To opt-out of automatic batching, you can use `flushSync`:

```
import { flushSync } from 'react-dom';



function handleClick() {

  flushSync(() => {

    setCounter(c => c + 1);

  });

  // React has updated the DOM by now

  flushSync(() => {

    setFlag(f => !f);

  });

  // React has updated the DOM by now

}
```

For more information, see the [Automatic batching deep dive](https://github.com/reactwg/react-18/discussions/21).

## New APIs for Libraries[](#new-apis-for-libraries "Link for New APIs for Libraries ")

In the React 18 Working Group we worked with library maintainers to create new APIs needed to support concurrent rendering for use cases specific to their use case in areas like styles, and external stores. To support React 18, some libraries may need to switch to one of the following APIs:

* `useSyncExternalStore` is a new Hook that allows external stores to support concurrent reads by forcing updates to the store to be synchronous. This new API is recommended for any library that integrates with state external to React. For more information, see the [useSyncExternalStore overview post](https://github.com/reactwg/react-18/discussions/70) and [useSyncExternalStore API details](https://github.com/reactwg/react-18/discussions/86).
* `useInsertionEffect` is a new Hook that allows CSS-in-JS libraries to address performance issues of injecting styles in render. Unless you’ve already built a CSS-in-JS library we don’t expect you to ever use this. This Hook will run after the DOM is mutated, but before layout effects read the new layout. This solves an issue that already exists in React 17 and below, but is even more important in React 18 because React yields to the browser during concurrent rendering, giving it a chance to recalculate layout. For more information, see the [Library Upgrade Guide for `<style>`](https://github.com/reactwg/react-18/discussions/110).

React 18 also introduces new APIs for concurrent rendering such as `startTransition`, `useDeferredValue` and `useId`, which we share more about in the [release post](/blog/2022/03/29/react-v18).

## Updates to Strict Mode[](#updates-to-strict-mode "Link for Updates to Strict Mode ")

In the future, we’d like to add a feature that allows React to add and remove sections of the UI while preserving state. For example, when a user tabs away from a screen and back, React should be able to immediately show the previous screen. To do this, React would unmount and remount trees using the same component state as before.

This feature will give React better performance out-of-the-box, but requires components to be resilient to effects being mounted and destroyed multiple times. Most effects will work without any changes, but some effects assume they are only mounted or destroyed once.

To help surface these issues, React 18 introduces a new development-only check to Strict Mode. This new check will automatically unmount and remount every component, whenever a component mounts for the first time, restoring the previous state on the second mount.

Before this change, React would mount the component and create the effects:

```
* React mounts the component.

    * Layout effects are created.

    * Effect effects are created.
```

With Strict Mode in React 18, React will simulate unmounting and remounting the component in development mode:

```
* React mounts the component.

    * Layout effects are created.

    * Effect effects are created.

* React simulates unmounting the component.

    * Layout effects are destroyed.

    * Effects are destroyed.

* React simulates mounting the component with the previous state.

    * Layout effect setup code runs

    * Effect setup code runs
```

For more information, see the Working Group posts for [Adding Reusable State to StrictMode](https://github.com/reactwg/react-18/discussions/19) and [How to support Reusable State in Effects](https://github.com/reactwg/react-18/discussions/18).

## Configuring Your Testing Environment[](#configuring-your-testing-environment "Link for Configuring Your Testing Environment ")

When you first update your tests to use `createRoot`, you may see this warning in your test console:

Console

The current testing environment is not configured to support act(…)

To fix this, set `globalThis.IS_REACT_ACT_ENVIRONMENT` to `true` before running your test:

```
// In your test setup file

globalThis.IS_REACT_ACT_ENVIRONMENT = true;
```

The purpose of the flag is to tell React that it’s running in a unit test-like environment. React will log helpful warnings if you forget to wrap an update with `act`.

You can also set the flag to `false` to tell React that `act` isn’t needed. This can be useful for end-to-end tests that simulate a full browser environment.

Eventually, we expect testing libraries will configure this for you automatically. For example, the [next version of React Testing Library has built-in support for React 18](https://github.com/testing-library/react-testing-library/issues/509#issuecomment-917989936) without any additional configuration.

[More background on the `act` testing API and related changes](https://github.com/reactwg/react-18/discussions/102) is available in the working group.

## Dropping Support for Internet Explorer[](#dropping-support-for-internet-explorer "Link for Dropping Support for Internet Explorer ")

In this release, React is dropping support for Internet Explorer, which is [going out of support on June 15, 2022](https://blogs.windows.com/windowsexperience/2021/05/19/the-future-of-internet-explorer-on-windows-10-is-in-microsoft-edge). We’re making this change now because new features introduced in React 18 are built using modern browser features such as microtasks which cannot be adequately polyfilled in IE.

If you need to support Internet Explorer we recommend you stay with React 17.

## Deprecations[](#deprecations "Link for Deprecations ")

* `react-dom`: `ReactDOM.render` has been deprecated. Using it will warn and run your app in React 17 mode.
* `react-dom`: `ReactDOM.hydrate` has been deprecated. Using it will warn and run your app in React 17 mode.
* `react-dom`: `ReactDOM.unmountComponentAtNode` has been deprecated.
* `react-dom`: `ReactDOM.renderSubtreeIntoContainer` has been deprecated.
* `react-dom/server`: `ReactDOMServer.renderToNodeStream` has been deprecated.

## Other Breaking Changes[](#other-breaking-changes "Link for Other Breaking Changes ")

* **Consistent useEffect timing**: React now always synchronously flushes effect functions if the update was triggered during a discrete user input event such as a click or a keydown event. Previously, the behavior wasn’t always predictable or consistent.
* **Stricter hydration errors**: Hydration mismatches due to missing or extra text content are now treated like errors instead of warnings. React will no longer attempt to “patch up” individual nodes by inserting or deleting a node on the client in an attempt to match the server markup, and will revert to client rendering up to the closest `<Suspense>` boundary in the tree. This ensures the hydrated tree is consistent and avoids potential privacy and security holes that can be caused by hydration mismatches.
* **Suspense trees are always consistent:** If a component suspends before it’s fully added to the tree, React will not add it to the tree in an incomplete state or fire its effects. Instead, React will throw away the new tree completely, wait for the asynchronous operation to finish, and then retry rendering again from scratch. React will render the retry attempt concurrently, and without blocking the browser.
* **Layout Effects with Suspense**: When a tree re-suspends and reverts to a fallback, React will now clean up layout effects, and then re-create them when the content inside the boundary is shown again. This fixes an issue which prevented component libraries from correctly measuring layout when used with Suspense.
* **New JS Environment Requirements**: React now depends on modern browsers features including `Promise`, `Symbol`, and `Object.assign`. If you support older browsers and devices such as Internet Explorer which do not provide modern browser features natively or have non-compliant implementations, consider including a global polyfill in your bundled application.

## Other Notable Changes[](#other-notable-changes "Link for Other Notable Changes ")

### React[](#react "Link for React ")

* **Components can now render `undefined`:** React no longer warns if you return `undefined` from a component. This makes the allowed component return values consistent with values that are allowed in the middle of a component tree. We suggest to use a linter to prevent mistakes like forgetting a `return` statement before JSX.
* **In tests, `act` warnings are now opt-in:** If you’re running end-to-end tests, the `act` warnings are unnecessary. We’ve introduced an [opt-in](https://github.com/reactwg/react-18/discussions/102) mechanism so you can enable them only for unit tests where they are useful and beneficial.
* **No warning about `setState` on unmounted components:** Previously, React warned about memory leaks when you call `setState` on an unmounted component. This warning was added for subscriptions, but people primarily run into it in scenarios where setting state is fine, and workarounds make the code worse. We’ve [removed](https://github.com/facebook/react/pull/22114) this warning.
* **No suppression of console logs:** When you use Strict Mode, React renders each component twice to help you find unexpected side effects. In React 17, we’ve suppressed console logs for one of the two renders to make the logs easier to read. In response to [community feedback](https://github.com/facebook/react/issues/21783) about this being confusing, we’ve removed the suppression. Instead, if you have React DevTools installed, the second log’s renders will be displayed in grey, and there will be an option (off by default) to suppress them completely.
* **Improved memory usage:** React now cleans up more internal fields on unmount, making the impact from unfixed memory leaks that may exist in your application code less severe.

### React DOM Server[](#react-dom-server "Link for React DOM Server ")

* **`renderToString`:** Will no longer error when suspending on the server. Instead, it will emit the fallback HTML for the closest `<Suspense>` boundary and then retry rendering the same content on the client. It is still recommended that you switch to a streaming API like `renderToPipeableStream` or `renderToReadableStream` instead.
* **`renderToStaticMarkup`:** Will no longer error when suspending on the server. Instead, it will emit the fallback HTML for the closest `<Suspense>` boundary.

## Changelog[](#changelog "Link for Changelog ")

You can view the [full changelog here](https://github.com/facebook/react/blob/main/CHANGELOG.md).

[PreviousReact v18.0](/blog/2022/03/29/react-v18)

[NextReact Conf 2021 Recap](/blog/2021/12/17/react-conf-2021-recap)

***

----
url: https://react.dev/learn/updating-objects-in-state
----

```
const [x, setX] = useState(0);
```

So far you’ve been working with numbers, strings, and booleans. These kinds of JavaScript values are “immutable”, meaning unchangeable or “read-only”. You can trigger a re-render to *replace* a value:

```
setX(5);
```

The `x` state changed from `0` to `5`, but the *number `0` itself* did not change. It’s not possible to make any changes to the built-in primitive values like numbers, strings, and booleans in JavaScript.

Now consider an object in state:

```
const [position, setPosition] = useState({ x: 0, y: 0 });
```

Technically, it is possible to change the contents of *the object itself*. **This is called a mutation:**

```
position.x = 5;
```

However, although objects in React state are technically mutable, you should treat them **as if** they were immutable—like numbers, booleans, and strings. Instead of mutating them, you should always replace them.

## Treat state as read-only[](#treat-state-as-read-only "Link for Treat state as read-only ")

In other words, you should **treat any JavaScript object that you put into state as read-only.**

This example holds an object in state to represent the current pointer position. The red dot is supposed to move when you touch or move the cursor over the preview area. But the dot stays in the initial position:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function MovingDot() {
  const [position, setPosition] = useState({
    x: 0,
    y: 0
  });
  return (
    <div
      onPointerMove={e => {
        position.x = e.clientX;
        position.y = e.clientY;
      }}
      style={{
        position: 'relative',
        width: '100vw',
        height: '100vh',
      }}>
      <div style={{
        position: 'absolute',
        backgroundColor: 'red',
        borderRadius: '50%',
        transform: `translate(${position.x}px, ${position.y}px)`,
        left: -10,
        top: -10,
        width: 20,
        height: 20,
      }} />
    </div>
  );
}
```

The problem is with this bit of code.

```
onPointerMove={e => {

  position.x = e.clientX;

  position.y = e.clientY;

}}
```

This code modifies the object assigned to `position` from [the previous render.](/learn/state-as-a-snapshot#rendering-takes-a-snapshot-in-time) But without using the state setting function, React has no idea that object has changed. So React does not do anything in response. It’s like trying to change the order after you’ve already eaten the meal. While mutating state can work in some cases, we don’t recommend it. You should treat the state value you have access to in a render as read-only.

To actually [trigger a re-render](/learn/state-as-a-snapshot#setting-state-triggers-renders) in this case, **create a *new* object and pass it to the state setting function:**

```
onPointerMove={e => {

  setPosition({

    x: e.clientX,

    y: e.clientY

  });

}}
```

With `setPosition`, you’re telling React:

* Replace `position` with this new object
* And render this component again

Notice how the red dot now follows your pointer when you touch or hover over the preview area:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function MovingDot() {
  const [position, setPosition] = useState({
    x: 0,
    y: 0
  });
  return (
    <div
      onPointerMove={e => {
        setPosition({
          x: e.clientX,
          y: e.clientY
        });
      }}
      style={{
        position: 'relative',
        width: '100vw',
        height: '100vh',
      }}>
      <div style={{
        position: 'absolute',
        backgroundColor: 'red',
        borderRadius: '50%',
        transform: `translate(${position.x}px, ${position.y}px)`,
        left: -10,
        top: -10,
        width: 20,
        height: 20,
      }} />
    </div>
  );
}
```

##### Deep Dive#### Local mutation is fine[](#local-mutation-is-fine "Link for Local mutation is fine ")

Code like this is a problem because it modifies an *existing* object in state:

```
position.x = e.clientX;

position.y = e.clientY;
```

But code like this is **absolutely fine** because you’re mutating a fresh object you have *just created*:

```
const nextPosition = {};

nextPosition.x = e.clientX;

nextPosition.y = e.clientY;

setPosition(nextPosition);
```

In fact, it is completely equivalent to writing this:

```
setPosition({

  x: e.clientX,

  y: e.clientY

});
```

Mutation is only a problem when you change *existing* objects that are already in state. Mutating an object you’ve just created is okay because *no other code references it yet.* Changing it isn’t going to accidentally impact something that depends on it. This is called a “local mutation”. You can even do local mutation [while rendering.](/learn/keeping-components-pure#local-mutation-your-components-little-secret) Very convenient and completely okay!

## Copying objects with the spread syntax[](#copying-objects-with-the-spread-syntax "Link for Copying objects with the spread syntax ")

In the previous example, the `position` object is always created fresh from the current cursor position. But often, you will want to include *existing* data as a part of the new object you’re creating. For example, you may want to update *only one* field in a form, but keep the previous values for all other fields.

These input fields don’t work because the `onChange` handlers mutate the state:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function Form() {
  const [person, setPerson] = useState({
    firstName: 'Barbara',
    lastName: 'Hepworth',
    email: 'bhepworth@sculpture.com'
  });

  function handleFirstNameChange(e) {
    person.firstName = e.target.value;
  }

  function handleLastNameChange(e) {
    person.lastName = e.target.value;
  }

  function handleEmailChange(e) {
    person.email = e.target.value;
  }

  return (
    <>
      <label>
        First name:
        <input
          value={person.firstName}
          onChange={handleFirstNameChange}
        />
      </label>
      <label>
        Last name:
        <input
          value={person.lastName}
          onChange={handleLastNameChange}
        />
      </label>
      <label>
        Email:
        <input
          value={person.email}
          onChange={handleEmailChange}
        />
      </label>
      <p>
        {person.firstName}{' '}
        {person.lastName}{' '}
        ({person.email})
      </p>
    </>
  );
}
```

For example, this line mutates the state from a past render:

```
person.firstName = e.target.value;
```

The reliable way to get the behavior you’re looking for is to create a new object and pass it to `setPerson`. But here, you want to also **copy the existing data into it** because only one of the fields has changed:

```
setPerson({

  firstName: e.target.value, // New first name from the input

  lastName: person.lastName,

  email: person.email

});
```

You can use the `...` [object spread](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax#spread_in_object_literals) syntax so that you don’t need to copy every property separately.

```
setPerson({

  ...person, // Copy the old fields

  firstName: e.target.value // But override this one

});
```

Now the form works!

Notice how you didn’t declare a separate state variable for each input field. For large forms, keeping all data grouped in an object is very convenient—as long as you update it correctly!

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function Form() {
  const [person, setPerson] = useState({
    firstName: 'Barbara',
    lastName: 'Hepworth',
    email: 'bhepworth@sculpture.com'
  });

  function handleFirstNameChange(e) {
    setPerson({
      ...person,
      firstName: e.target.value
    });
  }

  function handleLastNameChange(e) {
    setPerson({
      ...person,
      lastName: e.target.value
    });
  }

  function handleEmailChange(e) {
    setPerson({
      ...person,
      email: e.target.value
    });
  }

  return (
    <>
      <label>
        First name:
        <input
          value={person.firstName}
          onChange={handleFirstNameChange}
        />
      </label>
      <label>
        Last name:
        <input
          value={person.lastName}
          onChange={handleLastNameChange}
        />
      </label>
      <label>
        Email:
        <input
          value={person.email}
          onChange={handleEmailChange}
        />
      </label>
      <p>
        {person.firstName}{' '}
        {person.lastName}{' '}
        ({person.email})
      </p>
    </>
  );
}
```

Note that the `...` spread syntax is “shallow”—it only copies things one level deep. This makes it fast, but it also means that if you want to update a nested property, you’ll have to use it more than once.

##### Deep Dive#### Using a single event handler for multiple fields[](#using-a-single-event-handler-for-multiple-fields "Link for Using a single event handler for multiple fields ")

You can also use the `[` and `]` braces inside your object definition to specify a property with a dynamic name. Here is the same example, but with a single event handler instead of three different ones:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function Form() {
  const [person, setPerson] = useState({
    firstName: 'Barbara',
    lastName: 'Hepworth',
    email: 'bhepworth@sculpture.com'
  });

  function handleChange(e) {
    setPerson({
      ...person,
      [e.target.name]: e.target.value
    });
  }

  return (
    <>
      <label>
        First name:
        <input
          name="firstName"
          value={person.firstName}
          onChange={handleChange}
        />
      </label>
      <label>
        Last name:
        <input
          name="lastName"
          value={person.lastName}
          onChange={handleChange}
        />
      </label>
      <label>
        Email:
        <input
          name="email"
          value={person.email}
          onChange={handleChange}
        />
      </label>
      <p>
        {person.firstName}{' '}
        {person.lastName}{' '}
        ({person.email})
      </p>
    </>
  );
}
```

Here, `e.target.name` refers to the `name` property given to the `<input>` DOM element.

## Updating a nested object[](#updating-a-nested-object "Link for Updating a nested object ")

Consider a nested object structure like this:

```
const [person, setPerson] = useState({

  name: 'Niki de Saint Phalle',

  artwork: {

    title: 'Blue Nana',

    city: 'Hamburg',

    image: 'https://react.dev/images/docs/scientists/Sd1AgUOm.jpg',

  }

});
```

If you wanted to update `person.artwork.city`, it’s clear how to do it with mutation:

```
person.artwork.city = 'New Delhi';
```

But in React, you treat state as immutable! In order to change `city`, you would first need to produce the new `artwork` object (pre-populated with data from the previous one), and then produce the new `person` object which points at the new `artwork`:

```
const nextArtwork = { ...person.artwork, city: 'New Delhi' };

const nextPerson = { ...person, artwork: nextArtwork };

setPerson(nextPerson);
```

Or, written as a single function call:

```
setPerson({

  ...person, // Copy other fields

  artwork: { // but replace the artwork

    ...person.artwork, // with the same one

    city: 'New Delhi' // but in New Delhi!

  }

});
```

This gets a bit wordy, but it works fine for many cases:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function Form() {
  const [person, setPerson] = useState({
    name: 'Niki de Saint Phalle',
    artwork: {
      title: 'Blue Nana',
      city: 'Hamburg',
      image: 'https://react.dev/images/docs/scientists/Sd1AgUOm.jpg',
    }
  });

  function handleNameChange(e) {
    setPerson({
      ...person,
      name: e.target.value
    });
  }

  function handleTitleChange(e) {
    setPerson({
      ...person,
      artwork: {
        ...person.artwork,
        title: e.target.value
      }
    });
  }

  function handleCityChange(e) {
    setPerson({
      ...person,
      artwork: {
        ...person.artwork,
        city: e.target.value
      }
    });
  }

  function handleImageChange(e) {
    setPerson({
      ...person,
      artwork: {
        ...person.artwork,
        image: e.target.value
      }
    });
  }

  return (
    <>
      <label>
        Name:
        <input
          value={person.name}
          onChange={handleNameChange}
        />
      </label>
      <label>
        Title:
        <input
          value={person.artwork.title}
          onChange={handleTitleChange}
        />
      </label>
      <label>
        City:
        <input
          value={person.artwork.city}
          onChange={handleCityChange}
        />
      </label>
      <label>
        Image:
        <input
          value={person.artwork.image}
          onChange={handleImageChange}
        />
      </label>
      <p>
        <i>{person.artwork.title}</i>
        {' by '}
        {person.name}
        <br />
        (located in {person.artwork.city})
      </p>
      <img
        src={person.artwork.image}
        alt={person.artwork.title}
      />
    </>
  );
}
```

##### Deep Dive#### Objects are not really nested[](#objects-are-not-really-nested "Link for Objects are not really nested ")

An object like this appears “nested” in code:

```
let obj = {

  name: 'Niki de Saint Phalle',

  artwork: {

    title: 'Blue Nana',

    city: 'Hamburg',

    image: 'https://react.dev/images/docs/scientists/Sd1AgUOm.jpg',

  }

};
```

However, “nesting” is an inaccurate way to think about how objects behave. When the code executes, there is no such thing as a “nested” object. You are really looking at two different objects:

```
let obj1 = {

  title: 'Blue Nana',

  city: 'Hamburg',

  image: 'https://react.dev/images/docs/scientists/Sd1AgUOm.jpg',

};



let obj2 = {

  name: 'Niki de Saint Phalle',

  artwork: obj1

};
```

The `obj1` object is not “inside” `obj2`. For example, `obj3` could “point” at `obj1` too:

```
let obj1 = {

  title: 'Blue Nana',

  city: 'Hamburg',

  image: 'https://react.dev/images/docs/scientists/Sd1AgUOm.jpg',

};



let obj2 = {

  name: 'Niki de Saint Phalle',

  artwork: obj1

};



let obj3 = {

  name: 'Copycat',

  artwork: obj1

};
```

If you were to mutate `obj3.artwork.city`, it would affect both `obj2.artwork.city` and `obj1.city`. This is because `obj3.artwork`, `obj2.artwork`, and `obj1` are the same object. This is difficult to see when you think of objects as “nested”. Instead, they are separate objects “pointing” at each other with properties.

### Write concise update logic with Immer[](#write-concise-update-logic-with-immer "Link for Write concise update logic with Immer ")

If your state is deeply nested, you might want to consider [flattening it.](/learn/choosing-the-state-structure#avoid-deeply-nested-state) But, if you don’t want to change your state structure, you might prefer a shortcut to nested spreads. [Immer](https://github.com/immerjs/use-immer) is a popular library that lets you write using the convenient but mutating syntax and takes care of producing the copies for you. With Immer, the code you write looks like you are “breaking the rules” and mutating an object:

```
updatePerson(draft => {

  draft.artwork.city = 'Lagos';

});
```

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
{
  "dependencies": {
    "immer": "1.7.3",
    "react": "latest",
    "react-dom": "latest",
    "react-scripts": "latest",
    "use-immer": "0.5.1"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject"
  },
  "devDependencies": {}
}
```

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function Scoreboard() {
  const [player, setPlayer] = useState({
    firstName: 'Ranjani',
    lastName: 'Shettar',
    score: 10,
  });

  function handlePlusClick() {
    player.score++;
  }

  function handleFirstNameChange(e) {
    setPlayer({
      ...player,
      firstName: e.target.value,
    });
  }

  function handleLastNameChange(e) {
    setPlayer({
      lastName: e.target.value
    });
  }

  return (
    <>
      <label>
        Score: <b>{player.score}</b>
        {' '}
        <button onClick={handlePlusClick}>
          +1
        </button>
      </label>
      <label>
        First name:
        <input
          value={player.firstName}
          onChange={handleFirstNameChange}
        />
      </label>
      <label>
        Last name:
        <input
          value={player.lastName}
          onChange={handleLastNameChange}
        />
      </label>
    </>
  );
}
```

[PreviousQueueing a Series of State Updates](/learn/queueing-a-series-of-state-updates)

[NextUpdating Arrays in State](/learn/updating-arrays-in-state)

***

----
url: https://react.dev/reference/react/forwardRef
----

[API Reference](/reference/react)

[Legacy React APIs](/reference/react/legacy)

# forwardRef[](#undefined "Link for this heading")

### Deprecated

In React 19, `forwardRef` is no longer necessary. Pass `ref` as a prop instead.

`forwardRef` will be deprecated in a future release. Learn more [here](/blog/2024/04/25/react-19#ref-as-a-prop).

`forwardRef` lets your component expose a DOM node to the parent component with a [ref.](/learn/manipulating-the-dom-with-refs)

```
const SomeComponent = forwardRef(render)
```

***

## Reference[](#reference "Link for Reference ")

### `forwardRef(render)`[](#forwardref "Link for this heading")

Call `forwardRef()` to let your component receive a ref and forward it to a child component:

```
import { forwardRef } from 'react';



const MyInput = forwardRef(function MyInput(props, ref) {

  // ...

});
```

***

### `render` function[](#render-function "Link for this heading")

`forwardRef` accepts a render function as an argument. React calls this function with `props` and `ref`:

```
const MyInput = forwardRef(function MyInput(props, ref) {

  return (

    <label>

      {props.label}

      <input ref={ref} />

    </label>

  );

});
```

#### Parameters[](#render-parameters "Link for Parameters ")

* `props`: The props passed by the parent component.

* `ref`: The `ref` attribute passed by the parent component. The `ref` can be an object or a function. If the parent component has not passed a ref, it will be `null`. You should either pass the `ref` you receive to another component, or pass it to [`useImperativeHandle`.](/reference/react/useImperativeHandle)

#### Returns[](#render-returns "Link for Returns ")

`forwardRef` returns a React component that you can render in JSX. Unlike React components defined as plain functions, the component returned by `forwardRef` is able to take a `ref` prop.

***

## Usage[](#usage "Link for Usage ")

### Exposing a DOM node to the parent component[](#exposing-a-dom-node-to-the-parent-component "Link for Exposing a DOM node to the parent component ")

By default, each component’s DOM nodes are private. However, sometimes it’s useful to expose a DOM node to the parent—for example, to allow focusing it. To opt in, wrap your component definition into `forwardRef()`:

```
import { forwardRef } from 'react';



const MyInput = forwardRef(function MyInput(props, ref) {

  const { label, ...otherProps } = props;

  return (

    <label>

      {label}

      <input {...otherProps} />

    </label>

  );

});
```

You will receive a ref as the second argument after props. Pass it to the DOM node that you want to expose:

```
import { forwardRef } from 'react';



const MyInput = forwardRef(function MyInput(props, ref) {

  const { label, ...otherProps } = props;

  return (

    <label>

      {label}

      <input {...otherProps} ref={ref} />

    </label>

  );

});
```

This lets the parent `Form` component access the `<input>` DOM node exposed by `MyInput`:

```
function Form() {

  const ref = useRef(null);



  function handleClick() {

    ref.current.focus();

  }



  return (

    <form>

      <MyInput label="Enter your name:" ref={ref} />

      <button type="button" onClick={handleClick}>

        Edit

      </button>

    </form>

  );

}
```

This `Form` component [passes a ref](/reference/react/useRef#manipulating-the-dom-with-a-ref) to `MyInput`. The `MyInput` component *forwards* that ref to the `<input>` browser tag. As a result, the `Form` component can access that `<input>` DOM node and call [`focus()`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus) on it.

Keep in mind that exposing a ref to the DOM node inside your component makes it harder to change your component’s internals later. You will typically expose DOM nodes from reusable low-level components like buttons or text inputs, but you won’t do it for application-level components like an avatar or a comment.

#### Examples of forwarding a ref[](#examples "Link for Examples of forwarding a ref")

#### Example 1 of 2:Focusing a text input[](#focusing-a-text-input "Link for this heading")

Clicking the button will focus the input. The `Form` component defines a ref and passes it to the `MyInput` component. The `MyInput` component forwards that ref to the browser `<input>`. This lets the `Form` component focus the `<input>`.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useRef } from 'react';
import MyInput from './MyInput.js';

export default function Form() {
  const ref = useRef(null);

  function handleClick() {
    ref.current.focus();
  }

  return (
    <form>
      <MyInput label="Enter your name:" ref={ref} />
      <button type="button" onClick={handleClick}>
        Edit
      </button>
    </form>
  );
}
```

***

### Forwarding a ref through multiple components[](#forwarding-a-ref-through-multiple-components "Link for Forwarding a ref through multiple components ")

Instead of forwarding a `ref` to a DOM node, you can forward it to your own component like `MyInput`:

```
const FormField = forwardRef(function FormField(props, ref) {

  // ...

  return (

    <>

      <MyInput ref={ref} />

      ...

    </>

  );

});
```

If that `MyInput` component forwards a ref to its `<input>`, a ref to `FormField` will give you that `<input>`:

```
function Form() {

  const ref = useRef(null);



  function handleClick() {

    ref.current.focus();

  }



  return (

    <form>

      <FormField label="Enter your name:" ref={ref} isRequired={true} />

      <button type="button" onClick={handleClick}>

        Edit

      </button>

    </form>

  );

}
```

The `Form` component defines a ref and passes it to `FormField`. The `FormField` component forwards that ref to `MyInput`, which forwards it to a browser `<input>` DOM node. This is how `Form` accesses that DOM node.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useRef } from 'react';
import FormField from './FormField.js';

export default function Form() {
  const ref = useRef(null);

  function handleClick() {
    ref.current.focus();
  }

  return (
    <form>
      <FormField label="Enter your name:" ref={ref} isRequired={true} />
      <button type="button" onClick={handleClick}>
        Edit
      </button>
    </form>
  );
}
```

***

### Exposing an imperative handle instead of a DOM node[](#exposing-an-imperative-handle-instead-of-a-dom-node "Link for Exposing an imperative handle instead of a DOM node ")

Instead of exposing an entire DOM node, you can expose a custom object, called an *imperative handle,* with a more constrained set of methods. To do this, you’d need to define a separate ref to hold the DOM node:

```
const MyInput = forwardRef(function MyInput(props, ref) {

  const inputRef = useRef(null);



  // ...



  return <input {...props} ref={inputRef} />;

});
```

Pass the `ref` you received to [`useImperativeHandle`](/reference/react/useImperativeHandle) and specify the value you want to expose to the `ref`:

```
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} />;

});
```

If some component gets a ref to `MyInput`, it will only receive your `{ focus, scrollIntoView }` object instead of the DOM node. This lets you limit the information you expose about your DOM node to the minimum.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useRef } from 'react';
import MyInput from './MyInput.js';

export default function Form() {
  const ref = useRef(null);

  function handleClick() {
    ref.current.focus();
    // This won't work because the DOM node isn't exposed:
    // ref.current.style.opacity = 0.5;
  }

  return (
    <form>
      <MyInput placeholder="Enter your name" ref={ref} />
      <button type="button" onClick={handleClick}>
        Edit
      </button>
    </form>
  );
}
```

[Read more about using imperative handles.](/reference/react/useImperativeHandle)

### Pitfall

**Do not overuse refs.** You should only use refs for *imperative* behaviors that you can’t express as props: for example, scrolling to a node, focusing a node, triggering an animation, selecting text, and so on.

**If you can express something as a prop, you should not use a ref.** For example, instead of exposing an imperative handle like `{ open, close }` from a `Modal` component, it is better to take `isOpen` as a prop like `<Modal isOpen={isOpen} />`. [Effects](/learn/synchronizing-with-effects) can help you expose imperative behaviors via props.

***

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### My component is wrapped in `forwardRef`, but the `ref` to it is always `null`[](#my-component-is-wrapped-in-forwardref-but-the-ref-to-it-is-always-null "Link for this heading")

This usually means that you forgot to actually use the `ref` that you received.

For example, this component doesn’t do anything with its `ref`:

```
const MyInput = forwardRef(function MyInput({ label }, ref) {

  return (

    <label>

      {label}

      <input />

    </label>

  );

});
```

To fix it, pass the `ref` down to a DOM node or another component that can accept a ref:

```
const MyInput = forwardRef(function MyInput({ label }, ref) {

  return (

    <label>

      {label}

      <input ref={ref} />

    </label>

  );

});
```

The `ref` to `MyInput` could also be `null` if some of the logic is conditional:

```
const MyInput = forwardRef(function MyInput({ label, showInput }, ref) {

  return (

    <label>

      {label}

      {showInput && <input ref={ref} />}

    </label>

  );

});
```

If `showInput` is `false`, then the ref won’t be forwarded to any node, and a ref to `MyInput` will remain empty. This is particularly easy to miss if the condition is hidden inside another component, like `Panel` in this example:

```
const MyInput = forwardRef(function MyInput({ label, showInput }, ref) {

  return (

    <label>

      {label}

      <Panel isExpanded={showInput}>

        <input ref={ref} />

      </Panel>

    </label>

  );

});
```

[PreviouscreateRef](/reference/react/createRef)

[NextisValidElement](/reference/react/isValidElement)

***

----
url: https://18.react.dev/reference/rsc/server-actions
----

[API Reference](/reference/react)

# Server Actions[](#undefined "Link for this heading")

Server Actions allow Client Components to call async functions executed on the server.

* [Creating a Server Action from a Server Component](#creating-a-server-action-from-a-server-component)
* [Importing Server Actions from Client Components](#importing-server-actions-from-client-components)
* [Composing Server Actions with Actions](#composing-server-actions-with-actions)
* [Form Actions with Server Actions](#form-actions-with-server-actions)
* [Server Actions with `useActionState`](#server-actions-with-use-action-state)
* [Progressive enhancement with `useActionState`](#progressive-enhancement-with-useactionstate)

### Note

#### How do I build support for Server Actions?[](#how-do-i-build-support-for-server-actions "Link for How do I build support for Server Actions? ")

While Server Actions in React 19 are stable and will not break between major versions, the underlying APIs used to implement Server Actions in a React Server Components bundler or framework do not follow semver and may break between minors in React 19.x.

To support Server Actions as a bundler or framework, we recommend pinning to a specific React version, or using the Canary release. We will continue working with bundlers and frameworks to stabilize the APIs used to implement Server Actions in the future.

When a Server Action is defined with the `"use server"` directive, your framework will automatically create a reference to the server function, and pass that reference to the Client Component. When that function is called on the client, React will send a request to the server to execute the function, and return the result.

Server Actions can be created in Server Components and passed as props to Client Components, or they can be imported and used in Client Components.

### Creating a Server Action from a Server Component[](#creating-a-server-action-from-a-server-component "Link for Creating a Server Action from a Server Component ")

Server Components can define Server Actions with the `"use server"` directive:

```
// Server Component

import Button from './Button';



function EmptyNote () {

  async function createNoteAction() {

    // Server Action

    'use server';

    

    await db.notes.create();

  }



  return <Button onClick={createNoteAction}/>;

}
```

When React renders the `EmptyNote` Server Component, it will create a reference to the `createNoteAction` function, and pass that reference to the `Button` Client Component. When the button is clicked, React will send a request to the server to execute the `createNoteAction` function with the reference provided:

```
"use client";



export default function Button({onClick}) { 

  console.log(onClick); 

  // {$$typeof: Symbol.for("react.server.reference"), $$id: 'createNoteAction'}

  return <button onClick={() => onClick()}>Create Empty Note</button>

}
```

For more, see the docs for [`"use server"`](/reference/rsc/use-server).

### Importing Server Actions from Client Components[](#importing-server-actions-from-client-components "Link for Importing Server Actions from Client Components ")

Client Components can import Server Actions from files that use the `"use server"` directive:

```
"use server";



export async function createNoteAction() {

  await db.notes.create();

}
```

When the bundler builds the `EmptyNote` Client Component, it will create a reference to the `createNoteAction` function in the bundle. When the `button` is clicked, React will send a request to the server to execute the `createNoteAction` function using the reference provided:

```
"use client";

import {createNoteAction} from './actions';



function EmptyNote() {

  console.log(createNoteAction);

  // {$$typeof: Symbol.for("react.server.reference"), $$id: 'createNoteAction'}

  return <button onClick={createNoteAction} />

}
```

For more, see the docs for [`"use server"`](/reference/rsc/use-server).

### Composing Server Actions with Actions[](#composing-server-actions-with-actions "Link for Composing Server Actions with Actions ")

Server Actions can be composed with Actions on the client:

```
"use server";



export async function updateName(name) {

  if (!name) {

    return {error: 'Name is required'};

  }

  await db.users.updateName(name);

}
```

```
"use client";



import {updateName} from './actions';



function UpdateName() {

  const [name, setName] = useState('');

  const [error, setError] = useState(null);



  const [isPending, startTransition] = useTransition();



  const submitAction = async () => {

    startTransition(async () => {

      const {error} = await updateName(name);

      if (!error) {

        setError(error);

      } else {

        setName('');

      }

    })

  }

  

  return (

    <form action={submitAction}>

      <input type="text" name="name" disabled={isPending}/>

      {state.error && <span>Failed: {state.error}</span>}

    </form>

  )

}
```

This allows you to access the `isPending` state of the Server Action by wrapping it in an Action on the client.

For more, see the docs for [Calling a Server Action outside of `<form>`](/reference/rsc/use-server#calling-a-server-action-outside-of-form)

### Form Actions with Server Actions[](#form-actions-with-server-actions "Link for Form Actions with Server Actions ")

Server Actions work with the new Form features in React 19.

You can pass a Server Action to a Form to automatically submit the form to the server:

```
"use client";



import {updateName} from './actions';



function UpdateName() {

  return (

    <form action={updateName}>

      <input type="text" name="name" />

    </form>

  )

}
```

When the Form submission succeeds, React will automatically reset the form. You can add `useActionState` to access the pending state, last response, or to support progressive enhancement.

For more, see the docs for [Server Actions in Forms](/reference/rsc/use-server#server-actions-in-forms).

### Server Actions with `useActionState`[](#server-actions-with-use-action-state "Link for this heading")

You can compose Server Actions with `useActionState` for the common case where you just need access to the action pending state and last returned response:

```
"use client";



import {updateName} from './actions';



function UpdateName() {

  const [state, submitAction, isPending] = useActionState(updateName, {error: null});



  return (

    <form action={submitAction}>

      <input type="text" name="name" disabled={isPending}/>

      {state.error && <span>Failed: {state.error}</span>}

    </form>

  );

}
```

When using `useActionState` with Server Actions, React will also automatically replay form submissions entered before hydration finishes. This means users can interact with your app even before the app has hydrated.

For more, see the docs for [`useActionState`](/reference/react-dom/hooks/useFormState).

### Progressive enhancement with `useActionState`[](#progressive-enhancement-with-useactionstate "Link for this heading")

Server Actions also support progressive enhancement with the third argument of `useActionState`.

```
"use client";



import {updateName} from './actions';



function UpdateName() {

  const [, submitAction] = useActionState(updateName, null, `/name/update`);



  return (

    <form action={submitAction}>

      ...

    </form>

  );

}
```

When the permalink is provided to `useActionState`, React will redirect to the provided URL if the form is submitted before the JavaScript bundle loads.

For more, see the docs for [`useActionState`](/reference/react-dom/hooks/useFormState).

[PreviousServer Components](/reference/rsc/server-components)

[NextDirectives](/reference/rsc/directives)

***

----
url: https://18.react.dev/reference/react-dom/server/renderToStaticMarkup
----

[API Reference](/reference/react)

[Server APIs](/reference/react-dom/server)

# renderToStaticMarkup[](#undefined "Link for this heading")

`renderToStaticMarkup` renders a non-interactive React tree to an HTML string.

```
const html = renderToStaticMarkup(reactNode, options?)
```

* [Reference](#reference)
  * [`renderToStaticMarkup(reactNode, options?)`](#rendertostaticmarkup)
* [Usage](#usage)
  * [Rendering a non-interactive React tree as HTML to a string](#rendering-a-non-interactive-react-tree-as-html-to-a-string)

***

## Reference[](#reference "Link for Reference ")

### `renderToStaticMarkup(reactNode, options?)`[](#rendertostaticmarkup "Link for this heading")

On the server, call `renderToStaticMarkup` to render your app to HTML.

```
import { renderToStaticMarkup } from 'react-dom/server';



const html = renderToStaticMarkup(<Page />);
```

***

## Usage[](#usage "Link for Usage ")

### Rendering a non-interactive React tree as HTML to a string[](#rendering-a-non-interactive-react-tree-as-html-to-a-string "Link for Rendering a non-interactive React tree as HTML to a string ")

Call `renderToStaticMarkup` to render your app to an HTML string which you can send with your server response:

```
import { renderToStaticMarkup } from 'react-dom/server';



// The route handler syntax depends on your backend framework

app.use('/', (request, response) => {

  const html = renderToStaticMarkup(<Page />);

  response.send(html);

});
```

This will produce the initial non-interactive HTML output of your React components.

### Pitfall

This method renders **non-interactive HTML that cannot be hydrated.** This is useful if you want to use React as a simple static page generator, or if you’re rendering completely static content like emails.

Interactive apps should use [`renderToString`](/reference/react-dom/server/renderToString) on the server and [`hydrateRoot`](/reference/react-dom/client/hydrateRoot) on the client.

[PreviousrenderToReadableStream](/reference/react-dom/server/renderToReadableStream)

[NextrenderToStaticNodeStream](/reference/react-dom/server/renderToStaticNodeStream)

***

----
url: https://legacy.reactjs.org/docs/forwarding-refs.html
----

> These docs are old and won’t be updated. Go to [react.dev](https://react.dev/) for the new React docs.
>
> These new documentation pages teach modern React and include live examples:
>
> * [Manipulating the DOM with Refs](https://react.dev/learn/manipulating-the-dom-with-refs)
> * [`forwardRef`](https://react.dev/reference/react/forwardRef)

Ref forwarding is a technique for automatically passing a [ref](/docs/refs-and-the-dom.html) through a component to one of its children. This is typically not necessary for most components in the application. However, it can be useful for some kinds of components, especially in reusable component libraries. The most common scenarios are described below.

## [](#forwarding-refs-to-dom-components)Forwarding refs to DOM components

Consider a `FancyButton` component that renders the native `button` DOM element:

```
function FancyButton(props) {
  return (
    <button className="FancyButton">
      {props.children}
    </button>
  );
}
```

React components hide their implementation details, including their rendered output. Other components using `FancyButton` **usually will not need to** [obtain a ref](/docs/refs-and-the-dom.html) to the inner `button` DOM element. This is good because it prevents components from relying on each other’s DOM structure too much.

Although such encapsulation is desirable for application-level components like `FeedStory` or `Comment`, it can be inconvenient for highly reusable “leaf” components like `FancyButton` or `MyTextInput`. These components tend to be used throughout the application in a similar manner as a regular DOM `button` and `input`, and accessing their DOM nodes may be unavoidable for managing focus, selection, or animations.

**Ref forwarding is an opt-in feature that lets some components take a `ref` they receive, and pass it further down (in other words, “forward” it) to a child.**

In the example below, `FancyButton` uses `React.forwardRef` to obtain the `ref` passed to it, and then forward it to the DOM `button` that it renders:

```
const FancyButton = React.forwardRef((props, ref) => (  <button ref={ref} className="FancyButton">    {props.children}
  </button>
));

// You can now get a ref directly to the DOM button:
const ref = React.createRef();
<FancyButton ref={ref}>Click me!</FancyButton>;
```

This way, components using `FancyButton` can get a ref to the underlying `button` DOM node and access it if necessary—just like if they used a DOM `button` directly.

Here is a step-by-step explanation of what happens in the above example:

1. We create a [React ref](/docs/refs-and-the-dom.html) by calling `React.createRef` and assign it to a `ref` variable.
2. We pass our `ref` down to `<FancyButton ref={ref}>` by specifying it as a JSX attribute.
3. React passes the `ref` to the `(props, ref) => ...` function inside `forwardRef` as a second argument.
4. We forward this `ref` argument down to `<button ref={ref}>` by specifying it as a JSX attribute.
5. When the ref is attached, `ref.current` will point to the `<button>` DOM node.

> Note
>
> The second `ref` argument only exists when you define a component with `React.forwardRef` call. Regular function or class components don’t receive the `ref` argument, and ref is not available in props either.
>
> Ref forwarding is not limited to DOM components. You can forward refs to class component instances, too.

## [](#note-for-component-library-maintainers)Note for component library maintainers

**When you start using `forwardRef` in a component library, you should treat it as a breaking change and release a new major version of your library.** This is because your library likely has an observably different behavior (such as what refs get assigned to, and what types are exported), and this can break apps and other libraries that depend on the old behavior.

Conditionally applying `React.forwardRef` when it exists is also not recommended for the same reasons: it changes how your library behaves and can break your users’ apps when they upgrade React itself.

## [](#forwarding-refs-in-higher-order-components)Forwarding refs in higher-order components

This technique can also be particularly useful with [higher-order components](/docs/higher-order-components.html) (also known as HOCs). Let’s start with an example HOC that logs component props to the console:

```
function logProps(WrappedComponent) {  class LogProps extends React.Component {
    componentDidUpdate(prevProps) {
      console.log('old props:', prevProps);
      console.log('new props:', this.props);
    }

    render() {
      return <WrappedComponent {...this.props} />;    }
  }

  return LogProps;
}
```

The “logProps” HOC passes all `props` through to the component it wraps, so the rendered output will be the same. For example, we can use this HOC to log all props that get passed to our “fancy button” component:

```
class FancyButton extends React.Component {
  focus() {
    // ...
  }

  // ...
}

// Rather than exporting FancyButton, we export LogProps.
// It will render a FancyButton though.
export default logProps(FancyButton);
```

There is one caveat to the above example: refs will not get passed through. That’s because `ref` is not a prop. Like `key`, it’s handled differently by React. If you add a ref to a HOC, the ref will refer to the outermost container component, not the wrapped component.

This means that refs intended for our `FancyButton` component will actually be attached to the `LogProps` component:

```
import FancyButton from './FancyButton';

const ref = React.createRef();
// The FancyButton component we imported is the LogProps HOC.
// Even though the rendered output will be the same,
// Our ref will point to LogProps instead of the inner FancyButton component!
// This means we can't call e.g. ref.current.focus()
<FancyButton
  label="Click Me"
  handleClick={handleClick}
  ref={ref}/>;
```

Fortunately, we can explicitly forward refs to the inner `FancyButton` component using the `React.forwardRef` API. `React.forwardRef` accepts a render function that receives `props` and `ref` parameters and returns a React node. For example:

```
function logProps(Component) {
  class LogProps extends React.Component {
    componentDidUpdate(prevProps) {
      console.log('old props:', prevProps);
      console.log('new props:', this.props);
    }

    render() {
      const {forwardedRef, ...rest} = this.props;
      // Assign the custom prop "forwardedRef" as a ref
      return <Component ref={forwardedRef} {...rest} />;    }
  }

  // Note the second param "ref" provided by React.forwardRef.
  // We can pass it along to LogProps as a regular prop, e.g. "forwardedRef"
  // And it can then be attached to the Component.
  return React.forwardRef((props, ref) => {    return <LogProps {...props} forwardedRef={ref} />;  });}
```

## [](#displaying-a-custom-name-in-devtools)Displaying a custom name in DevTools

`React.forwardRef` accepts a render function. React DevTools uses this function to determine what to display for the ref forwarding component.

For example, the following component will appear as ”*ForwardRef*” in the DevTools:

```
const WrappedComponent = React.forwardRef((props, ref) => {
  return <LogProps {...props} forwardedRef={ref} />;
});
```

If you name the render function, DevTools will also include its name (e.g. ”*ForwardRef(myFunction)*”):

```
const WrappedComponent = React.forwardRef(
  function myFunction(props, ref) {
    return <LogProps {...props} forwardedRef={ref} />;
  }
);
```

You can even set the function’s `displayName` property to include the component you’re wrapping:

```
function logProps(Component) {
  class LogProps extends React.Component {
    // ...
  }

  function forwardRef(props, ref) {
    return <LogProps {...props} forwardedRef={ref} />;
  }

  // Give this component a more helpful display name in DevTools.
  // e.g. "ForwardRef(logProps(MyComponent))"
  const name = Component.displayName || Component.name;  forwardRef.displayName = `logProps(${name})`;
  return React.forwardRef(forwardRef);
}
```

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/forwarding-refs.md)

----
url: https://legacy.reactjs.org/blog/2015/03/16/react-v0.13.1.html
----

March 16, 2015 by [Paul O’Shannessy](https://twitter.com/zpao)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

It’s been less than a week since we shipped v0.13.0 but it’s time to do another quick release. We just released v0.13.1 which contains bugfixes for a number of small issues.

Thanks all of you who have been upgrading your applications and taking the time to report issues. And a huge thank you to those of you who submitted pull requests for the issues you found! 2 of the 6 fixes that went out today came from people who aren’t on the core team!

The release is now available for download:

* **React**\
  Dev build with warnings: <https://fb.me/react-0.13.1.js>\
  Minified build for production: <https://fb.me/react-0.13.1.min.js>
* **React with Add-Ons**\
  Dev build with warnings: <https://fb.me/react-with-addons-0.13.1.js>\
  Minified build for production: <https://fb.me/react-with-addons-0.13.1.min.js>
* **In-Browser JSX transformer**\
  <https://fb.me/JSXTransformer-0.13.1.js>

We’ve also published version `0.13.1` of the `react` and `react-tools` packages on npm and the `react` package on bower.

***

## [](#changelog)Changelog

### [](#react-core)React Core

#### [](#bug-fixes)Bug Fixes

* Don’t throw when rendering empty `<select>` elements
* Ensure updating `style` works when transitioning from `null`

### [](#react-with-add-ons)React with Add-Ons

#### [](#bug-fixes-1)Bug Fixes

* TestUtils: Don’t warn about `getDOMNode` for ES6 classes
* TestUtils: Ensure wrapped full page components (`<html>`, `<head>`, `<body>`) are treated as DOM components
* Perf: Stop double-counting DOM components

### [](#react-tools)React Tools

#### [](#bug-fixes-2)Bug Fixes

* Fix option parsing for `--non-strict-es6module`

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2015-03-16-react-v0.13.1.md)

----
url: https://18.react.dev/reference/react/useLayoutEffect
----

[API Reference](/reference/react)

[Hooks](/reference/react/hooks)

# useLayoutEffect[](#undefined "Link for this heading")

### Pitfall

`useLayoutEffect` can hurt performance. Prefer [`useEffect`](/reference/react/useEffect) when possible.

`useLayoutEffect` is a version of [`useEffect`](/reference/react/useEffect) that fires before the browser repaints the screen.

```
useLayoutEffect(setup, dependencies?)
```

* [Reference](#reference)
  * [`useLayoutEffect(setup, dependencies?)`](#useinsertioneffect)
* [Usage](#usage)
  * [Measuring layout before the browser repaints the screen](#measuring-layout-before-the-browser-repaints-the-screen)
* [Troubleshooting](#troubleshooting)
  * [I’m getting an error: “`useLayoutEffect` does nothing on the server”](#im-getting-an-error-uselayouteffect-does-nothing-on-the-server)

***

## Reference[](#reference "Link for Reference ")

### `useLayoutEffect(setup, dependencies?)`[](#useinsertioneffect "Link for this heading")

Call `useLayoutEffect` to perform the layout measurements before the browser repaints the screen:

```
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);

  }, []);

  // ...
```

[See more examples below.](#usage)

#### Parameters[](#parameters "Link for Parameters ")

* `setup`: The function with your Effect’s logic. Your setup function may also optionally return a *cleanup* function. Before your component is added to the DOM, React will run your setup function. After every re-render with changed dependencies, React will first run the cleanup function (if you provided it) with the old values, and then run your setup function with the new values. Before your component is removed from the DOM, React will run your cleanup function.

* **optional** `dependencies`: The list of all reactive values referenced inside of the `setup` code. Reactive values include props, state, and all the variables and functions declared directly inside your component body. If your linter is [configured for React](/learn/editor-setup#linting), it will verify that every reactive value is correctly specified as a dependency. The list of dependencies must have a constant number of items and be written inline like `[dep1, dep2, dep3]`. React will compare each dependency with its previous value using the [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) comparison. If you omit this argument, your Effect will re-run after every re-render of the component.

***

```
function Tooltip() {

  const ref = useRef(null);

  const [tooltipHeight, setTooltipHeight] = useState(0); // You don't know real height yet



  useLayoutEffect(() => {

    const { height } = ref.current.getBoundingClientRect();

    setTooltipHeight(height); // Re-render now that you know the real height

  }, []);



  // ...use tooltipHeight in the rendering logic below...

}
```

```
import { useRef, useLayoutEffect, useState } from 'react';
import { createPortal } from 'react-dom';
import TooltipContainer from './TooltipContainer.js';

export default function Tooltip({ children, targetRect }) {
  const ref = useRef(null);
  const [tooltipHeight, setTooltipHeight] = useState(0);

  useLayoutEffect(() => {
    const { height } = ref.current.getBoundingClientRect();
    setTooltipHeight(height);
    console.log('Measured tooltip height: ' + height);
  }, []);

  let tooltipX = 0;
  let tooltipY = 0;
  if (targetRect !== null) {
    tooltipX = targetRect.left;
    tooltipY = targetRect.top - tooltipHeight;
    if (tooltipY < 0) {
      // It doesn't fit above, so place below.
      tooltipY = targetRect.bottom;
    }
  }

  return createPortal(
    <TooltipContainer x={tooltipX} y={tooltipY} contentRef={ref}>
      {children}
    </TooltipContainer>,
    document.body
  );
}
```

Notice that even though the `Tooltip` component has to render in two passes (first, with `tooltipHeight` initialized to `0` and then with the real measured height), you only see the final result. This is why you need `useLayoutEffect` instead of [`useEffect`](/reference/react/useEffect) for this example. Let’s look at the difference in detail below.

#### useLayoutEffect vs useEffect[](#examples "Link for useLayoutEffect vs useEffect")

#### Example 1 of 2:`useLayoutEffect` blocks the browser from repainting[](#uselayouteffect-blocks-the-browser-from-repainting "Link for this heading")

React guarantees that the code inside `useLayoutEffect` and any state updates scheduled inside it will be processed **before the browser repaints the screen.** This lets you render the tooltip, measure it, and re-render the tooltip again without the user noticing the first extra render. In other words, `useLayoutEffect` blocks the browser from painting.

```
import { useRef, useLayoutEffect, useState } from 'react';
import { createPortal } from 'react-dom';
import TooltipContainer from './TooltipContainer.js';

export default function Tooltip({ children, targetRect }) {
  const ref = useRef(null);
  const [tooltipHeight, setTooltipHeight] = useState(0);

  useLayoutEffect(() => {
    const { height } = ref.current.getBoundingClientRect();
    setTooltipHeight(height);
  }, []);

  let tooltipX = 0;
  let tooltipY = 0;
  if (targetRect !== null) {
    tooltipX = targetRect.left;
    tooltipY = targetRect.top - tooltipHeight;
    if (tooltipY < 0) {
      // It doesn't fit above, so place below.
      tooltipY = targetRect.bottom;
    }
  }

  return createPortal(
    <TooltipContainer x={tooltipX} y={tooltipY} contentRef={ref}>
      {children}
    </TooltipContainer>,
    document.body
  );
}
```

### Note

Rendering in two passes and blocking the browser hurts performance. Try to avoid this when you can.

***

***

----
url: https://18.react.dev/community/team
----

[TheSavior](https://github.com/TheSavior)

Lauren’s programming career peaked when she first discovered the `<marquee>` tag. She’s been chasing that high ever since. She studied Finance instead of CS in college, so she learned to code using Excel instead of Java. Lauren enjoys dropping cheeky memes in chat, playing video games with her partner, and petting her dog Zelda.

[potetotes](https://twitter.com/potetotes)

[potetotes](https://threads.net/potetotes)

[no.lol](https://bsky.app/profile/no.lol)

[poteto](https://github.com/poteto)

### Luna Wei[](#luna-wei "Link for Luna Wei")

Engineer at Meta

Luna first learnt the fundamentals of python at the age of 6 from her father. Since then, she has been unstoppable. Luna aspires to be a gen z, and the road to success is paved with environmental advocacy, urban gardening and lots of quality time with her Voo-Doo’d (as pictured).

[lunaleaps](https://twitter.com/lunaleaps)

[lunaleaps](https://threads.net/lunaleaps)

[lunaleaps](https://github.com/lunaleaps)

### Matt Carroll[](#matt-carroll "Link for Matt Carroll")

Developer Advocate at Meta

Matt stumbled into coding, and since then, has become enamored with creating things in communities that can’t be created alone. Prior to React, he worked on YouTube, the Google Assistant, Fuchsia, and Google Cloud AI and Evernote. When he’s not trying to make better developer tools he enjoys the mountains, jazz, and spending time with his family.

[mattcarrollcode](https://twitter.com/mattcarrollcode)

[mattcarrollcode](https://threads.net/mattcarrollcode)

[mattcarrollcode](https://github.com/mattcarrollcode)

### Mofei Zhang[](#mofei-zhang "Link for Mofei Zhang")

Engineer at Meta

Mofei started programming when she realized it can help her cheat in video games. She focused on operating systems in undergrad / grad school, but now finds herself happily tinkering on React. Outside of work, she enjoys debugging bouldering problems and planning her next backpacking trip(s).

[z\_mofei](https://threads.net/z_mofei)

[mofeiZ](https://github.com/mofeiZ)

### Noah Lemen[](#noah-lemen "Link for Noah Lemen")

Engineer at Meta

Noah’s interest in UI programming sparked during his education in music technology at NYU. At Meta, he’s worked on internal tools, browsers, web performance, and is currently focused on React. Outside of work, Noah can be found tinkering with synthesizers or spending time with his cat.

[noahlemen](https://twitter.com/noahlemen)

[noahlemen](https://threads.net/noahlemen)

[noahlemen](https://github.com/noahlemen)

[noahle.men](https://noahle.men)


### Sathya Gunasekaran[](#sathya-gunasekaran "Link for Sathya Gunasekaran ")

Engineer at Meta

Sathya hated the Dragon Book in school but somehow ended up working on compilers all his career. When he’s not compiling React components, he’s either drinking coffee or eating yet another Dosa.

[\_gsathya](https://twitter.com/_gsathya)

[gsathya.03](https://threads.net/gsathya.03)

[gsathya](https://github.com/gsathya)

### Tianyu Yao[](#tianyu-yao "Link for Tianyu Yao")

Engineer at Meta

Tianyu’s interest in computers started as a kid because he loves video games. So he majored in computer science and still plays childish games like League of Legends. When he is not in front of a computer, he enjoys playing with his two kittens, hiking and kayaking.

[tianyu0](https://twitter.com/tianyu0)

[tyao1](https://github.com/tyao1)


***

----
url: https://18.react.dev/learn/manipulating-the-dom-with-refs
----

```
import { useRef } from 'react';
```

Then, use it to declare a ref inside your component:

```
const myRef = useRef(null);
```

Finally, pass your ref as the `ref` attribute to the JSX tag for which you want to get the DOM node:

```
<div ref={myRef}>
```

The `useRef` Hook returns an object with a single property called `current`. Initially, `myRef.current` will be `null`. When React creates a DOM node for this `<div>`, React will put a reference to this node into `myRef.current`. You can then access this DOM node from your [event handlers](/learn/responding-to-events) and use the built-in [browser APIs](https://developer.mozilla.org/docs/Web/API/Element) defined on it.

```
// You can use any browser APIs, for example:

myRef.current.scrollIntoView();
```

### Example: Focusing a text input[](#example-focusing-a-text-input "Link for Example: Focusing a text input ")

In this example, clicking the button will focus the input:

```
import { useRef } from 'react';

export default function Form() {
  const inputRef = useRef(null);

  function handleClick() {
    inputRef.current.focus();
  }

  return (
    <>
      <input ref={inputRef} />
      <button onClick={handleClick}>
        Focus the input
      </button>
    </>
  );
}
```

```
import { useRef } from 'react';

export default function CatFriends() {
  const firstCatRef = useRef(null);
  const secondCatRef = useRef(null);
  const thirdCatRef = useRef(null);

  function handleScrollToFirstCat() {
    firstCatRef.current.scrollIntoView({
      behavior: 'smooth',
      block: 'nearest',
      inline: 'center'
    });
  }

  function handleScrollToSecondCat() {
    secondCatRef.current.scrollIntoView({
      behavior: 'smooth',
      block: 'nearest',
      inline: 'center'
    });
  }

  function handleScrollToThirdCat() {
    thirdCatRef.current.scrollIntoView({
      behavior: 'smooth',
      block: 'nearest',
      inline: 'center'
    });
  }

  return (
    <>
      <nav>
        <button onClick={handleScrollToFirstCat}>
          Neo
        </button>
        <button onClick={handleScrollToSecondCat}>
          Millie
        </button>
        <button onClick={handleScrollToThirdCat}>
          Bella
        </button>
      </nav>
      <div>
        <ul>
          <li>
            <img
              src="https://placecats.com/neo/300/200"
              alt="Neo"
              ref={firstCatRef}
            />
          </li>
          <li>
            <img
              src="https://placecats.com/millie/200/200"
              alt="Millie"
              ref={secondCatRef}
            />
          </li>
          <li>
            <img
              src="https://placecats.com/bella/199/200"
              alt="Bella"
              ref={thirdCatRef}
            />
          </li>
        </ul>
      </div>
    </>
  );
}
```

##### Deep Dive#### How to manage a list of refs using a ref callback[](#how-to-manage-a-list-of-refs-using-a-ref-callback "Link for How to manage a list of refs using a ref callback ")

In the above examples, there is a predefined number of refs. However, sometimes you might need a ref to each item in the list, and you don’t know how many you will have. Something like this **wouldn’t work**:

```
<ul>

  {items.map((item) => {

    // Doesn't work!

    const ref = useRef(null);

    return <li ref={ref} />;

  })}

</ul>
```

This is because **Hooks must only be called at the top-level of your component.** You can’t call `useRef` in a loop, in a condition, or inside a `map()` call.

One possible way around this is to get a single ref to their parent element, and then use DOM manipulation methods like [`querySelectorAll`](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll) to “find” the individual child nodes from it. However, this is brittle and can break if your DOM structure changes.

Another solution is to **pass a function to the `ref` attribute.** This is called a [`ref` callback.](/reference/react-dom/components/common#ref-callback) React will call your ref callback with the DOM node when it’s time to set the ref, and with `null` when it’s time to clear it. This lets you maintain your own array or a [Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map), and access any ref by its index or some kind of ID.

This example shows how you can use this approach to scroll to an arbitrary node in a long list:

```
import { useRef, useState } from "react";

export default function CatFriends() {
  const itemsRef = useRef(null);
  const [catList, setCatList] = useState(setupCatList);

  function scrollToCat(cat) {
    const map = getMap();
    const node = map.get(cat);
    node.scrollIntoView({
      behavior: "smooth",
      block: "nearest",
      inline: "center",
    });
  }

  function getMap() {
    if (!itemsRef.current) {
      // Initialize the Map on first usage.
      itemsRef.current = new Map();
    }
    return itemsRef.current;
  }

  return (
    <>
      <nav>
        <button onClick={() => scrollToCat(catList[0])}>Neo</button>
        <button onClick={() => scrollToCat(catList[5])}>Millie</button>
        <button onClick={() => scrollToCat(catList[9])}>Bella</button>
      </nav>
      <div>
        <ul>
          {catList.map((cat) => (
            <li
              key={cat}
              ref={(node) => {
                const map = getMap();
                if (node) {
                  map.set(cat, node);
                } else {
                  map.delete(cat);
                }
              }}
            >
              <img src={cat} />
            </li>
          ))}
        </ul>
      </div>
    </>
  );
}

function setupCatList() {
  const catList = [];
  for (let i = 0; i < 10; i++) {
    catList.push("https://loremflickr.com/320/240/cat?lock=" + i);
  }

  return catList;
}
```

In this example, `itemsRef` doesn’t hold a single DOM node. Instead, it holds a [Map](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Map) from item ID to a DOM node. ([Refs can hold any values!](/learn/referencing-values-with-refs)) The [`ref` callback](/reference/react-dom/components/common#ref-callback) on every list item takes care to update the Map:

```
<li

  key={cat.id}

  ref={node => {

    const map = getMap();

    if (node) {

      // Add to the Map

      map.set(cat, node);

    } else {

      // Remove from the Map

      map.delete(cat);

    }

  }}

>
```

This lets you read individual DOM nodes from the Map later.

### Canary

This example shows another approach for managing the Map with a `ref` callback cleanup function.

```
<li

  key={cat.id}

  ref={node => {

    const map = getMap();

    // Add to the Map

    map.set(cat, node);



    return () => {

      // Remove from the Map

      map.delete(cat);

    };

  }}

>
```

## Accessing another component’s DOM nodes[](#accessing-another-components-dom-nodes "Link for Accessing another component’s DOM nodes ")

When you put a ref on a built-in component that outputs a browser element like `<input />`, React will set that ref’s `current` property to the corresponding DOM node (such as the actual `<input />` in the browser).

However, if you try to put a ref on **your own** component, like `<MyInput />`, by default you will get `null`. Here is an example demonstrating it. Notice how clicking the button **does not** focus the input:

```
import { useRef } from 'react';

function MyInput(props) {
  return <input {...props} />;
}

export default function MyForm() {
  const inputRef = useRef(null);

  function handleClick() {
    inputRef.current.focus();
  }

  return (
    <>
      <MyInput ref={inputRef} />
      <button onClick={handleClick}>
        Focus the input
      </button>
    </>
  );
}
```

To help you notice the issue, React also prints an error to the console:

Console

Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?

This happens because by default React does not let a component access the DOM nodes of other components. Not even for its own children! This is intentional. Refs are an escape hatch that should be used sparingly. Manually manipulating *another* component’s DOM nodes makes your code even more fragile.

Instead, components that *want* to expose their DOM nodes have to **opt in** to that behavior. A component can specify that it “forwards” its ref to one of its children. Here’s how `MyInput` can use the `forwardRef` API:

```
const MyInput = forwardRef((props, ref) => {

  return <input {...props} ref={ref} />;

});
```

This is how it works:

1. `<MyInput ref={inputRef} />` tells React to put the corresponding DOM node into `inputRef.current`. However, it’s up to the `MyInput` component to opt into that—by default, it doesn’t.
2. The `MyInput` component is declared using `forwardRef`. **This opts it into receiving the `inputRef` from above as the second `ref` argument** which is declared after `props`.
3. `MyInput` itself passes the `ref` it received to the `<input>` inside of it.

Now clicking the button to focus the input works:

```
import { forwardRef, useRef } from 'react';

const MyInput = forwardRef((props, ref) => {
  return <input {...props} ref={ref} />;
});

export default function Form() {
  const inputRef = useRef(null);

  function handleClick() {
    inputRef.current.focus();
  }

  return (
    <>
      <MyInput ref={inputRef} />
      <button onClick={handleClick}>
        Focus the input
      </button>
    </>
  );
}
```

In design systems, it is a common pattern for low-level components like buttons, inputs, and so on, to forward their refs to their DOM nodes. On the other hand, high-level components like forms, lists, or page sections usually won’t expose their DOM nodes to avoid accidental dependencies on the DOM structure.

##### Deep Dive#### Exposing a subset of the API with an imperative handle[](#exposing-a-subset-of-the-api-with-an-imperative-handle "Link for Exposing a subset of the API with an imperative handle ")

In the above example, `MyInput` exposes the original DOM input element. This lets the parent component call `focus()` on it. However, this also lets the parent component do something else—for example, change its CSS styles. In uncommon cases, you may want to restrict the exposed functionality. You can do that with `useImperativeHandle`:

```
import {
  forwardRef, 
  useRef, 
  useImperativeHandle
} from 'react';

const MyInput = forwardRef((props, ref) => {
  const realInputRef = useRef(null);
  useImperativeHandle(ref, () => ({
    // Only expose focus and nothing else
    focus() {
      realInputRef.current.focus();
    },
  }));
  return <input {...props} ref={realInputRef} />;
});

export default function Form() {
  const inputRef = useRef(null);

  function handleClick() {
    inputRef.current.focus();
  }

  return (
    <>
      <MyInput ref={inputRef} />
      <button onClick={handleClick}>
        Focus the input
      </button>
    </>
  );
}
```

Here, `realInputRef` inside `MyInput` holds the actual input DOM node. However, `useImperativeHandle` instructs React to provide your own special object as the value of a ref to the parent component. So `inputRef.current` inside the `Form` component will only have the `focus` method. In this case, the ref “handle” is not the DOM node, but the custom object you create inside `useImperativeHandle` call.

```
import { useState, useRef } from 'react';

export default function TodoList() {
  const listRef = useRef(null);
  const [text, setText] = useState('');
  const [todos, setTodos] = useState(
    initialTodos
  );

  function handleAdd() {
    const newTodo = { id: nextId++, text: text };
    setText('');
    setTodos([ ...todos, newTodo]);
    listRef.current.lastChild.scrollIntoView({
      behavior: 'smooth',
      block: 'nearest'
    });
  }

  return (
    <>
      <button onClick={handleAdd}>
        Add
      </button>
      <input
        value={text}
        onChange={e => setText(e.target.value)}
      />
      <ul ref={listRef}>
        {todos.map(todo => (
          <li key={todo.id}>{todo.text}</li>
        ))}
      </ul>
    </>
  );
}

let nextId = 0;
let initialTodos = [];
for (let i = 0; i < 20; i++) {
  initialTodos.push({
    id: nextId++,
    text: 'Todo #' + (i + 1)
  });
}
```

The issue is with these two lines:

```
setTodos([ ...todos, newTodo]);

listRef.current.lastChild.scrollIntoView();
```

In React, [state updates are queued.](/learn/queueing-a-series-of-state-updates) Usually, this is what you want. However, here it causes a problem because `setTodos` does not immediately update the DOM. So the time you scroll the list to its last element, the todo has not yet been added. This is why scrolling always “lags behind” by one item.

To fix this issue, you can force React to update (“flush”) the DOM synchronously. To do this, import `flushSync` from `react-dom` and **wrap the state update** into a `flushSync` call:

```
flushSync(() => {

  setTodos([ ...todos, newTodo]);

});

listRef.current.lastChild.scrollIntoView();
```

This will instruct React to update the DOM synchronously right after the code wrapped in `flushSync` executes. As a result, the last todo will already be in the DOM by the time you try to scroll to it:

```
import { useState, useRef } from 'react';
import { flushSync } from 'react-dom';

export default function TodoList() {
  const listRef = useRef(null);
  const [text, setText] = useState('');
  const [todos, setTodos] = useState(
    initialTodos
  );

  function handleAdd() {
    const newTodo = { id: nextId++, text: text };
    flushSync(() => {
      setText('');
      setTodos([ ...todos, newTodo]);      
    });
    listRef.current.lastChild.scrollIntoView({
      behavior: 'smooth',
      block: 'nearest'
    });
  }

  return (
    <>
      <button onClick={handleAdd}>
        Add
      </button>
      <input
        value={text}
        onChange={e => setText(e.target.value)}
      />
      <ul ref={listRef}>
        {todos.map(todo => (
          <li key={todo.id}>{todo.text}</li>
        ))}
      </ul>
    </>
  );
}

let nextId = 0;
let initialTodos = [];
for (let i = 0; i < 20; i++) {
  initialTodos.push({
    id: nextId++,
    text: 'Todo #' + (i + 1)
  });
}
```

## Best practices for DOM manipulation with refs[](#best-practices-for-dom-manipulation-with-refs "Link for Best practices for DOM manipulation with refs ")

Refs are an escape hatch. You should only use them when you have to “step outside React”. Common examples of this include managing focus, scroll position, or calling browser APIs that React does not expose.

If you stick to non-destructive actions like focusing and scrolling, you shouldn’t encounter any problems. However, if you try to **modify** the DOM manually, you can risk conflicting with the changes React is making.

To illustrate this problem, this example includes a welcome message and two buttons. The first button toggles its presence using [conditional rendering](/learn/conditional-rendering) and [state](/learn/state-a-components-memory), as you would usually do in React. The second button uses the [`remove()` DOM API](https://developer.mozilla.org/en-US/docs/Web/API/Element/remove) to forcefully remove it from the DOM outside of React’s control.

Try pressing “Toggle with setState” a few times. The message should disappear and appear again. Then press “Remove from the DOM”. This will forcefully remove it. Finally, press “Toggle with setState”:

```
import { useState, useRef } from 'react';

export default function Counter() {
  const [show, setShow] = useState(true);
  const ref = useRef(null);

  return (
    <div>
      <button
        onClick={() => {
          setShow(!show);
        }}>
        Toggle with setState
      </button>
      <button
        onClick={() => {
          ref.current.remove();
        }}>
        Remove from the DOM
      </button>
      {show && <p ref={ref}>Hello world</p>}
    </div>
  );
}
```

* A component doesn’t expose its DOM nodes by default. You can opt into exposing a DOM node by using `forwardRef` and passing the second `ref` argument down to a specific node.
* Avoid changing DOM nodes managed by React.
* If you do modify DOM nodes managed by React, modify parts that React has no reason to update.

## Try out some challenges[](#challenges "Link for Try out some challenges")

#### Challenge 1 of 4:Play and pause the video[](#play-and-pause-the-video "Link for this heading")

In this example, the button toggles a state variable to switch between a playing and a paused state. However, in order to actually play or pause the video, toggling state is not enough. You also need to call [`play()`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/play) and [`pause()`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/pause) on the DOM element for the `<video>`. Add a ref to it, and make the button work.

```
import { useState, useRef } from 'react';

export default function VideoPlayer() {
  const [isPlaying, setIsPlaying] = useState(false);

  function handleClick() {
    const nextIsPlaying = !isPlaying;
    setIsPlaying(nextIsPlaying);
  }

  return (
    <>
      <button onClick={handleClick}>
        {isPlaying ? 'Pause' : 'Play'}
      </button>
      <video width="250">
        <source
          src="https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4"
          type="video/mp4"
        />
      </video>
    </>
  )
}
```

For an extra challenge, keep the “Play” button in sync with whether the video is playing even if the user right-clicks the video and plays it using the built-in browser media controls. You might want to listen to `onPlay` and `onPause` on the video to do that.

[PreviousReferencing Values with Refs](/learn/referencing-values-with-refs)

[NextSynchronizing with Effects](/learn/synchronizing-with-effects)

***

----
url: https://legacy.reactjs.org/blog/2014/11/25/community-roundup-24.html
----

November 25, 2014 by [Steven Luscher](https://twitter.com/steveluscher)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

## [](#keep-it-simple)Keep it Simple

Pedro Nauck ([pedronauck](https://github.com/pedronauck)) delivered an impeccably illustrated deck at Brazil’s *Front in Floripa* conference. Watch him talk about how to keep delivering value as your app scales, by keeping your development process simple.

Murilo Pereira ([mpereira](https://github.com/mpereira)) tussles with the topic of complexity in this blog post about [coping with scaling up](http://www.techsonian.net/2014/09/from-backbone-to-react-our-experience-scaling-a-web-application/), where he describes how his team used React to make possible the “nearly impossible.”

I ([steveluscher](https://github.com/steveluscher)) spoke at Manning Publications’ “Powered By JavaScript” Strangeloop pre-conf in St. Louis. There, I proposed a new notation to talk about development complexity – Big-Coffee Notation ☕(n) – and spoke about the features of React that help keep our Big-Coffee from going quadratic, as our user interfaces get more complex.

James Pearce ([jamesgpearce](https://github.com/jamesgpearce)) carried Big-Coffee all the way to Raleigh, NC. At the *All Things Open* conference, he spoke about some of the design decisions that went into React, particularly those that lend themselves to simpler, more reliable code.

## [](#all-about-isomorphism)All About Isomorphism

Michael Ridgway ([mridgway](https://github.com/mridgway)) shows us how Yahoo! (who recently [moved Yahoo! Mail to React](http://www.slideshare.net/rmsguhan/react-meetup-mailonreact)) renders their React+Flux application, server-side.

Péter Márton ([hekike](https://github.com/hekike)) helps us brew a cold one (literally) using an application that’s server-client [isomorphic and indexable](http://blog.risingstack.com/from-angularjs-to-react-the-isomorphic-way/). Demo and sample code included – cold ones sold separately.

And, lest you think that client-server isomorphism exists in pursuit of crawalable, indexable HTML alone, watch as Nate Hunzaker ([nhunzaker](https://github.com/nhunzaker)) [server renders data visualizations as SVG](http://viget.com/extend/visualization-is-for-sharing-using-react-for-portable-data-visualization) with React.

## [](#react-router-mows-the-lawn)React Router Mows the Lawn

Ryan Florence ([rpflorence](https://github.com/rpflorence%5D)) and Michael Jackson ([mjackson](https://github.com/mjackson)) unveiled a new API for [React Router](https://github.com/rackt/react-router) that solves some of its user’s problems by eliminating the problems themselves. Read all about what React Router learned from its community of users, and how they’ve [rolled your ideas into their latest release](https://github.com/rackt/react-router/wiki/Announcements).

## [](#react-in-practice)React in Practice

Jonathan Beebe ([somethingkindawierd](https://github.com/somethingkindawierd)) spoke about how he uses React to build tools that deliver hope to those trying to make the best of a bad situation. Watch his talk from this year’s *Nodevember* conference in Nashville

If you take a peek under the covers, you’ll find that React powers [Carousel](https://blog.carousel.com/2014/11/introducing-carousel-for-web-ipad-and-android-tablet/), Dropbox’s new photo and video gallery app.

We enjoyed a cinematic/narrative experience with this React-powered, interactive story by British author William Boyd. Dive into “[The Vanishing Game](https://thevanishinggame.wellstoried.com)” and see for yourself.

## [](#be-kind-rewind)Be Kind, Rewind

Spend the next 60 seconds watching Daniel Woelfel ([dwwoelfel](https://github.com/dwwoelfel)) serialize a React app’s state as a string, then deserialize it to produce a working UI. Read about how he uses this technique to [reproduce bugs](http://blog.circleci.com/local-state-global-concerns/) reported to him by his users.

## [](#community-components)Community Components

Tom Chen ([tomchentw](https://github.com/tomchentw)) brings us a [react-google-maps](https://tomchentw.github.io/react-google-maps/) component, and a way to syntax highlight source code using Prism and the [react-prism](https://tomchentw.github.io/react-prism/) component, for good measure.

Jed Watson ([jedwatson](https://github.com/JedWatson)) helps you manage touch, tap, and press events using the [react-tappable](https://github.com/JedWatson/react-tappable) component.

To find these, and more community-built components, consult the [React Components](http://react-components.com/) and [React Rocks](http://react.rocks) component directories. React Rocks recently exceeded one-hundred listed components and counting. See one missing? Add the keyword `react-component` to your `package.json` to get listed on React Components, and [submit a link to React Rocks](https://docs.google.com/forms/d/1TpnwJmLcmmGj-_TI68upu_bKBViYeiKx7Aj9uKmV6wY/viewform).

## [](#waiter-theres-a-css-in-my-javascript)Waiter, There’s a CSS In My JavaScript

The internet is abuzz with talk of styling React components using JavaScript instead of CSS. Christopher Chedeau ([vjeux](https://github.com/vjeux)) talks about some of the [fundamental style management challenges](https://speakerdeck.com/vjeux/react-css-in-js) we grapple with, at Facebook scale. A number of implementations of JavaScript centric style management solutions have appeared in the wild, including the React-focused [react-style](https://github.com/js-next/react-style).

## [](#test-isolation)Test Isolation

Yahoo! shows us how they make use of `iframe` elements to [unit test React components in isolation](http://yahooeng.tumblr.com/post/102274727496/to-testutil-or-not-to-testutil).

## [](#youve-got-the-hang-of-flux-now-lets-flow)You’ve Got The Hang of Flux, Now Let’s Flow

Facebook Open Source released [Flow](https://code.facebook.com/posts/1505962329687926/flow-a-new-static-type-checker-for-javascript/) this month – a static type checker for JavaScript. Naturally, Flow supports JSX, and you can use it to [type check React applications](https://code.facebook.com/posts/1505962329687926/flow-a-new-static-type-checker-for-javascript/#compatibility). There’s never been a better reason to start making use of `propTypes` in your component specifications!

## [](#countdown-to-reactjs-conf-2014)Countdown to React.js Conf 2014

We’re counting down the days until [React.js Conf](http://conf.reactjs.com) at Facebook’s headquarters in Menlo Park, California, on January 28th & 29th, 2015. Thank you, to everyone who responded to the Call for Presenters. Mark the dates; tickets go on sale in three waves: at noon PST on November 28th, December 5th, and December 12th, 2014.

## [](#react-meetups-around-the-world)React Meetups Around the World

> React JS meetup having pretty good turn up rate today [#londonreact](https://twitter.com/hashtag/londonreact?src=hash) [pic.twitter.com/c360dlVVAe](http://t.co/c360dlVVAe)
>
> — Alexander Savin (@karismafilms) [November 19, 2014](https://twitter.com/karismafilms/status/535152580377468928)

> 60+ attendees at the second React.js Utah meetup. [@ryanflorence](https://twitter.com/ryanflorence) doing a great job, even without the internet. [pic.twitter.com/fV59AQTOyu](http://t.co/fV59AQTOyu)
>
> — ReactJS Utah (@reactjsutah) [October 29, 2014](https://twitter.com/reactjsutah/status/527259410020573184)

> [#ReactJS](https://twitter.com/hashtag/ReactJS?src=hash) meetup at [@Yahoo](https://twitter.com/Yahoo) ! History of [@yahoomail](https://twitter.com/yahoomail) and why we chose react and NodeJS [pic.twitter.com/Nm4EdTv45G](http://t.co/Nm4EdTv45G)
>
> — rmsguhan (@rmsguhan) [September 26, 2014](https://twitter.com/rmsguhan/status/515370950427029504)

> The very first ReactJS meetup in NYC tonight, I'll be speaking about the big ideas behind Om <http://t.co/dvPrFqE9eP>
>
> — David Nolen (@swannodette) [November 11, 2014](https://twitter.com/swannodette/status/532190993463128064)

> If anyone in Sydney is curious about [@reactjs](https://twitter.com/reactjs), I'm presenting at [@sydjs](https://twitter.com/sydjs) tonight on how to use it and why it is the future. [#javascript](https://twitter.com/hashtag/javascript?src=hash)
>
> — Jed Watson (@JedWatson) [November 19, 2014](https://twitter.com/JedWatson/status/534943557568565248)

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2014-11-25-community-roundup-24.md)

----
url: https://legacy.reactjs.org/blog/2013/10/16/react-v0.5.0.html
----

October 16, 2013 by [Paul O’Shannessy](https://twitter.com/zpao)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

This release is the result of several months of hard work from members of the team and the community. While there are no groundbreaking changes in core, we’ve worked hard to improve performance and memory usage. We’ve also worked hard to make sure we are being consistent in our usage of DOM properties.

The biggest change you’ll notice as a developer is that we no longer support `class` in JSX as a way to provide CSS classes. Since this prop was being converted to `className` at the transform step, it caused some confusion when trying to access it in composite components. As a result we decided to make our DOM properties mirror their counterparts in the JS DOM API. There are [a few exceptions](https://github.com/facebook/react/blob/main/src/dom/DefaultDOMPropertyConfig.js#L156) where we deviate slightly in an attempt to be consistent internally.

The other major change in v0.5 is that we’ve added an additional build - `react-with-addons` - which adds support for some extras that we’ve been working on including animations and two-way binding. [Read more about these addons in the docs](/docs/addons.html).

## [](#thanks-to-our-community)Thanks to Our Community

We added *22 new people* to the list of authors since we launched React v0.4.1 nearly 3 months ago. With a total of 48 names in our `AUTHORS` file, that means we’ve nearly doubled the number of contributors in that time period. We’ve seen the number of people contributing to discussion on IRC, mailing lists, Stack Overflow, and GitHub continue rising. We’ve also had people tell us about talks they’ve given in their local community about React.

It’s been awesome to see the things that people are building with React, and we can’t wait to see what you come up with next!

## [](#changelog)Changelog

### [](#react)React

* Memory usage improvements - reduced allocations in core which will help with GC pauses
* Performance improvements - in addition to speeding things up, we made some tweaks to stay out of slow path code in V8 and Nitro.
* Standardized prop -> DOM attribute process. This previously resulting in additional type checking and overhead as well as confusing cases for users. Now we will always convert your value to a string before inserting it into the DOM.
* Support for Selection events.
* Support for [Composition events](https://developer.mozilla.org/en-US/docs/Web/API/CompositionEvent).
* Support for additional DOM properties (`charSet`, `content`, `form`, `httpEquiv`, `rowSpan`, `autoCapitalize`).
* Support for additional SVG properties (`rx`, `ry`).
* Support for using `getInitialState` and `getDefaultProps` in mixins.
* Support mounting into iframes.
* Bug fixes for controlled form components.
* Bug fixes for SVG element creation.
* Added `React.version`.
* Added `React.isValidClass` - Used to determine if a value is a valid component constructor.
* Removed `React.autoBind` - This was deprecated in v0.4 and now properly removed.
* Renamed `React.unmountAndReleaseReactRootNode` to `React.unmountComponentAtNode`.
* Began laying down work for refined performance analysis.
* Better support for server-side rendering - [react-page](https://github.com/facebook/react-page) has helped improve the stability for server-side rendering.
* Made it possible to use React in environments enforcing a strict [Content Security Policy](https://developer.mozilla.org/en-US/docs/Security/CSP/Introducing_Content_Security_Policy). This also makes it possible to use React to build Chrome extensions.

### [](#react-with-addons-new)React with Addons (New!)

* Introduced a separate build with several “addons” which we think can help improve the React experience. We plan to deprecate this in the long-term, instead shipping each as standalone pieces. [Read more in the docs](/docs/addons.html).

### [](#jsx)JSX

* No longer transform `class` to `className` as part of the transform! This is a breaking change - if you were using `class`, you *must* change this to `className` or your components will be visually broken.
* Added warnings to the in-browser transformer to make it clear it is not intended for production use.
* Improved compatibility for Windows
* Improved support for maintaining line numbers when transforming.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2013-10-16-react-v0.5.0.md)

----
url: https://react.dev/reference/react/experimental_taintUniqueValue
----

[API Reference](/reference/react)

[APIs](/reference/react/apis)

# experimental\_taintUniqueValue[](#undefined "Link for this heading")

### Experimental Feature

```
taintUniqueValue(errMessage, lifetime, value)
```

To prevent passing an object containing sensitive data, see [`taintObjectReference`](/reference/react/experimental_taintObjectReference).

* [Reference](#reference)
  * [`taintUniqueValue(message, lifetime, value)`](#taintuniquevalue)
* [Usage](#usage)
  * [Prevent a token from being passed to Client Components](#prevent-a-token-from-being-passed-to-client-components)

***

## Reference[](#reference "Link for Reference ")

### `taintUniqueValue(message, lifetime, value)`[](#taintuniquevalue "Link for this heading")

Call `taintUniqueValue` with a password, token, key or hash to register it with React as something that should not be allowed to be passed to the Client as is:

```
import {experimental_taintUniqueValue} from 'react';



experimental_taintUniqueValue(

  'Do not pass secret keys to the client.',

  process,

  process.env.SECRET_KEY

);
```

***

## Usage[](#usage "Link for Usage ")

### Prevent a token from being passed to Client Components[](#prevent-a-token-from-being-passed-to-client-components "Link for Prevent a token from being passed to Client Components ")

To ensure that sensitive information such as passwords, session tokens, or other unique values do not inadvertently get passed to Client Components, the `taintUniqueValue` function provides a layer of protection. When a value is tainted, any attempt to pass it to a Client Component will result in an error.

The `lifetime` argument defines the duration for which the value remains tainted. For values that should remain tainted indefinitely, objects like [`globalThis`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/globalThis) or `process` can serve as the `lifetime` argument. These objects have a lifespan that spans the entire duration of your app’s execution.

```
import {experimental_taintUniqueValue} from 'react';



experimental_taintUniqueValue(

  'Do not pass a user password to the client.',

  globalThis,

  process.env.SECRET_KEY

);
```

If the tainted value’s lifespan is tied to a object, the `lifetime` should be the object that encapsulates the value. This ensures the tainted value remains protected for the lifetime of the encapsulating object.

```
import {experimental_taintUniqueValue} from 'react';



export async function getUser(id) {

  const user = await db`SELECT * FROM users WHERE id = ${id}`;

  experimental_taintUniqueValue(

    'Do not pass a user session token to the client.',

    user,

    user.session.token

  );

  return user;

}
```

In this example, the `user` object serves as the `lifetime` argument. If this object gets stored in a global cache or is accessible by another request, the session token remains tainted.

### Pitfall

**Do not rely solely on tainting for security.** Tainting a value doesn’t block every possible derived value. For example, creating a new value by upper casing a tainted string will not taint the new value.

```
import {experimental_taintUniqueValue} from 'react';



const password = 'correct horse battery staple';



experimental_taintUniqueValue(

  'Do not pass the password to the client.',

  globalThis,

  password

);



const uppercasePassword = password.toUpperCase() // `uppercasePassword` is not tainted
```

In this example, the constant `password` is tainted. Then `password` is used to create a new value `uppercasePassword` by calling the `toUpperCase` method on `password`. The newly created `uppercasePassword` is not tainted.

Other similar ways of deriving new values from tainted values like concatenating it into a larger string, converting it to base64, or returning a substring create untained values.

Tainting only protects against simple mistakes like explicitly passing secret values to the client. Mistakes in calling the `taintUniqueValue` like using a global store outside of React, without the corresponding lifetime object, can cause the tainted value to become untainted. Tainting is a layer of protection; a secure app will have multiple layers of protection, well designed APIs, and isolation patterns.

##### Deep Dive#### Using `server-only` and `taintUniqueValue` to prevent leaking secrets[](#using-server-only-and-taintuniquevalue-to-prevent-leaking-secrets "Link for this heading")

If you’re running a Server Components environment that has access to private keys or passwords such as database passwords, you have to be careful not to pass that to a Client Component.

```
export async function Dashboard(props) {

  // DO NOT DO THIS

  return <Overview password={process.env.API_PASSWORD} />;

}
```

```
"use client";



import {useEffect} from '...'



export async function Overview({ password }) {

  useEffect(() => {

    const headers = { Authorization: password };

    fetch(url, { headers }).then(...);

  }, [password]);

  ...

}
```

This example would leak the secret API token to the client. If this API token can be used to access data this particular user shouldn’t have access to, it could lead to a data breach.

Ideally, secrets like this are abstracted into a single helper file that can only be imported by trusted data utilities on the server. The helper can even be tagged with [`server-only`](https://www.npmjs.com/package/server-only) to ensure that this file isn’t imported on the client.

```
import "server-only";



export function fetchAPI(url) {

  const headers = { Authorization: process.env.API_PASSWORD };

  return fetch(url, { headers });

}
```

Sometimes mistakes happen during refactoring and not all of your colleagues might know about this. To protect against this mistakes happening down the line we can “taint” the actual password:

```
import "server-only";

import {experimental_taintUniqueValue} from 'react';



experimental_taintUniqueValue(

  'Do not pass the API token password to the client. ' +

    'Instead do all fetches on the server.'

  process,

  process.env.API_PASSWORD

);
```

Now whenever anyone tries to pass this password to a Client Component, or send the password to a Client Component with a Server Function, an error will be thrown with message you defined when you called `taintUniqueValue`.

***

[Previousexperimental\_taintObjectReference](/reference/react/experimental_taintObjectReference)

***

----
url: https://react.dev/blog/2023/03/22/react-labs-what-we-have-been-working-on-march-2023
----

[Blog](/blog)

# React Labs: What We've Been Working On – March 2023[](#undefined "Link for this heading")

March 22, 2023 by [Joseph Savona](https://twitter.com/en_JS), [Josh Story](https://twitter.com/joshcstory), [Lauren Tan](https://twitter.com/potetotes), [Mengdi Chen](https://twitter.com/mengdi_en), [Samuel Susla](https://twitter.com/SamuelSusla), [Sathya Gunasekaran](https://twitter.com/_gsathya), [Sebastian Markbåge](https://twitter.com/sebmarkbage), and [Andrew Clark](https://twitter.com/acdlite)

***

In React Labs posts, we write about projects in active research and development. We’ve made significant progress on them since our [last update](/blog/2022/06/15/react-labs-what-we-have-been-working-on-june-2022), and we’d like to share what we learned.

***

## React Server Components[](#react-server-components "Link for React Server Components ")

React Server Components (or RSC) is a new application architecture designed by the React team.

We’ve first shared our research on RSC in an [introductory talk](/blog/2020/12/21/data-fetching-with-react-server-components) and an [RFC](https://github.com/reactjs/rfcs/pull/188). To recap them, we are introducing a new kind of component—Server Components—that run ahead of time and are excluded from your JavaScript bundle. Server Components can run during the build, letting you read from the filesystem or fetch static content. They can also run on the server, letting you access your data layer without having to build an API. You can pass data by props from Server Components to the interactive Client Components in the browser.

RSC combines the simple “request/response” mental model of server-centric Multi-Page Apps with the seamless interactivity of client-centric Single-Page Apps, giving you the best of both worlds.

Since our last update, we have merged the [React Server Components RFC](https://github.com/reactjs/rfcs/blob/main/text/0188-server-components.md) to ratify the proposal. We resolved outstanding issues with the [React Server Module Conventions](https://github.com/reactjs/rfcs/blob/main/text/0227-server-module-conventions.md) proposal, and reached consensus with our partners to go with the `"use client"` convention. These documents also act as specification for what an RSC-compatible implementation should support.

The biggest change is that we introduced [`async` / `await`](https://github.com/reactjs/rfcs/pull/229) as the primary way to do data fetching from Server Components. We also plan to support data loading from the client by introducing a new Hook called `use` that unwraps Promises. Although we can’t support `async / await` in arbitrary components in client-only apps, we plan to add support for it when you structure your client-only app similar to how RSC apps are structured.

Now that we have data fetching pretty well sorted, we’re exploring the other direction: sending data from the client to the server, so that you can execute database mutations and implement forms. We’re doing this by letting you pass Server Action functions across the server/client boundary, which the client can then call, providing seamless RPC. Server Actions also give you progressively enhanced forms before JavaScript loads.

React Server Components has shipped in [Next.js App Router](/learn/creating-a-react-app#nextjs-app-router). This showcases a deep integration of a router that really buys into RSC as a primitive, but it’s not the only way to build a RSC-compatible router and framework. There’s a clear separation for features provided by the RSC spec and implementation. React Server Components is meant as a spec for components that work across compatible React frameworks.

We generally recommend using an existing framework, but if you need to build your own custom framework, it is possible. Building your own RSC-compatible framework is not as easy as we’d like it to be, mainly due to the deep bundler integration needed. The current generation of bundlers are great for use on the client, but they weren’t designed with first-class support for splitting a single module graph between the server and the client. This is why we’re now partnering directly with bundler developers to get the primitives for RSC built-in.

## Asset Loading[](#asset-loading "Link for Asset Loading ")

[Suspense](/reference/react/Suspense) lets you specify what to display on the screen while the data or code for your components is still being loaded. This lets your users progressively see more content while the page is loading as well as during the router navigations that load more data and code. However, from the user’s perspective, data loading and rendering do not tell the whole story when considering whether new content is ready. By default, browsers load stylesheets, fonts, and images independently, which can lead to UI jumps and consecutive layout shifts.

We’re working to fully integrate Suspense with the loading lifecycle of stylesheets, fonts, and images, so that React takes them into account to determine whether the content is ready to be displayed. Without any change to the way you author your React components, updates will behave in a more coherent and pleasing manner. As an optimization, we will also provide a manual way to preload assets like fonts directly from components.

We are currently implementing these features and will have more to share soon.

## Document Metadata[](#document-metadata "Link for Document Metadata ")

Different pages and screens in your app may have different metadata like the `<title>` tag, description, and other `<meta>` tags specific to this screen. From the maintenance perspective, it’s more scalable to keep this information close to the React component for that page or screen. However, the HTML tags for this metadata need to be in the document `<head>` which is typically rendered in a component at the very root of your app.

Today, people solve this problem with one of the two techniques.

One technique is to render a special third-party component that moves `<title>`, `<meta>`, and other tags inside it into the document `<head>`. This works for major browsers but there are many clients which do not run client-side JavaScript, such as Open Graph parsers, and so this technique is not universally suitable.

Another technique is to server-render the page in two parts. First, the main content is rendered and all such tags are collected. Then, the `<head>` is rendered with these tags. Finally, the `<head>` and the main content are sent to the browser. This approach works, but it prevents you from taking advantage of the [React 18’s Streaming Server Renderer](/reference/react-dom/server/renderToReadableStream) because you’d have to wait for all content to render before sending the `<head>`.

This is why we’re adding built-in support for rendering `<title>`, `<meta>`, and metadata `<link>` tags anywhere in your component tree out of the box. It would work the same way in all environments, including fully client-side code, SSR, and in the future, RSC. We will share more details about this soon.

## React Optimizing Compiler[](#react-optimizing-compiler "Link for React Optimizing Compiler ")

Since our previous update we’ve been actively iterating on the design of [React Forget](/blog/2022/06/15/react-labs-what-we-have-been-working-on-june-2022#react-compiler), an optimizing compiler for React. We’ve previously talked about it as an “auto-memoizing compiler”, and that is true in some sense. But building the compiler has helped us understand React’s programming model even more deeply. A better way to understand React Forget is as an automatic *reactivity* compiler.

The core idea of React is that developers define their UI as a function of the current state. You work with plain JavaScript values — numbers, strings, arrays, objects — and use standard JavaScript idioms — if/else, for, etc — to describe your component logic. The mental model is that React will re-render whenever the application state changes. We believe this simple mental model and keeping close to JavaScript semantics is an important principle in React’s programming model.

The catch is that React can sometimes be *too* reactive: it can re-render too much. For example, in JavaScript we don’t have cheap ways to compare if two objects or arrays are equivalent (having the same keys and values), so creating a new object or array on each render may cause React to do more work than it strictly needs to. This means developers have to explicitly memoize components so as to not over-react to changes.

Our goal with React Forget is to ensure that React apps have just the right amount of reactivity by default: that apps re-render only when state values *meaningfully* change. From an implementation perspective this means automatically memoizing, but we believe that the reactivity framing is a better way to understand React and Forget. One way to think about this is that React currently re-renders when object identity changes. With Forget, React re-renders when the semantic value changes — but without incurring the runtime cost of deep comparisons.

In terms of concrete progress, since our last update we have substantially iterated on the design of the compiler to align with this automatic reactivity approach and to incorporate feedback from using the compiler internally. After some significant refactors to the compiler starting late last year, we’ve now begun using the compiler in production in limited areas at Meta. We plan to open-source it once we’ve proved it in production.

Finally, a lot of people have expressed interest in how the compiler works. We’re looking forward to sharing a lot more details when we prove the compiler and open-source it. But there are a few bits we can share now:

The core of the compiler is almost completely decoupled from Babel, and the core compiler API is (roughly) old AST in, new AST out (while retaining source location data). Under the hood we use a custom code representation and transformation pipeline in order to do low-level semantic analysis. However, the primary public interface to the compiler will be via Babel and other build system plugins. For ease of testing we currently have a Babel plugin which is a very thin wrapper that calls the compiler to generate a new version of each function and swap it in.

As we refactored the compiler over the last few months, we wanted to focus on refining the core compilation model to ensure we could handle complexities such as conditionals, loops, reassignment, and mutation. However, JavaScript has a lot of ways to express each of those features: if/else, ternaries, for, for-in, for-of, etc. Trying to support the full language up-front would have delayed the point where we could validate the core model. Instead, we started with a small but representative subset of the language: let/const, if/else, for loops, objects, arrays, primitives, function calls, and a few other features. As we gained confidence in the core model and refined our internal abstractions, we expanded the supported language subset. We’re also explicit about syntax we don’t yet support, logging diagnostics and skipping compilation for unsupported input. We have utilities to try the compiler on Meta’s codebases and see what unsupported features are most common so we can prioritize those next. We’ll continue incrementally expanding towards supporting the whole language.

Making plain JavaScript in React components reactive requires a compiler with a deep understanding of semantics so that it can understand exactly what the code is doing. By taking this approach, we’re creating a system for reactivity within JavaScript that lets you write product code of any complexity with the full expressivity of the language, instead of being limited to a domain specific language.

## Offscreen Rendering[](#offscreen-rendering "Link for Offscreen Rendering ")

Offscreen rendering is an upcoming capability in React for rendering screens in the background without additional performance overhead. You can think of it as a version of the [`content-visibility` CSS property](https://developer.mozilla.org/en-US/docs/Web/CSS/content-visibility) that works not only for DOM elements but React components, too. During our research, we’ve discovered a variety of use cases:

* A router can prerender screens in the background so that when a user navigates to them, they’re instantly available.
* A tab switching component can preserve the state of hidden tabs, so the user can switch between them without losing their progress.
* A virtualized list component can prerender additional rows above and below the visible window.
* When opening a modal or popup, the rest of the app can be put into “background” mode so that events and updates are disabled for everything except the modal.

Most React developers will not interact with React’s offscreen APIs directly. Instead, offscreen rendering will be integrated into things like routers and UI libraries, and then developers who use those libraries will automatically benefit without additional work.

The idea is that you should be able to render any React tree offscreen without changing the way you write your components. When a component is rendered offscreen, it does not actually *mount* until the component becomes visible — its effects are not fired. For example, if a component uses `useEffect` to log analytics when it appears for the first time, prerendering won’t mess up the accuracy of those analytics. Similarly, when a component goes offscreen, its effects are unmounted, too. A key feature of offscreen rendering is that you can toggle the visibility of a component without losing its state.

Since our last update, we’ve tested an experimental version of prerendering internally at Meta in our React Native apps on Android and iOS, with positive performance results. We’ve also improved how offscreen rendering works with Suspense — suspending inside an offscreen tree will not trigger Suspense fallbacks. Our remaining work involves finalizing the primitives that are exposed to library developers. We expect to publish an RFC later this year, alongside an experimental API for testing and feedback.

## Transition Tracing[](#transition-tracing "Link for Transition Tracing ")

The Transition Tracing API lets you detect when [React Transitions](/reference/react/useTransition) become slower and investigate why they may be slow. Following our last update, we have completed the initial design of the API and published an [RFC](https://github.com/reactjs/rfcs/pull/238). The basic capabilities have also been implemented. The project is currently on hold. We welcome feedback on the RFC and look forward to resuming its development to provide a better performance measurement tool for React. This will be particularly useful with routers built on top of React Transitions, like the [Next.js App Router](/learn/creating-a-react-app#nextjs-app-router).

***

In addition to this update, our team has made recent guest appearances on community podcasts and livestreams to speak more on our work and answer questions.

* [Dan Abramov](https://bsky.app/profile/danabra.mov) and [Joe Savona](https://twitter.com/en_JS) were interviewed by [Kent C. Dodds on his YouTube channel](https://www.youtube.com/watch?v=h7tur48JSaw), where they discussed concerns around React Server Components.
* [Dan Abramov](https://bsky.app/profile/danabra.mov) and [Joe Savona](https://twitter.com/en_JS) were guests on the [JSParty podcast](https://jsparty.fm/267) and shared their thoughts about the future of React.

Thanks to [Andrew Clark](https://twitter.com/acdlite), [Dan Abramov](https://bsky.app/profile/danabra.mov), [Dave McCabe](https://twitter.com/mcc_abe), [Luna Wei](https://twitter.com/lunaleaps), [Matt Carroll](https://twitter.com/mattcarrollcode), [Sean Keegan](https://twitter.com/DevRelSean), [Sebastian Silbermann](https://twitter.com/sebsilbermann), [Seth Webster](https://twitter.com/sethwebster), and [Sophie Alpert](https://twitter.com/sophiebits) for reviewing this post.

Thanks for reading, and see you in the next update!

[PreviousReact Canaries: Enabling Incremental Feature Rollout Outside Meta](/blog/2023/05/03/react-canaries)

[NextIntroducing react.dev](/blog/2023/03/16/introducing-react-dev)

***

----
url: https://react.dev/learn/thinking-in-react
----

```
[

  { category: "Fruits", price: "$1", stocked: true, name: "Apple" },

  { category: "Fruits", price: "$1", stocked: true, name: "Dragonfruit" },

  { category: "Fruits", price: "$2", stocked: false, name: "Passionfruit" },

  { category: "Vegetables", price: "$2", stocked: true, name: "Spinach" },

  { category: "Vegetables", price: "$4", stocked: false, name: "Pumpkin" },

  { category: "Vegetables", price: "$1", stocked: true, name: "Peas" }

]
```

The mockup looks like this:

To implement a UI in React, you will usually follow the same five steps.

## Step 1: Break the UI into a component hierarchy[](#step-1-break-the-ui-into-a-component-hierarchy "Link for Step 1: Break the UI into a component hierarchy ")

Start by drawing boxes around every component and subcomponent in the mockup and naming them. If you work with a designer, they may have already named these components in their design tool. Ask them!

Depending on your background, you can think about splitting up a design into components in different ways:

* **Programming**—use the same techniques for deciding if you should create a new function or object. One such technique is the [separation of concerns](https://en.wikipedia.org/wiki/Separation_of_concerns), that is, a component should ideally only be concerned with one thing. If it ends up growing, it should be decomposed into smaller subcomponents.

    * `ProductCategoryRow`
    * `ProductRow`

## Step 2: Build a static version in React[](#step-2-build-a-static-version-in-react "Link for Step 2: Build a static version in React ")

Now that you have your component hierarchy, it’s time to implement your app. The most straightforward approach is to build a version that renders the UI from your data model without adding any interactivity… yet! It’s often easier to build the static version first and add interactivity later. Building a static version requires a lot of typing and no thinking, but adding interactivity requires a lot of thinking and not a lot of typing.

To build a static version of your app that renders your data model, you’ll want to build [components](/learn/your-first-component) that reuse other components and pass data using [props.](/learn/passing-props-to-a-component) Props are a way of passing data from parent to child. (If you’re familiar with the concept of [state](/learn/state-a-components-memory), don’t use state at all to build this static version. State is reserved only for interactivity, that is, data that changes over time. Since this is a static version of the app, you don’t need it.)

You can either build “top down” by starting with building the components higher up in the hierarchy (like `FilterableProductTable`) or “bottom up” by working from components lower down (like `ProductRow`). In simpler examples, it’s usually easier to go top-down, and on larger projects, it’s easier to go bottom-up.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
function ProductCategoryRow({ category }) {
  return (
    <tr>
      <th colSpan="2">
        {category}
      </th>
    </tr>
  );
}

function ProductRow({ product }) {
  const name = product.stocked ? product.name :
    <span style={{ color: 'red' }}>
      {product.name}
    </span>;

  return (
    <tr>
      <td>{name}</td>
      <td>{product.price}</td>
    </tr>
  );
}

function ProductTable({ products }) {
  const rows = [];
  let lastCategory = null;

  products.forEach((product) => {
    if (product.category !== lastCategory) {
      rows.push(
        <ProductCategoryRow
          category={product.category}
          key={product.category} />
      );
    }
    rows.push(
      <ProductRow
        product={product}
        key={product.name} />
    );
    lastCategory = product.category;
  });

  return (
    <table>
      <thead>
        <tr>
          <th>Name</th>
          <th>Price</th>
        </tr>
      </thead>
      <tbody>{rows}</tbody>
    </table>
  );
}

function SearchBar() {
  return (
    <form>
      <input type="text" placeholder="Search..." />
      <label>
        <input type="checkbox" />
        {' '}
        Only show products in stock
      </label>
    </form>
  );
}

function FilterableProductTable({ products }) {
  return (
    <div>
      <SearchBar />
      <ProductTable products={products} />
    </div>
  );
}

const PRODUCTS = [
  {category: "Fruits", price: "$1", stocked: true, name: "Apple"},
  {category: "Fruits", price: "$1", stocked: true, name: "Dragonfruit"},
  {category: "Fruits", price: "$2", stocked: false, name: "Passionfruit"},
  {category: "Vegetables", price: "$2", stocked: true, name: "Spinach"},
  {category: "Vegetables", price: "$4", stocked: false, name: "Pumpkin"},
  {category: "Vegetables", price: "$1", stocked: true, name: "Peas"}
];

export default function App() {
  return <FilterableProductTable products={PRODUCTS} />;
}
```

```
function FilterableProductTable({ products }) {

  const [filterText, setFilterText] = useState('');

  const [inStockOnly, setInStockOnly] = useState(false);
```

Then, pass `filterText` and `inStockOnly` to `ProductTable` and `SearchBar` as props:

```
<div>

  <SearchBar

    filterText={filterText}

    inStockOnly={inStockOnly} />

  <ProductTable

    products={products}

    filterText={filterText}

    inStockOnly={inStockOnly} />

</div>
```

You can start seeing how your application will behave. Edit the `filterText` initial value from `useState('')` to `useState('fruit')` in the sandbox code below. You’ll see both the search input text and the table update:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

function FilterableProductTable({ products }) {
  const [filterText, setFilterText] = useState('');
  const [inStockOnly, setInStockOnly] = useState(false);

  return (
    <div>
      <SearchBar
        filterText={filterText}
        inStockOnly={inStockOnly} />
      <ProductTable
        products={products}
        filterText={filterText}
        inStockOnly={inStockOnly} />
    </div>
  );
}

function ProductCategoryRow({ category }) {
  return (
    <tr>
      <th colSpan="2">
        {category}
      </th>
    </tr>
  );
}

function ProductRow({ product }) {
  const name = product.stocked ? product.name :
    <span style={{ color: 'red' }}>
      {product.name}
    </span>;

  return (
    <tr>
      <td>{name}</td>
      <td>{product.price}</td>
    </tr>
  );
}

function ProductTable({ products, filterText, inStockOnly }) {
  const rows = [];
  let lastCategory = null;

  products.forEach((product) => {
    if (
      product.name.toLowerCase().indexOf(
        filterText.toLowerCase()
      ) === -1
    ) {
      return;
    }
    if (inStockOnly && !product.stocked) {
      return;
    }
    if (product.category !== lastCategory) {
      rows.push(
        <ProductCategoryRow
          category={product.category}
          key={product.category} />
      );
    }
    rows.push(
      <ProductRow
        product={product}
        key={product.name} />
    );
    lastCategory = product.category;
  });

  return (
    <table>
      <thead>
        <tr>
          <th>Name</th>
          <th>Price</th>
        </tr>
      </thead>
      <tbody>{rows}</tbody>
    </table>
  );
}

function SearchBar({ filterText, inStockOnly }) {
  return (
    <form>
      <input
        type="text"
        value={filterText}
        placeholder="Search..."/>
      <label>
        <input
          type="checkbox"
          checked={inStockOnly} />
        {' '}
        Only show products in stock
      </label>
    </form>
  );
}

const PRODUCTS = [
  {category: "Fruits", price: "$1", stocked: true, name: "Apple"},
  {category: "Fruits", price: "$1", stocked: true, name: "Dragonfruit"},
  {category: "Fruits", price: "$2", stocked: false, name: "Passionfruit"},
  {category: "Vegetables", price: "$2", stocked: true, name: "Spinach"},
  {category: "Vegetables", price: "$4", stocked: false, name: "Pumpkin"},
  {category: "Vegetables", price: "$1", stocked: true, name: "Peas"}
];

export default function App() {
  return <FilterableProductTable products={PRODUCTS} />;
}
```

Notice that editing the form doesn’t work yet. There is a console error in the sandbox above explaining why:

Console

You provided a \`value\` prop to a form field without an \`onChange\` handler. This will render a read-only field.

In the sandbox above, `ProductTable` and `SearchBar` read the `filterText` and `inStockOnly` props to render the table, the input, and the checkbox. For example, here is how `SearchBar` populates the input value:

```
function SearchBar({ filterText, inStockOnly }) {

  return (

    <form>

      <input

        type="text"

        value={filterText}

        placeholder="Search..."/>
```

However, you haven’t added any code to respond to the user actions like typing yet. This will be your final step.

## Step 5: Add inverse data flow[](#step-5-add-inverse-data-flow "Link for Step 5: Add inverse data flow ")

Currently your app renders correctly with props and state flowing down the hierarchy. But to change the state according to user input, you will need to support data flowing the other way: the form components deep in the hierarchy need to update the state in `FilterableProductTable`.

React makes this data flow explicit, but it requires a little more typing than two-way data binding. If you try to type or check the box in the example above, you’ll see that React ignores your input. This is intentional. By writing `<input value={filterText} />`, you’ve set the `value` prop of the `input` to always be equal to the `filterText` state passed in from `FilterableProductTable`. Since `filterText` state is never set, the input never changes.

You want to make it so whenever the user changes the form inputs, the state updates to reflect those changes. The state is owned by `FilterableProductTable`, so only it can call `setFilterText` and `setInStockOnly`. To let `SearchBar` update the `FilterableProductTable`’s state, you need to pass these functions down to `SearchBar`:

```
function FilterableProductTable({ products }) {

  const [filterText, setFilterText] = useState('');

  const [inStockOnly, setInStockOnly] = useState(false);



  return (

    <div>

      <SearchBar

        filterText={filterText}

        inStockOnly={inStockOnly}

        onFilterTextChange={setFilterText}

        onInStockOnlyChange={setInStockOnly} />
```

Inside the `SearchBar`, you will add the `onChange` event handlers and set the parent state from them:

```
function SearchBar({

  filterText,

  inStockOnly,

  onFilterTextChange,

  onInStockOnlyChange

}) {

  return (

    <form>

      <input

        type="text"

        value={filterText}

        placeholder="Search..."

        onChange={(e) => onFilterTextChange(e.target.value)}

      />

      <label>

        <input

          type="checkbox"

          checked={inStockOnly}

          onChange={(e) => onInStockOnlyChange(e.target.checked)}
```

Now the application fully works!

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

function FilterableProductTable({ products }) {
  const [filterText, setFilterText] = useState('');
  const [inStockOnly, setInStockOnly] = useState(false);

  return (
    <div>
      <SearchBar
        filterText={filterText}
        inStockOnly={inStockOnly}
        onFilterTextChange={setFilterText}
        onInStockOnlyChange={setInStockOnly} />
      <ProductTable
        products={products}
        filterText={filterText}
        inStockOnly={inStockOnly} />
    </div>
  );
}

function ProductCategoryRow({ category }) {
  return (
    <tr>
      <th colSpan="2">
        {category}
      </th>
    </tr>
  );
}

function ProductRow({ product }) {
  const name = product.stocked ? product.name :
    <span style={{ color: 'red' }}>
      {product.name}
    </span>;

  return (
    <tr>
      <td>{name}</td>
      <td>{product.price}</td>
    </tr>
  );
}

function ProductTable({ products, filterText, inStockOnly }) {
  const rows = [];
  let lastCategory = null;

  products.forEach((product) => {
    if (
      product.name.toLowerCase().indexOf(
        filterText.toLowerCase()
      ) === -1
    ) {
      return;
    }
    if (inStockOnly && !product.stocked) {
      return;
    }
    if (product.category !== lastCategory) {
      rows.push(
        <ProductCategoryRow
          category={product.category}
          key={product.category} />
      );
    }
    rows.push(
      <ProductRow
        product={product}
        key={product.name} />
    );
    lastCategory = product.category;
  });

  return (
    <table>
      <thead>
        <tr>
          <th>Name</th>
          <th>Price</th>
        </tr>
      </thead>
      <tbody>{rows}</tbody>
    </table>
  );
}

function SearchBar({
  filterText,
  inStockOnly,
  onFilterTextChange,
  onInStockOnlyChange
}) {
  return (
    <form>
      <input
        type="text"
        value={filterText} placeholder="Search..."
        onChange={(e) => onFilterTextChange(e.target.value)} />
      <label>
        <input
          type="checkbox"
          checked={inStockOnly}
          onChange={(e) => onInStockOnlyChange(e.target.checked)} />
        {' '}
        Only show products in stock
      </label>
    </form>
  );
}

const PRODUCTS = [
  {category: "Fruits", price: "$1", stocked: true, name: "Apple"},
  {category: "Fruits", price: "$1", stocked: true, name: "Dragonfruit"},
  {category: "Fruits", price: "$2", stocked: false, name: "Passionfruit"},
  {category: "Vegetables", price: "$2", stocked: true, name: "Spinach"},
  {category: "Vegetables", price: "$4", stocked: false, name: "Pumpkin"},
  {category: "Vegetables", price: "$1", stocked: true, name: "Peas"}
];

export default function App() {
  return <FilterableProductTable products={PRODUCTS} />;
}
```

You can learn all about handling events and updating state in the [Adding Interactivity](/learn/adding-interactivity) section.

## Where to go from here[](#where-to-go-from-here "Link for Where to go from here ")

This was a very brief introduction to how to think about building components and applications with React. You can [start a React project](/learn/installation) right now or [dive deeper on all the syntax](/learn/describing-the-ui) used in this tutorial.

[PreviousTutorial: Tic-Tac-Toe](/learn/tutorial-tic-tac-toe)

[NextInstallation](/learn/installation)

***

----
url: https://react.dev/reference/react-dom/components/script
----

[API Reference](/reference/react)

[Components](/reference/react-dom/components)

# \<script>[](#undefined "Link for this heading")

The [built-in browser `<script>` component](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script) lets you add a script to your document.

```
<script> alert("hi!") </script>
```

* [Reference](#reference)
  * [`<script>`](#script)

* [Usage](#usage)

  * [Rendering an external script](#rendering-an-external-script)
  * [Rendering an inline script](#rendering-an-inline-script)

***

## Reference[](#reference "Link for Reference ")

### `<script>`[](#script "Link for this heading")

To add inline or external scripts to your document, render the [built-in browser `<script>` component](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script). You can render `<script>` from any component and React will [in certain cases](#special-rendering-behavior) place the corresponding DOM element in the document head and de-duplicate identical scripts.

```
<script> alert("hi!") </script>

<script src="script.js" />
```

[See more examples below.](#usage)

#### Props[](#props "Link for Props ")

`<script>` supports all [common element props.](/reference/react-dom/components/common#common-props)

***

## Usage[](#usage "Link for Usage ")

### Rendering an external script[](#rendering-an-external-script "Link for Rendering an external script ")

If a component depends on certain scripts in order to be displayed correctly, you can render a `<script>` within the component. However, the component might be committed before the script has finished loading. You can start depending on the script content once the `load` event is fired e.g. by using the `onLoad` prop.

React will de-duplicate scripts that have the same `src`, inserting only one of them into the DOM even if multiple components render it.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import ShowRenderedHTML from './ShowRenderedHTML.js';

function Map({lat, long}) {
  return (
    <>
      <script async src="map-api.js" onLoad={() => console.log('script loaded')} />
      <div id="map" data-lat={lat} data-long={long} />
    </>
  );
}

export default function Page() {
  return (
    <ShowRenderedHTML>
      <Map />
    </ShowRenderedHTML>
  );
}
```

### Note

When you want to use a script, it can be beneficial to call the [preinit](/reference/react-dom/preinit) function. Calling this function may allow the browser to start fetching the script earlier than if you just render a `<script>` component, for example by sending an [HTTP Early Hints response](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/103).

### Rendering an inline script[](#rendering-an-inline-script "Link for Rendering an inline script ")

To include an inline script, render the `<script>` component with the script source code as its children. Inline scripts are not de-duplicated or moved to the document `<head>`.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import ShowRenderedHTML from './ShowRenderedHTML.js';

function Tracking() {
  return (
    <script>
      ga('send', 'pageview');
    </script>
  );
}

export default function Page() {
  return (
    <ShowRenderedHTML>
      <h1>My Website</h1>
      <Tracking />
      <p>Welcome</p>
    </ShowRenderedHTML>
  );
}
```

[Previous\<meta>](/reference/react-dom/components/meta)

[Next\<style>](/reference/react-dom/components/style)

***

----
url: https://18.react.dev/reference/rsc/use-client
----

[API Reference](/reference/react)

[Directives](/reference/rsc/directives)

# 'use client'[](#undefined "Link for this heading")

### Canary

`'use client'` is needed only if you’re [using React Server Components](/learn/start-a-new-react-project#bleeding-edge-react-frameworks) or building a library compatible with them.

***

## Reference[](#reference "Link for Reference ")

### `'use client'`[](#use-client "Link for this heading")

Add `'use client'` at the top of a file to mark the module and its transitive dependencies as client code.

```
'use client';



import { useState } from 'react';

import { formatDate } from './formatters';

import Button from './button';



export default function RichTextEditor({ timestamp, text }) {

  const date = formatDate(timestamp);

  // ...

  const editButton = <Button />;

  // ...

}
```

When a file marked with `'use client'` is imported from a Server Component, [compatible bundlers](/learn/start-a-new-react-project#bleeding-edge-react-frameworks) will treat the module import as a boundary between server-run and client-run code.

```
import FancyText from './FancyText';
import InspirationGenerator from './InspirationGenerator';
import Copyright from './Copyright';

export default function App() {
  return (
    <>
      <FancyText title text="Get Inspired App" />
      <InspirationGenerator>
        <Copyright year={2004} />
      </InspirationGenerator>
    </>
  );
}
```

```
// This is a definition of a component

function MyComponent() {

  return <p>My Component</p>

}
```

2. A “component” can also refer to a **component usage** of its definition.

```
import MyComponent from './MyComponent';



function App() {

  // This is a usage of a component

  return <MyComponent />;

}
```

* Functions that are [Server Actions](/reference/rsc/use-server)

```
'use client';

import { useState } from 'react';

export default function Counter({initialValue = 0}) {
  const [countValue, setCountValue] = useState(initialValue);
  const increment = () => setCountValue(countValue + 1);
  const decrement = () => setCountValue(countValue - 1);
  return (
    <>
      <h2>Count Value: {countValue}</h2>
      <button onClick={increment}>+1</button>
      <button onClick={decrement}>-1</button>
    </>
  );
}
```

As `Counter` requires both the `useState` Hook and event handlers to increment or decrement the value, this component must be a Client Component and will require a `'use client'` directive at the top.

In contrast, a component that renders UI without interaction will not need to be a Client Component.

```
import { readFile } from 'node:fs/promises';

import Counter from './Counter';



export default async function CounterContainer() {

  const initialValue = await readFile('/path/to/counter_value');

  return <Counter initialValue={initialValue} />

}
```

For example, `Counter`’s parent component, `CounterContainer`, does not require `'use client'` as it is not interactive and does not use state. In addition, `CounterContainer` must be a Server Component as it reads from the local file system on the server, which is possible only in a Server Component.

There are also components that don’t use any server or client-only features and can be agnostic to where they render. In our earlier example, `FancyText` is one such component.

```
export default function FancyText({title, text}) {

  return title

    ? <h1 className='fancy title'>{text}</h1>

    : <h3 className='fancy cursive'>{text}</h3>

}
```

In this case, we don’t add the `'use client'` directive, resulting in `FancyText`’s *output* (rather than its source code) to be sent to the browser when referenced from a Server Component. As demonstrated in the earlier Inspirations app example, `FancyText` is used as both a Server or Client Component, depending on where it is imported and used.

But if `FancyText`’s HTML output was large relative to its source code (including dependencies), it might be more efficient to force it to always be a Client Component. Components that return a long SVG path string are one case where it may be more efficient to force a component to be a Client Component.

### Using client APIs[](#using-client-apis "Link for Using client APIs ")

Your React app may use client-specific APIs, such as the browser’s APIs for web storage, audio and video manipulation, and device hardware, among [others](https://developer.mozilla.org/en-US/docs/Web/API).

In this example, the component uses [DOM APIs](https://developer.mozilla.org/en-US/docs/Glossary/DOM) to manipulate a [`canvas`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas) element. Since those APIs are only available in the browser, it must be marked as a Client Component.

```
'use client';



import {useRef, useEffect} from 'react';



export default function Circle() {

  const ref = useRef(null);

  useLayoutEffect(() => {

    const canvas = ref.current;

    const context = canvas.getContext('2d');

    context.reset();

    context.beginPath();

    context.arc(100, 75, 50, 0, 2 * Math.PI);

    context.stroke();

  });

  return <canvas ref={ref} />;

}
```

***

----
url: https://legacy.reactjs.org/blog/2014/03/28/the-road-to-1.0.html
----

March 28, 2014 by [Paul O’Shannessy](https://twitter.com/zpao)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

When we launched React last spring, we purposefully decided not to call it 1.0. It was production ready, but we had plans to evolve APIs and behavior as we saw how people were using React, both internally and externally. We’ve learned a lot over the past 9 months and we’ve thought a lot about what 1.0 will mean for React. A couple weeks ago, I outlined [several projects](https://github.com/facebook/react/wiki/Projects) that we have planned to take us to 1.0 and beyond. Today I’m writing a bit more about them to give our users a better insight into our plans.

Our primary goal with 1.0 is to clarify our messaging and converge on an API that is aligned with our goals. In order to do that, we want to clean up bad patterns we’ve seen in use and really help enable developers write good code.

## [](#descriptors)Descriptors

The first part of this is what we’re calling “descriptors”. I talked about this briefly in our [v0.10 announcements](/react/blog/2014/03/21/react-v0.10.html). The goal here is to separate our virtual DOM representation from our use of it. Simply, this means the return value of a component (e.g. `React.DOM.div()`, `MyComponent()`) will be a simple object containing the information React needs to render. Currently the object returned is actually linked to React’s internal representation of the component and even directly to the DOM element. This has enabled some bad patterns that are quite contrary to how we want people to use React. That’s our failure.

We added some warnings in v0.9 to start migrating some of these bad patterns. With v0.10 we’ll catch more. You’ll see more on this soon as we expect to ship v0.11 with descriptors.

## [](#api-cleanup)API Cleanup

This is really connected to everything. We want to keep the API as simple as possible and help developers [fall into the pit of success](http://blog.codinghorror.com/falling-into-the-pit-of-success/). Enabling bad patterns with bad APIs is not success.

## [](#es6)ES6

Before we even launched React publicly, members of the team were talking about how we could leverage ES6, namely classes, to improve the experience of creating React components. Calling `React.createClass(...)` isn’t great. We don’t quite have the right answer here yet, but we’re close. We want to make sure we make this as simple as possible. It could look like this:

```
class MyComponent extends React.Component {
  render() {
    ...
  }
}
```

There are other features of ES6 we’re already using in core. I’m sure we’ll see more of that. The `jsx` executable we ship with `react-tools` already supports transforming many parts of ES6 into code that will run on older browsers.

## [](#context)Context

While we haven’t documented `context`, it exists in some form in React already. It exists as a way to pass values through a tree without having to use props at every single point. We’ve seen this need crop up time and time again, so we want to make this as easy as possible. Its use has performance tradeoffs, and there are known weaknesses in our implementation, so we want to make sure this is a solid feature.

## [](#addons)Addons

As you may know, we ship a separate build of React with some extra features we called “addons”. While this has served us fine, it’s not great for our users. It’s made testing harder, but also results in more cache misses for people using a CDN. The problem we face is that many of these “addons” need access to parts of React that we don’t expose publicly. Our goal is to ship each addon on its own and let each hook into React as needed. This would also allow others to write and distribute “addons”.

## [](#browser-support)Browser Support

As much as we’d all like to stop supporting older browsers, it’s not always possible. Facebook still supports IE8. While React won’t support IE8 forever, our goal is to have 1.0 support IE8. Hopefully we can continue to abstract some of these rough parts.

## [](#animations)Animations

Finding a way to define animations in a declarative way is a hard problem. We’ve been exploring the space for a long time. We’ve introduced some half-measures to alleviate some use cases, but the larger problem remains. While we’d like to make this a part of 1.0, realistically we don’t think we’ll have a good solution in place.

## [](#miscellaneous)Miscellaneous

There are several other things I listed on [our projects page](https://github.com/facebook/react/wiki/Projects) that we’re tracking. Some of them are internals and have no obvious outward effect (improve tests, repo separation, updated test runner). I encourage you to take a look.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2014-03-28-the-road-to-1.0.md)

----
url: https://legacy.reactjs.org/blog/2013/09/24/community-roundup-8.html
----

September 24, 2013 by [Vjeux](https://twitter.com/vjeux)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

A lot has happened in the month since our last update. Here are some of the more interesting things we’ve found. But first, we have a couple updates before we share links.

First, we are organizing a [React Hackathon](http://reactjshack-a-thon.splashthat.com/) in Facebook’s Seattle office on Saturday September 28. If you want to hack on React, meet some of the team or win some prizes, feel free to join us!

We’ve also reached a point where there are too many questions for us to handle directly. We’re encouraging people to ask questions on [StackOverflow](http://stackoverflow.com/questions/tagged/reactjs) using the tag [\[reactjs\]](http://stackoverflow.com/questions/tagged/reactjs). Many members of the team and community have subscribed to the tag, so feel free to ask questions there. We think these will be more discoverable than Google Groups archives or IRC logs.

## [](#javascript-jabber)JavaScript Jabber

[Pete Hunt](http://www.petehunt.net/) and [Jordan Walke](https://github.com/jordwalke) were interviewed on [JavaScript Jabber](http://javascriptjabber.com/073-jsj-react-with-pete-hunt-and-jordan-walke/) for an hour. They go over many aspects of React such as 60 FPS, Data binding, Performance, Diffing Algorithm, DOM Manipulation, Node.js support, server-side rendering, JSX, requestAnimationFrame and the community. This is a gold mine of information about React.

> **PETE:** So React was designed all around that. Conceptually, how you build a React app is that every time your data changes, it’s like hitting the refresh button in a server-rendered app. What we do is we conceptually throw out all of the markup and event handlers that you’ve registered and we reset the whole page and then we redraw the entire page. If you’re writing a server-rendered app, handling updates is really easy because you hit the refresh button and you’re pretty much guaranteed to get what you expect.
>
> **MERRICK:** That’s true. You don’t get into these odd states.
>
> **PETE:** Exactly, exactly. In order to implement that, we communicate it as a fake DOM. What we’ll do is rather than throw out the actual browser html and event handlers, we have an internal representation of what the page looks like and then we generate a brand new representation of what we want the page to look like. Then we perform this really, really fast diffing algorithm between those two page representations, DOM representations. Then React will compute the minimum set of DOM mutations it needs to make to bring the page up to date.
>
> Then to finally get to answer your question, that set of DOM mutations then goes into a queue and we can plug in arbitrary flushing strategies for that. For example, when we originally launched React in open source, every setState would immediately trigger a flush to the DOM. That wasn’t part of the contract of setState, but that was just our strategy and it worked pretty well. Then this totally awesome open source contributor Sophie Alpert at Khan Academy built a new batching strategy which would basically queue up every single DOM update and state change that happened within an event tick and would execute them in bulk at the end of the event tick.
>
> [Read the full conversation …](http://javascriptjabber.com/073-jsj-react-with-pete-hunt-and-jordan-walke/)

## [](#jsxtransformer-trick)JSXTransformer Trick

While this is not going to work for all the attributes since they are camelCased in React, this is a pretty cool trick.

> Turn any DOM element into a React.js function: JSXTransformer.transform("/\*\* [@jsx](https://twitter.com/jsx) React.DOM \*/" + element.innerHTML).code
>
> — Ross Allen (@ssorallen) [September 9, 2013](https://twitter.com/ssorallen/statuses/377105575441489920)

## [](#remarkable-react)Remarkable React

[Stoyan Stefanov](http://www.phpied.com/) gave a talk at [BrazilJS](http://braziljs.com.br/) about React and wrote an article with the content of the presentation. He goes through the difficulties of writing *active apps* using the DOM API and shows how React handles it.

> So how does exactly React deal with it internally? Two crazy ideas - virtual DOM and synthetic events.
>
> You define you components in React. It builds a virtual DOM in JavaScript land which is way more efficient. Then it updates the DOM. (And “virtual DOM” is a very big name for what is simply a JavaScript object with nested key-value pairs)
>
> Data changes. React computes a diff (in JavaScript land, which is, of course, much more efficient) and updates the single table cell that needs to change. React replicates the state of the virtual DOM into the actual DOM only when and where it’s necessary. And does it all at once, in most cases in a single tick of the `requestAnimationFrame()`.
>
> What about event handlers? They are synthetic. React uses event delegation to listen way at the top of the React tree. So removing a node in the virtual DOM has no effect on the event handling.
>
> The events are automatically cross-browser (they are React events). They are also much closer to W3C than any browser. That means that for example `e.target` works, no need to look for the event object or checking whether it’s `e.target` or `e.srcElement` (IE). Bubbling and capturing phases also work cross browser. React also takes the liberty of making some small fixes, e.g. the event `<input onChange>` fires when you type, not when blur away from the input. And of course, event delegation is used as the most efficient way to handle events. You know that “thou shall use event delegation” is also commonly given advice for making web apps snappy.
>
> The good thing about the virtual DOM is that it’s all in JavaScript land. You build all your UI in JavaScript. Which means it can be rendered on the server side, so you initial view is fast (and any SEO concerns are addressed). Also, if there are especially heavy operations they can be threaded into WebWorkers, which otherwise have no DOM access.
>
> [Read More …](http://www.phpied.com/remarkable-react/)

## [](#markdown-in-react)Markdown in React

[Sophie Alpert](http://sophiebits.com/) converted [marked](https://github.com/chjj/marked), a Markdown JavaScript implementation, in React: [marked-react](https://github.com/sophiebits/marked-react). Even without using JSX, the HTML generation is now a lot cleaner. It is also safer as forgetting a call to `escape` will not introduce an XSS vulnerability.

[](https://github.com/sophiebits/marked-react/commit/cb70c9df6542c7c34ede9efe16f9b6580692a457)

## [](#unite-from-bugbusters)Unite from BugBusters

[Renault John Lecoultre](https://twitter.com/renajohn) wrote [Unite](https://www.bugbuster.com/), an interactive tool for analyzing code dynamically using React. It integrates with CodeMirror.

[](https://unite.bugbuster.com/)

## [](#reactjs-irc-logs)#reactjs IRC Logs

[Vjeux](http://blog.vjeux.com/) re-implemented the display part of the IRC logger in React. Just 130 lines are needed for a performant infinite scroll with timestamps and color-coded author names.

[View the source on JSFiddle…](http://jsfiddle.net/vjeux/QL9tz)

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2013-09-24-community-roundup-8.md)

----
url: https://legacy.reactjs.org/blog/2014/01/02/react-chrome-developer-tools.html
----

January 02, 2014 by [Sebastian Markbåge](https://twitter.com/sebmarkbage)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

With the new year, we thought you’d enjoy some new tools for debugging React code. Today we’re releasing the [React Developer Tools](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi), an extension to the Chrome Developer Tools. [Download them from the Chrome Web Store](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi).

You will get a new tab titled “React” in your Chrome DevTools. This tab shows you a list of the root React Components that are rendered on the page as well as the subcomponents that each root renders.

Selecting a Component in this tab allows you to view and edit its props and state in the panel on the right. In the breadcrumbs at the bottom, you can inspect the selected Component, the Component that created it, the Component that created that one, and so on.

When you inspect a DOM element using the regular Elements tab, you can switch over to the React tab and the corresponding Component will be automatically selected. The Component will also be automatically selected if you have a breakpoint within its render phase. This allows you to step through the render tree and see how one Component affects another one.

[](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi)

We hope these tools will help your team better understand your component hierarchy and track down bugs. We’re very excited about this initial launch and appreciate any feedback you may have. As always, we also accept [pull requests on GitHub](https://github.com/facebook/react-devtools).

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2014-01-02-react-chrome-developer-tools.md)

----
url: https://18.react.dev/reference/react/forwardRef
----

[API Reference](/reference/react)

[APIs](/reference/react/apis)

# forwardRef[](#undefined "Link for this heading")

`forwardRef` lets your component expose a DOM node to parent component with a [ref.](/learn/manipulating-the-dom-with-refs)

```
const SomeComponent = forwardRef(render)
```

***

## Reference[](#reference "Link for Reference ")

### `forwardRef(render)`[](#forwardref "Link for this heading")

Call `forwardRef()` to let your component receive a ref and forward it to a child component:

```
import { forwardRef } from 'react';



const MyInput = forwardRef(function MyInput(props, ref) {

  // ...

});
```

***

### `render` function[](#render-function "Link for this heading")

`forwardRef` accepts a render function as an argument. React calls this function with `props` and `ref`:

```
const MyInput = forwardRef(function MyInput(props, ref) {

  return (

    <label>

      {props.label}

      <input ref={ref} />

    </label>

  );

});
```

#### Parameters[](#render-parameters "Link for Parameters ")

* `props`: The props passed by the parent component.

* `ref`: The `ref` attribute passed by the parent component. The `ref` can be an object or a function. If the parent component has not passed a ref, it will be `null`. You should either pass the `ref` you receive to another component, or pass it to [`useImperativeHandle`.](/reference/react/useImperativeHandle)

#### Returns[](#render-returns "Link for Returns ")

`forwardRef` returns a React component that you can render in JSX. Unlike React components defined as plain functions, the component returned by `forwardRef` is able to take a `ref` prop.

***

## Usage[](#usage "Link for Usage ")

### Exposing a DOM node to the parent component[](#exposing-a-dom-node-to-the-parent-component "Link for Exposing a DOM node to the parent component ")

By default, each component’s DOM nodes are private. However, sometimes it’s useful to expose a DOM node to the parent—for example, to allow focusing it. To opt in, wrap your component definition into `forwardRef()`:

```
import { forwardRef } from 'react';



const MyInput = forwardRef(function MyInput(props, ref) {

  const { label, ...otherProps } = props;

  return (

    <label>

      {label}

      <input {...otherProps} />

    </label>

  );

});
```

You will receive a ref as the second argument after props. Pass it to the DOM node that you want to expose:

```
import { forwardRef } from 'react';



const MyInput = forwardRef(function MyInput(props, ref) {

  const { label, ...otherProps } = props;

  return (

    <label>

      {label}

      <input {...otherProps} ref={ref} />

    </label>

  );

});
```

This lets the parent `Form` component access the `<input>` DOM node exposed by `MyInput`:

```
function Form() {

  const ref = useRef(null);



  function handleClick() {

    ref.current.focus();

  }



  return (

    <form>

      <MyInput label="Enter your name:" ref={ref} />

      <button type="button" onClick={handleClick}>

        Edit

      </button>

    </form>

  );

}
```

This `Form` component [passes a ref](/reference/react/useRef#manipulating-the-dom-with-a-ref) to `MyInput`. The `MyInput` component *forwards* that ref to the `<input>` browser tag. As a result, the `Form` component can access that `<input>` DOM node and call [`focus()`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus) on it.

Keep in mind that exposing a ref to the DOM node inside your component makes it harder to change your component’s internals later. You will typically expose DOM nodes from reusable low-level components like buttons or text inputs, but you won’t do it for application-level components like an avatar or a comment.

#### Examples of forwarding a ref[](#examples "Link for Examples of forwarding a ref")

#### Example 1 of 2:Focusing a text input[](#focusing-a-text-input "Link for this heading")

Clicking the button will focus the input. The `Form` component defines a ref and passes it to the `MyInput` component. The `MyInput` component forwards that ref to the browser `<input>`. This lets the `Form` component focus the `<input>`.

```
import { useRef } from 'react';
import MyInput from './MyInput.js';

export default function Form() {
  const ref = useRef(null);

  function handleClick() {
    ref.current.focus();
  }

  return (
    <form>
      <MyInput label="Enter your name:" ref={ref} />
      <button type="button" onClick={handleClick}>
        Edit
      </button>
    </form>
  );
}
```

***

### Forwarding a ref through multiple components[](#forwarding-a-ref-through-multiple-components "Link for Forwarding a ref through multiple components ")

Instead of forwarding a `ref` to a DOM node, you can forward it to your own component like `MyInput`:

```
const FormField = forwardRef(function FormField(props, ref) {

  // ...

  return (

    <>

      <MyInput ref={ref} />

      ...

    </>

  );

});
```

If that `MyInput` component forwards a ref to its `<input>`, a ref to `FormField` will give you that `<input>`:

```
function Form() {

  const ref = useRef(null);



  function handleClick() {

    ref.current.focus();

  }



  return (

    <form>

      <FormField label="Enter your name:" ref={ref} isRequired={true} />

      <button type="button" onClick={handleClick}>

        Edit

      </button>

    </form>

  );

}
```

The `Form` component defines a ref and passes it to `FormField`. The `FormField` component forwards that ref to `MyInput`, which forwards it to a browser `<input>` DOM node. This is how `Form` accesses that DOM node.

```
import { useRef } from 'react';
import FormField from './FormField.js';

export default function Form() {
  const ref = useRef(null);

  function handleClick() {
    ref.current.focus();
  }

  return (
    <form>
      <FormField label="Enter your name:" ref={ref} isRequired={true} />
      <button type="button" onClick={handleClick}>
        Edit
      </button>
    </form>
  );
}
```

***

### Exposing an imperative handle instead of a DOM node[](#exposing-an-imperative-handle-instead-of-a-dom-node "Link for Exposing an imperative handle instead of a DOM node ")

Instead of exposing an entire DOM node, you can expose a custom object, called an *imperative handle,* with a more constrained set of methods. To do this, you’d need to define a separate ref to hold the DOM node:

```
const MyInput = forwardRef(function MyInput(props, ref) {

  const inputRef = useRef(null);



  // ...



  return <input {...props} ref={inputRef} />;

});
```

Pass the `ref` you received to [`useImperativeHandle`](/reference/react/useImperativeHandle) and specify the value you want to expose to the `ref`:

```
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} />;

});
```

If some component gets a ref to `MyInput`, it will only receive your `{ focus, scrollIntoView }` object instead of the DOM node. This lets you limit the information you expose about your DOM node to the minimum.

```
import { useRef } from 'react';
import MyInput from './MyInput.js';

export default function Form() {
  const ref = useRef(null);

  function handleClick() {
    ref.current.focus();
    // This won't work because the DOM node isn't exposed:
    // ref.current.style.opacity = 0.5;
  }

  return (
    <form>
      <MyInput placeholder="Enter your name" ref={ref} />
      <button type="button" onClick={handleClick}>
        Edit
      </button>
    </form>
  );
}
```

[Read more about using imperative handles.](/reference/react/useImperativeHandle)

### Pitfall

**Do not overuse refs.** You should only use refs for *imperative* behaviors that you can’t express as props: for example, scrolling to a node, focusing a node, triggering an animation, selecting text, and so on.

**If you can express something as a prop, you should not use a ref.** For example, instead of exposing an imperative handle like `{ open, close }` from a `Modal` component, it is better to take `isOpen` as a prop like `<Modal isOpen={isOpen} />`. [Effects](/learn/synchronizing-with-effects) can help you expose imperative behaviors via props.

***

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### My component is wrapped in `forwardRef`, but the `ref` to it is always `null`[](#my-component-is-wrapped-in-forwardref-but-the-ref-to-it-is-always-null "Link for this heading")

This usually means that you forgot to actually use the `ref` that you received.

For example, this component doesn’t do anything with its `ref`:

```
const MyInput = forwardRef(function MyInput({ label }, ref) {

  return (

    <label>

      {label}

      <input />

    </label>

  );

});
```

To fix it, pass the `ref` down to a DOM node or another component that can accept a ref:

```
const MyInput = forwardRef(function MyInput({ label }, ref) {

  return (

    <label>

      {label}

      <input ref={ref} />

    </label>

  );

});
```

The `ref` to `MyInput` could also be `null` if some of the logic is conditional:

```
const MyInput = forwardRef(function MyInput({ label, showInput }, ref) {

  return (

    <label>

      {label}

      {showInput && <input ref={ref} />}

    </label>

  );

});
```

If `showInput` is `false`, then the ref won’t be forwarded to any node, and a ref to `MyInput` will remain empty. This is particularly easy to miss if the condition is hidden inside another component, like `Panel` in this example:

```
const MyInput = forwardRef(function MyInput({ label, showInput }, ref) {

  return (

    <label>

      {label}

      <Panel isExpanded={showInput}>

        <input ref={ref} />

      </Panel>

    </label>

  );

});
```

[PreviouscreateContext](/reference/react/createContext)

[Nextlazy](/reference/react/lazy)

***

----
url: https://18.react.dev/learn/typescript
----

[Learn React](/learn)

[Installation](/learn/installation)

All [production-grade React frameworks](/learn/start-a-new-react-project#production-grade-react-frameworks) offer support for using TypeScript. Follow the framework specific guide for installation:

npm install @types/react @types/react-dom

[TypeScript Playground](https://www.typescriptlang.org/play#src=import%20*%20as%20React%20from%20'react'%3B%0A%0Afunction%20MyButton\(%7B%20title%20%7D%3A%20%7B%20title%3A%20string%20%7D\)%20%7B%0A%20%20return%20\(%0A%20%20%20%20%3Cbutton%3E%7Btitle%7D%3C%2Fbutton%3E%0A%20%20\)%3B%0A%7D%0A%0Aexport%20default%20function%20MyApp\(\)%20%7B%0A%20%20return%20\(%0A%20%20%20%20%3Cdiv%3E%0A%20%20%20%20%20%20%3Ch1%3EWelcome%20to%20my%20app%3C%2Fh1%3E%0A%20%20%20%20%20%20%3CMyButton%20title%3D%22I'm%20a%20button%22%20%2F%3E%0A%20%20%20%20%3C%2Fdiv%3E%0A%20%20\)%3B%0A%7D%0A "Open in TypeScript Playground")

```
function MyButton({ title }: { title: string }) {
  return (
    <button>{title}</button>
  );
}

export default function MyApp() {
  return (
    <div>
      <h1>Welcome to my app</h1>
      <MyButton title="I'm a button" />
    </div>
  );
}
```

### Note

These sandboxes can handle TypeScript code, but they do not run the type-checker. This means you can amend the TypeScript sandboxes to learn, but you won’t get any type errors or warnings. To get type-checking, you can use the [TypeScript Playground](https://www.typescriptlang.org/play) or use a more fully-featured online sandbox.

This inline syntax is the simplest way to provide types for a component, though once you start to have a few fields to describe it can become unwieldy. Instead, you can use an `interface` or `type` to describe the component’s props:

[TypeScript Playground](https://www.typescriptlang.org/play#src=import%20*%20as%20React%20from%20'react'%3B%0A%0Ainterface%20MyButtonProps%20%7B%0A%20%20%2F**%20The%20text%20to%20display%20inside%20the%20button%20*%2F%0A%20%20title%3A%20string%3B%0A%20%20%2F**%20Whether%20the%20button%20can%20be%20interacted%20with%20*%2F%0A%20%20disabled%3A%20boolean%3B%0A%7D%0A%0Afunction%20MyButton\(%7B%20title%2C%20disabled%20%7D%3A%20MyButtonProps\)%20%7B%0A%20%20return%20\(%0A%20%20%20%20%3Cbutton%20disabled%3D%7Bdisabled%7D%3E%7Btitle%7D%3C%2Fbutton%3E%0A%20%20\)%3B%0A%7D%0A%0Aexport%20default%20function%20MyApp\(\)%20%7B%0A%20%20return%20\(%0A%20%20%20%20%3Cdiv%3E%0A%20%20%20%20%20%20%3Ch1%3EWelcome%20to%20my%20app%3C%2Fh1%3E%0A%20%20%20%20%20%20%3CMyButton%20title%3D%22I'm%20a%20disabled%20button%22%20disabled%3D%7Btrue%7D%2F%3E%0A%20%20%20%20%3C%2Fdiv%3E%0A%20%20\)%3B%0A%7D%0A "Open in TypeScript Playground")

```
interface MyButtonProps {
  /** The text to display inside the button */
  title: string;
  /** Whether the button can be interacted with */
  disabled: boolean;
}

function MyButton({ title, disabled }: MyButtonProps) {
  return (
    <button disabled={disabled}>{title}</button>
  );
}

export default function MyApp() {
  return (
    <div>
      <h1>Welcome to my app</h1>
      <MyButton title="I'm a disabled button" disabled={true}/>
    </div>
  );
}
```

The type describing your component’s props can be as simple or as complex as you need, though they should be an object type described with either a `type` or `interface`. You can learn about how TypeScript describes objects in [Object Types](https://www.typescriptlang.org/docs/handbook/2/objects.html) but you may also be interested in using [Union Types](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#union-types) to describe a prop that can be one of a few different types and the [Creating Types from Types](https://www.typescriptlang.org/docs/handbook/2/types-from-types.html) guide for more advanced use cases.

## Example Hooks[](#example-hooks "Link for Example Hooks ")

The type definitions from `@types/react` include types for the built-in Hooks, so you can use them in your components without any additional setup. They are built to take into account the code you write in your component, so you will get [inferred types](https://www.typescriptlang.org/docs/handbook/type-inference.html) a lot of the time and ideally do not need to handle the minutiae of providing the types.

However, we can look at a few examples of how to provide types for Hooks.

### `useState`[](#typing-usestate "Link for this heading")

The [`useState` Hook](/reference/react/useState) will re-use the value passed in as the initial state to determine what the type of the value should be. For example:

```
// Infer the type as "boolean"

const [enabled, setEnabled] = useState(false);
```

This will assign the type of `boolean` to `enabled`, and `setEnabled` will be a function accepting either a `boolean` argument, or a function that returns a `boolean`. If you want to explicitly provide a type for the state, you can do so by providing a type argument to the `useState` call:

```
// Explicitly set the type to "boolean"

const [enabled, setEnabled] = useState<boolean>(false);
```

This isn’t very useful in this case, but a common case where you may want to provide a type is when you have a union type. For example, `status` here can be one of a few different strings:

```
type Status = "idle" | "loading" | "success" | "error";



const [status, setStatus] = useState<Status>("idle");
```

Or, as recommended in [Principles for structuring state](/learn/choosing-the-state-structure#principles-for-structuring-state), you can group related state as an object and describe the different possibilities via object types:

```
type RequestState =

  | { status: 'idle' }

  | { status: 'loading' }

  | { status: 'success', data: any }

  | { status: 'error', error: Error };



const [requestState, setRequestState] = useState<RequestState>({ status: 'idle' });
```

### `useReducer`[](#typing-usereducer "Link for this heading")

The [`useReducer` Hook](/reference/react/useReducer) is a more complex Hook that takes a reducer function and an initial state. The types for the reducer function are inferred from the initial state. You can optionally provide a type argument to the `useReducer` call to provide a type for the state, but it is often better to set the type on the initial state instead:

[TypeScript Playground](https://www.typescriptlang.org/play#src=import%20*%20as%20React%20from%20'react'%3B%0A%0Aimport%20%7BuseReducer%7D%20from%20'react'%3B%0A%0Ainterface%20State%20%7B%0A%20%20%20count%3A%20number%20%0A%7D%3B%0A%0Atype%20CounterAction%20%3D%0A%20%20%7C%20%7B%20type%3A%20%22reset%22%20%7D%0A%20%20%7C%20%7B%20type%3A%20%22setCount%22%3B%20value%3A%20State%5B%22count%22%5D%20%7D%0A%0Aconst%20initialState%3A%20State%20%3D%20%7B%20count%3A%200%20%7D%3B%0A%0Afunction%20stateReducer\(state%3A%20State%2C%20action%3A%20CounterAction\)%3A%20State%20%7B%0A%20%20switch%20\(action.type\)%20%7B%0A%20%20%20%20case%20%22reset%22%3A%0A%20%20%20%20%20%20return%20initialState%3B%0A%20%20%20%20case%20%22setCount%22%3A%0A%20%20%20%20%20%20return%20%7B%20...state%2C%20count%3A%20action.value%20%7D%3B%0A%20%20%20%20default%3A%0A%20%20%20%20%20%20throw%20new%20Error\(%22Unknown%20action%22\)%3B%0A%20%20%7D%0A%7D%0A%0Aexport%20default%20function%20App\(\)%20%7B%0A%20%20const%20%5Bstate%2C%20dispatch%5D%20%3D%20useReducer\(stateReducer%2C%20initialState\)%3B%0A%0A%20%20const%20addFive%20%3D%20\(\)%20%3D%3E%20dispatch\(%7B%20type%3A%20%22setCount%22%2C%20value%3A%20state.count%20%2B%205%20%7D\)%3B%0A%20%20const%20reset%20%3D%20\(\)%20%3D%3E%20dispatch\(%7B%20type%3A%20%22reset%22%20%7D\)%3B%0A%0A%20%20return%20\(%0A%20%20%20%20%3Cdiv%3E%0A%20%20%20%20%20%20%3Ch1%3EWelcome%20to%20my%20counter%3C%2Fh1%3E%0A%0A%20%20%20%20%20%20%3Cp%3ECount%3A%20%7Bstate.count%7D%3C%2Fp%3E%0A%20%20%20%20%20%20%3Cbutton%20onClick%3D%7BaddFive%7D%3EAdd%205%3C%2Fbutton%3E%0A%20%20%20%20%20%20%3Cbutton%20onClick%3D%7Breset%7D%3EReset%3C%2Fbutton%3E%0A%20%20%20%20%3C%2Fdiv%3E%0A%20%20\)%3B%0A%7D%0A%0A "Open in TypeScript Playground")

```
import {useReducer} from 'react';

interface State {
   count: number 
};

type CounterAction =
  | { type: "reset" }
  | { type: "setCount"; value: State["count"] }

const initialState: State = { count: 0 };

function stateReducer(state: State, action: CounterAction): State {
  switch (action.type) {
    case "reset":
      return initialState;
    case "setCount":
      return { ...state, count: action.value };
    default:
      throw new Error("Unknown action");
  }
}

export default function App() {
  const [state, dispatch] = useReducer(stateReducer, initialState);

  const addFive = () => dispatch({ type: "setCount", value: state.count + 5 });
  const reset = () => dispatch({ type: "reset" });

  return (
    <div>
      <h1>Welcome to my counter</h1>

      <p>Count: {state.count}</p>
      <button onClick={addFive}>Add 5</button>
      <button onClick={reset}>Reset</button>
    </div>
  );
}
```

We are using TypeScript in a few key places:

* `interface State` describes the shape of the reducer’s state.
* `type CounterAction` describes the different actions which can be dispatched to the reducer.
* `const initialState: State` provides a type for the initial state, and also the type which is used by `useReducer` by default.
* `stateReducer(state: State, action: CounterAction): State` sets the types for the reducer function’s arguments and return value.

A more explicit alternative to setting the type on `initialState` is to provide a type argument to `useReducer`:

```
import { stateReducer, State } from './your-reducer-implementation';



const initialState = { count: 0 };



export default function App() {

  const [state, dispatch] = useReducer<State>(stateReducer, initialState);

}
```

### `useContext`[](#typing-usecontext "Link for this heading")

The [`useContext` Hook](/reference/react/useContext) is a technique for passing data down the component tree without having to pass props through components. It is used by creating a provider component and often by creating a Hook to consume the value in a child component.

The type of the value provided by the context is inferred from the value passed to the `createContext` call:

[TypeScript Playground](https://www.typescriptlang.org/play#src=import%20*%20as%20React%20from%20'react'%3B%0A%0Aimport%20%7B%20createContext%2C%20useContext%2C%20useState%20%7D%20from%20'react'%3B%0A%0Atype%20Theme%20%3D%20%22light%22%20%7C%20%22dark%22%20%7C%20%22system%22%3B%0Aconst%20ThemeContext%20%3D%20createContext%3CTheme%3E\(%22system%22\)%3B%0A%0Aconst%20useGetTheme%20%3D%20\(\)%20%3D%3E%20useContext\(ThemeContext\)%3B%0A%0Aexport%20default%20function%20MyApp\(\)%20%7B%0A%20%20const%20%5Btheme%2C%20setTheme%5D%20%3D%20useState%3CTheme%3E\('light'\)%3B%0A%0A%20%20return%20\(%0A%20%20%20%20%3CThemeContext.Provider%20value%3D%7Btheme%7D%3E%0A%20%20%20%20%20%20%3CMyComponent%20%2F%3E%0A%20%20%20%20%3C%2FThemeContext.Provider%3E%0A%20%20\)%0A%7D%0A%0Afunction%20MyComponent\(\)%20%7B%0A%20%20const%20theme%20%3D%20useGetTheme\(\)%3B%0A%0A%20%20return%20\(%0A%20%20%20%20%3Cdiv%3E%0A%20%20%20%20%20%20%3Cp%3ECurrent%20theme%3A%20%7Btheme%7D%3C%2Fp%3E%0A%20%20%20%20%3C%2Fdiv%3E%0A%20%20\)%0A%7D%0A "Open in TypeScript Playground")

```
import { createContext, useContext, useState } from 'react';

type Theme = "light" | "dark" | "system";
const ThemeContext = createContext<Theme>("system");

const useGetTheme = () => useContext(ThemeContext);

export default function MyApp() {
  const [theme, setTheme] = useState<Theme>('light');

  return (
    <ThemeContext.Provider value={theme}>
      <MyComponent />
    </ThemeContext.Provider>
  )
}

function MyComponent() {
  const theme = useGetTheme();

  return (
    <div>
      <p>Current theme: {theme}</p>
    </div>
  )
}
```

This technique works when you have a default value which makes sense - but there are occasionally cases when you do not, and in those cases `null` can feel reasonable as a default value. However, to allow the type-system to understand your code, you need to explicitly set `ContextShape | null` on the `createContext`.

This causes the issue that you need to eliminate the `| null` in the type for context consumers. Our recommendation is to have the Hook do a runtime check for it’s existence and throw an error when not present:

```
import { createContext, useContext, useState, useMemo } from 'react';



// This is a simpler example, but you can imagine a more complex object here

type ComplexObject = {

  kind: string

};



// The context is created with `| null` in the type, to accurately reflect the default value.

const Context = createContext<ComplexObject | null>(null);



// The `| null` will be removed via the check in the Hook.

const useGetComplexObject = () => {

  const object = useContext(Context);

  if (!object) { throw new Error("useGetComplexObject must be used within a Provider") }

  return object;

}



export default function MyApp() {

  const object = useMemo(() => ({ kind: "complex" }), []);



  return (

    <Context.Provider value={object}>

      <MyComponent />

    </Context.Provider>

  )

}



function MyComponent() {

  const object = useGetComplexObject();



  return (

    <div>

      <p>Current object: {object.kind}</p>

    </div>

  )

}
```

### `useMemo`[](#typing-usememo "Link for this heading")

The [`useMemo`](/reference/react/useMemo) Hooks will create/re-access a memorized value from a function call, re-running the function only when dependencies passed as the 2nd parameter are changed. The result of calling the Hook is inferred from the return value from the function in the first parameter. You can be more explicit by providing a type argument to the Hook.

```
// The type of visibleTodos is inferred from the return value of filterTodos

const visibleTodos = useMemo(() => filterTodos(todos, tab), [todos, tab]);
```

### `useCallback`[](#typing-usecallback "Link for this heading")

The [`useCallback`](/reference/react/useCallback) provide a stable reference to a function as long as the dependencies passed into the second parameter are the same. Like `useMemo`, the function’s type is inferred from the return value of the function in the first parameter, and you can be more explicit by providing a type argument to the Hook.

```
const handleClick = useCallback(() => {

  // ...

}, [todos]);
```

When working in TypeScript strict mode `useCallback` requires adding types for the parameters in your callback. This is because the type of the callback is inferred from the return value of the function, and without parameters the type cannot be fully understood.

Depending on your code-style preferences, you could use the `*EventHandler` functions from the React types to provide the type for the event handler at the same time as defining the callback:

```
import { useState, useCallback } from 'react';



export default function Form() {

  const [value, setValue] = useState("Change me");



  const handleChange = useCallback<React.ChangeEventHandler<HTMLInputElement>>((event) => {

    setValue(event.currentTarget.value);

  }, [setValue])

  

  return (

    <>

      <input value={value} onChange={handleChange} />

      <p>Value: {value}</p>

    </>

  );

}
```

## Useful Types[](#useful-types "Link for Useful Types ")

There is quite an expansive set of types which come from the `@types/react` package, it is worth a read when you feel comfortable with how React and TypeScript interact. You can find them [in React’s folder in DefinitelyTyped](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/react/index.d.ts). We will cover a few of the more common types here.

### DOM Events[](#typing-dom-events "Link for DOM Events ")

When working with DOM events in React, the type of the event can often be inferred from the event handler. However, when you want to extract a function to be passed to an event handler, you will need to explicitly set the type of the event.

[TypeScript Playground](https://www.typescriptlang.org/play#src=import%20*%20as%20React%20from%20'react'%3B%0A%0Aimport%20%7B%20useState%20%7D%20from%20'react'%3B%0A%0Aexport%20default%20function%20Form\(\)%20%7B%0A%20%20const%20%5Bvalue%2C%20setValue%5D%20%3D%20useState\(%22Change%20me%22\)%3B%0A%0A%20%20function%20handleChange\(event%3A%20React.ChangeEvent%3CHTMLInputElement%3E\)%20%7B%0A%20%20%20%20setValue\(event.currentTarget.value\)%3B%0A%20%20%7D%0A%0A%20%20return%20\(%0A%20%20%20%20%3C%3E%0A%20%20%20%20%20%20%3Cinput%20value%3D%7Bvalue%7D%20onChange%3D%7BhandleChange%7D%20%2F%3E%0A%20%20%20%20%20%20%3Cp%3EValue%3A%20%7Bvalue%7D%3C%2Fp%3E%0A%20%20%20%20%3C%2F%3E%0A%20%20\)%3B%0A%7D%0A "Open in TypeScript Playground")

```
import { useState } from 'react';

export default function Form() {
  const [value, setValue] = useState("Change me");

  function handleChange(event: React.ChangeEvent<HTMLInputElement>) {
    setValue(event.currentTarget.value);
  }

  return (
    <>
      <input value={value} onChange={handleChange} />
      <p>Value: {value}</p>
    </>
  );
}
```

There are many types of events provided in the React types - the full list can be found [here](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/b580df54c0819ec9df62b0835a315dd48b8594a9/types/react/index.d.ts#L1247C1-L1373) which is based on the [most popular events from the DOM](https://developer.mozilla.org/en-US/docs/Web/Events).

When determining the type you are looking for you can first look at the hover information for the event handler you are using, which will show the type of the event.

If you need to use an event that is not included in this list, you can use the `React.SyntheticEvent` type, which is the base type for all events.

### Children[](#typing-children "Link for Children ")

There are two common paths to describing the children of a component. The first is to use the `React.ReactNode` type, which is a union of all the possible types that can be passed as children in JSX:

```
interface ModalRendererProps {

  title: string;

  children: React.ReactNode;

}
```

This is a very broad definition of children. The second is to use the `React.ReactElement` type, which is only JSX elements and not JavaScript primitives like strings or numbers:

```
interface ModalRendererProps {

  title: string;

  children: React.ReactElement;

}
```

Note, that you cannot use TypeScript to describe that the children are a certain type of JSX elements, so you cannot use the type-system to describe a component which only accepts `<li>` children.

You can see an example of both `React.ReactNode` and `React.ReactElement` with the type-checker in [this TypeScript playground](https://www.typescriptlang.org/play?#code/JYWwDg9gTgLgBAJQKYEMDG8BmUIjgIilQ3wChSB6CxYmAOmXRgDkIATJOdNJMGAZzgwAFpxAR+8YADswAVwGkZMJFEzpOjDKw4AFHGEEBvUnDhphwADZsi0gFw0mDWjqQBuUgF9yaCNMlENzgAXjgACjADfkctFnYkfQhDAEpQgD44AB42YAA3dKMo5P46C2tbJGkvLIpcgt9-QLi3AEEwMFCItJDMrPTTbIQ3dKywdIB5aU4kKyQQKpha8drhhIGzLLWODbNs3b3s8YAxKBQAcwXpAThMaGWDvbH0gFloGbmrgQfBzYpd1YjQZbEYARkB6zMwO2SHSAAlZlYIBCdtCRkZpHIrFYahQYQD8UYYFA5EhcfjyGYqHAXnJAsIUHlOOUbHYhMIIHJzsI0Qk4P9SLUBuRqXEXEwAKKfRZcNA8PiCfxWACecAAUgBlAAacFm80W-CU11U6h4TgwUv11yShjgJjMLMqDnN9Dilq+nh8pD8AXgCHdMrCkWisVoAet0R6fXqhWKhjKllZVVxMcavpd4Zg7U6Qaj+2hmdG4zeRF10uu-Aeq0LBfLMEe-V+T2L7zLVu+FBWLdLeq+lc7DYFf39deFVOotMCACNOCh1dq219a+30uC8YWoZsRyuEdjkevR8uvoVMdjyTWt4WiSSydXD4NqZP4AymeZE072ZzuUeZQKheQgA).

### Style Props[](#typing-style-props "Link for Style Props ")

When using inline styles in React, you can use `React.CSSProperties` to describe the object passed to the `style` prop. This type is a union of all the possible CSS properties, and is a good way to ensure you are passing valid CSS properties to the `style` prop, and to get auto-complete in your editor.

```
interface MyComponentProps {

  style: React.CSSProperties;

}
```

***

----
url: https://18.react.dev/reference/react-dom/components
----

[API Reference](/reference/react)

# React DOM Components[](#undefined "Link for this heading")

React supports all of the browser built-in [HTML](https://developer.mozilla.org/en-US/docs/Web/HTML/Element) and [SVG](https://developer.mozilla.org/en-US/docs/Web/SVG/Element) components.

***

## Common components[](#common-components "Link for Common components ")

All of the built-in browser components support some props and events.

* [Common components (e.g. `<div>`)](/reference/react-dom/components/common)

This includes React-specific props like `ref` and `dangerouslySetInnerHTML`.

***

## Form components[](#form-components "Link for Form components ")

These built-in browser components accept user input:

* [`<input>`](/reference/react-dom/components/input)
* [`<select>`](/reference/react-dom/components/select)
* [`<textarea>`](/reference/react-dom/components/textarea)

They are special in React because passing the `value` prop to them makes them *[controlled.](/reference/react-dom/components/input#controlling-an-input-with-a-state-variable)*

***

***

***

### Custom HTML elements[](#custom-html-elements "Link for Custom HTML elements ")

If you render a tag with a dash, like `<my-element>`, React will assume you want to render a [custom HTML element.](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements) In React, rendering custom elements works differently from rendering built-in browser tags:

* All custom element props are serialized to strings and are always set using attributes.
* Custom elements accept `class` rather than `className`, and `for` rather than `htmlFor`.

If you render a built-in browser HTML element with an [`is`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/is) attribute, it will also be treated as a custom element.

### Note

[A future version of React will include more comprehensive support for custom elements.](https://github.com/facebook/react/issues/11347#issuecomment-1122275286)

You can try it by upgrading React packages to the most recent experimental version:

* `react@experimental`
* `react-dom@experimental`

Experimental versions of React may contain bugs. Don’t use them in production.

***

***

----
url: https://react.dev/learn/react-compiler/installation
----

[Learn React](/learn)

[React Compiler](/learn/react-compiler)

# Installation[](#undefined "Link for this heading")

This guide will help you install and configure React Compiler in your React application.

### You will learn

* How to install React Compiler
* Basic configuration for different build tools
* How to verify your setup is working

## Prerequisites[](#prerequisites "Link for Prerequisites ")

React Compiler is designed to work best with React 19, but it also supports React 17 and 18. Learn more about [React version compatibility](/reference/react-compiler/target).

## Installation[](#installation "Link for Installation ")

Install React Compiler as a `devDependency`:

Terminal

```
npm install -D babel-plugin-react-compiler@latest
```

Or with Yarn:

Terminal

```
yarn add -D babel-plugin-react-compiler@latest
```

Or with pnpm:

Terminal

```
pnpm install -D babel-plugin-react-compiler@latest
```

## Basic Setup[](#basic-setup "Link for Basic Setup ")

React Compiler is designed to work by default without any configuration. However, if you need to configure it in special circumstances (for example, to target React versions below 19), refer to the [compiler options reference](/reference/react-compiler/configuration).

The setup process depends on your build tool. React Compiler includes a Babel plugin that integrates with your build pipeline.

### Pitfall

React Compiler must run **first** in your Babel plugin pipeline. The compiler needs the original source information for proper analysis, so it must process your code before other transformations.

### Babel[](#babel "Link for Babel ")

Create or update your `babel.config.js`:

```
module.exports = {

  plugins: [

    'babel-plugin-react-compiler', // must run first!

    // ... other plugins

  ],

  // ... other config

};
```

### Vite[](#vite "Link for Vite ")

If you use Vite with version 6.0.0 or later of `@vitejs/plugin-react`, you can use the `reactCompilerPreset`:

Terminal

```
npm install -D @rolldown/plugin-babel
```

```
// vite.config.js

import { defineConfig } from 'vite';

import react, { reactCompilerPreset } from '@vitejs/plugin-react';

import babel from '@rolldown/plugin-babel';



export default defineConfig({

  plugins: [

    react(),

    babel({

      presets: [reactCompilerPreset()]

    }),

  ],

});
```

### Note

In `@vitejs/plugin-react@6.0.0`, the inline Babel option was removed. If you’re using an older version, you can use:

```
// vite.config.js

import { defineConfig } from 'vite';

import react from '@vitejs/plugin-react';



export default defineConfig({

  plugins: [

    react({

      babel: {

        plugins: ['babel-plugin-react-compiler'],

      },

    }),

  ],

});
```

Alternatively, you can use the Babel plugin directly with `@rolldown/plugin-babel`:

```
// vite.config.js

import { defineConfig } from 'vite';

import react from '@vitejs/plugin-react';

import babel from '@rolldown/plugin-babel';



export default defineConfig({

  plugins: [

    react(),

    babel({

      plugins: ['babel-plugin-react-compiler'],

    }),

  ],

});
```

### Next.js[](#usage-with-nextjs "Link for Next.js ")

Please refer to the [Next.js docs](https://nextjs.org/docs/app/api-reference/next-config-js/reactCompiler) for more information.

### React Router[](#usage-with-react-router "Link for React Router ")

Install `vite-plugin-babel`, and add the compiler’s Babel plugin to it:

Terminal

```
npm install vite-plugin-babel
```

```
// vite.config.js

import { defineConfig } from "vite";

import babel from "vite-plugin-babel";

import { reactRouter } from "@react-router/dev/vite";



const ReactCompilerConfig = { /* ... */ };



export default defineConfig({

  plugins: [

    reactRouter(),

    babel({

      filter: /\.[jt]sx?$/,

      babelConfig: {

        presets: ["@babel/preset-typescript"], // if you use TypeScript

        plugins: [

          ["babel-plugin-react-compiler", ReactCompilerConfig],

        ],

      },

    }),

  ],

});
```

### Webpack[](#usage-with-webpack "Link for Webpack ")

A community webpack loader is [now available here](https://github.com/SukkaW/react-compiler-webpack).

### Expo[](#usage-with-expo "Link for Expo ")

Please refer to [Expo’s docs](https://docs.expo.dev/guides/react-compiler/) to enable and use the React Compiler in Expo apps.

### Metro (React Native)[](#usage-with-react-native-metro "Link for Metro (React Native) ")

React Native uses Babel via Metro, so refer to the [Usage with Babel](#babel) section for installation instructions.

### Rspack[](#usage-with-rspack "Link for Rspack ")

Please refer to [Rspack’s docs](https://rspack.dev/guide/tech/react#react-compiler) to enable and use the React Compiler in Rspack apps.

### Rsbuild[](#usage-with-rsbuild "Link for Rsbuild ")

Please refer to [Rsbuild’s docs](https://rsbuild.dev/guide/framework/react#react-compiler) to enable and use the React Compiler in Rsbuild apps.

## ESLint Integration[](#eslint-integration "Link for ESLint Integration ")

React Compiler includes an ESLint rule that helps identify code that can’t be optimized. When the ESLint rule reports an error, it means the compiler will skip optimizing that specific component or hook. This is safe: the compiler will continue optimizing other parts of your codebase. You don’t need to fix all violations immediately. Address them at your own pace to gradually increase the number of optimized components.

Install the ESLint plugin:

Terminal

```
npm install -D eslint-plugin-react-hooks@latest
```

If you haven’t already configured eslint-plugin-react-hooks, follow the [installation instructions in the readme](https://github.com/facebook/react/blob/main/packages/eslint-plugin-react-hooks/README.md#installation). The compiler rules are available in the `recommended-latest` preset.

The ESLint rule will:

* Identify violations of the [Rules of React](/reference/rules)
* Show which components can’t be optimized
* Provide helpful error messages for fixing issues

## Verify Your Setup[](#verify-your-setup "Link for Verify Your Setup ")

After installation, verify that React Compiler is working correctly.

### Check React DevTools[](#check-react-devtools "Link for Check React DevTools ")

Components optimized by React Compiler will show a “Memo ✨” badge in React DevTools:

1. Install the [React Developer Tools](/learn/react-developer-tools) browser extension
2. Open your app in development mode
3. Open React DevTools
4. Look for the ✨ emoji next to component names

If the compiler is working:

* Components will show a “Memo ✨” badge in React DevTools
* Expensive calculations will be automatically memoized
* No manual `useMemo` is required

### Check Build Output[](#check-build-output "Link for Check Build Output ")

You can also verify the compiler is running by checking your build output. The compiled code will include automatic memoization logic that the compiler adds automatically.

```
import { c as _c } from "react/compiler-runtime";

export default function MyApp() {

  const $ = _c(1);

  let t0;

  if ($[0] === Symbol.for("react.memo_cache_sentinel")) {

    t0 = <div>Hello World</div>;

    $[0] = t0;

  } else {

    t0 = $[0];

  }

  return t0;

}
```

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### Opting out specific components[](#opting-out-specific-components "Link for Opting out specific components ")

If a component is causing issues after compilation, you can temporarily opt it out using the `"use no memo"` directive:

```
function ProblematicComponent() {

  "use no memo";

  // Component code here

}
```

This tells the compiler to skip optimization for this specific component. You should fix the underlying issue and remove the directive once resolved.

For more troubleshooting help, see the [debugging guide](/learn/react-compiler/debugging).

## Next Steps[](#next-steps "Link for Next Steps ")

Now that you have React Compiler installed, learn more about:

* [React version compatibility](/reference/react-compiler/target) for React 17 and 18
* [Configuration options](/reference/react-compiler/configuration) to customize the compiler
* [Incremental adoption strategies](/learn/react-compiler/incremental-adoption) for existing codebases
* [Debugging techniques](/learn/react-compiler/debugging) for troubleshooting issues
* [Compiling Libraries guide](/reference/react-compiler/compiling-libraries) for compiling your React library

[PreviousIntroduction](/learn/react-compiler/introduction)

[NextIncremental Adoption](/learn/react-compiler/incremental-adoption)

***

----
url: https://react.dev/reference/react/apis
----

[API Reference](/reference/react)

# Built-in React APIs[](#undefined "Link for this heading")

In addition to [Hooks](/reference/react/hooks) and [Components](/reference/react/components), the `react` package exports a few other APIs that are useful for defining components. This page lists all the remaining modern React APIs.

***

* [`createContext`](/reference/react/createContext) lets you define and provide context to the child components. Used with [`useContext`.](/reference/react/useContext)
* [`lazy`](/reference/react/lazy) lets you defer loading a component’s code until it’s rendered for the first time.
* [`memo`](/reference/react/memo) lets your component skip re-renders with same props. Used with [`useMemo`](/reference/react/useMemo) and [`useCallback`.](/reference/react/useCallback)
* [`startTransition`](/reference/react/startTransition) lets you mark a state update as non-urgent. Similar to [`useTransition`.](/reference/react/useTransition)
* [`act`](/reference/react/act) lets you wrap renders and interactions in tests to ensure updates have processed before making assertions.

***

## Resource APIs[](#resource-apis "Link for Resource APIs ")

*Resources* can be accessed by a component without having them as part of their state. For example, a component can read a message from a Promise or read styling information from a context.

To read a value from a resource, use this API:

* [`use`](/reference/react/use) lets you read the value of a resource like a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) or [context](/learn/passing-data-deeply-with-context).

```
function MessageComponent({ messagePromise }) {

  const message = use(messagePromise);

  const theme = use(ThemeContext);

  // ...

}
```

[Previous\<ViewTransition>](/reference/react/ViewTransition)

[Nextact](/reference/react/act)

***

----
url: https://legacy.reactjs.org/blog/2019/02/06/react-v16.8.0.html
----

February 06, 2019 by [Dan Abramov](https://twitter.com/dan_abramov)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

With React 16.8, [React Hooks](/docs/hooks-intro.html) are available in a stable release!

## [](#what-are-hooks)What Are Hooks?

Hooks let you use state and other React features without writing a class. You can also **build your own Hooks** to share reusable stateful logic between components.

If you’ve never heard of Hooks before, you might find these resources interesting:

* [Introducing Hooks](/docs/hooks-intro.html) explains why we’re adding Hooks to React.
* [Hooks at a Glance](/docs/hooks-overview.html) is a fast-paced overview of the built-in Hooks.
* [Building Your Own Hooks](/docs/hooks-custom.html) demonstrates code reuse with custom Hooks.
* [Making Sense of React Hooks](https://medium.com/@dan_abramov/making-sense-of-react-hooks-fdbde8803889) explores the new possibilities unlocked by Hooks.
* [useHooks.com](https://usehooks.com/) showcases community-maintained Hooks recipes and demos.

**You don’t have to learn Hooks right now.** Hooks have no breaking changes, and we have no plans to remove classes from React. The [Hooks FAQ](/docs/hooks-faq.html) describes the gradual adoption strategy.

## [](#no-big-rewrites)No Big Rewrites

We don’t recommend rewriting your existing applications to use Hooks overnight. Instead, try using Hooks in some of the new components, and let us know what you think. Code using Hooks will work [side by side](/docs/hooks-intro.html#gradual-adoption-strategy) with existing code using classes.

## [](#can-i-use-hooks-today)Can I Use Hooks Today?

Yes! Starting with 16.8.0, React includes a stable implementation of React Hooks for:

* React DOM
* React DOM Server
* React Test Renderer
* React Shallow Renderer

Note that **to enable Hooks, all React packages need to be 16.8.0 or higher**. Hooks won’t work if you forget to update, for example, React DOM.

**React Native will support Hooks in the [0.59 release](https://github.com/react-native-community/react-native-releases/issues/79#issuecomment-457735214).**

## [](#tooling-support)Tooling Support

React Hooks are now supported by React DevTools. They are also supported in the latest Flow and TypeScript definitions for React. We strongly recommend enabling a new [lint rule called `eslint-plugin-react-hooks`](https://www.npmjs.com/package/eslint-plugin-react-hooks) to enforce best practices with Hooks. It will soon be included into Create React App by default.

## [](#whats-next)What’s Next

We described our plan for the next months in the recently published [React Roadmap](/blog/2018/11/27/react-16-roadmap.html).

Note that React Hooks don’t cover *all* use cases for classes yet but they’re [very close](/docs/hooks-faq.html#do-hooks-cover-all-use-cases-for-classes). Currently, only `getSnapshotBeforeUpdate()` and `componentDidCatch()` methods don’t have equivalent Hooks APIs, and these lifecycles are relatively uncommon. If you want, you should be able to use Hooks in most of the new code you’re writing.

Even while Hooks were in alpha, the React community created many interesting [examples](https://codesandbox.io/react-hooks) and [recipes](https://usehooks.com) using Hooks for animations, forms, subscriptions, integrating with other libraries, and so on. We’re excited about Hooks because they make code reuse easier, helping you write your components in a simpler way and make great user experiences. We can’t wait to see what you’ll create next!

## [](#testing-hooks)Testing Hooks

We have added a new API called `ReactTestUtils.act()` in this release. It ensures that the behavior in your tests matches what happens in the browser more closely. We recommend to wrap any code rendering and triggering updates to your components into `act()` calls. Testing libraries can also wrap their APIs with it (for example, [`react-testing-library`](https://testing-library.com/react)’s `render` and `fireEvent` utilities do this).

For example, the counter example from [this page](/docs/hooks-effect.html) can be tested like this:

```
import React from 'react';
import ReactDOM from 'react-dom';
import { act } from 'react-dom/test-utils';import Counter from './Counter';

let container;

beforeEach(() => {
  container = document.createElement('div');
  document.body.appendChild(container);
});

afterEach(() => {
  document.body.removeChild(container);
  container = null;
});

it('can render and update a counter', () => {
  // Test first render and effect
  act(() => {    ReactDOM.render(<Counter />, container);  });  const button = container.querySelector('button');
  const label = container.querySelector('p');
  expect(label.textContent).toBe('You clicked 0 times');
  expect(document.title).toBe('You clicked 0 times');

  // Test second render and effect
  act(() => {    button.dispatchEvent(new MouseEvent('click', {bubbles: true}));  });  expect(label.textContent).toBe('You clicked 1 times');
  expect(document.title).toBe('You clicked 1 times');
});
```

The calls to `act()` will also flush the effects inside of them.

If you need to test a custom Hook, you can do so by creating a component in your test, and using your Hook from it. Then you can test the component you wrote.

To reduce the boilerplate, we recommend using [`react-testing-library`](https://testing-library.com/react) which is designed to encourage writing tests that use your components as the end users do.

## [](#thanks)Thanks

We’d like to thank everybody who commented on the [Hooks RFC](https://github.com/reactjs/rfcs/pull/68) for sharing their feedback. We’ve read all of your comments and made some adjustments to the final API based on them.

## [](#installation)Installation

### [](#react)React

React v16.8.0 is available on the npm registry.

To install React 16 with Yarn, run:

```
yarn add react@^16.8.0 react-dom@^16.8.0
```

To install React 16 with npm, run:

```
npm install --save react@^16.8.0 react-dom@^16.8.0
```

We also provide UMD builds of React via a CDN:

```
<script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
```

Refer to the documentation for [detailed installation instructions](/docs/installation.html).

### [](#eslint-plugin-for-react-hooks)ESLint Plugin for React Hooks

> Note
>
> As mentioned above, we strongly recommend using the `eslint-plugin-react-hooks` lint rule.
>
> If you’re using Create React App, instead of manually configuring ESLint you can wait for the next version of `react-scripts` which will come out shortly and will include this rule.

Assuming you already have ESLint installed, run:

```
# npm
npm install eslint-plugin-react-hooks --save-dev

# yarn
yarn add eslint-plugin-react-hooks --dev
```

Then add it to your ESLint configuration:

```
{
  "plugins": [
    // ...
    "react-hooks"
  ],
  "rules": {
    // ...
    "react-hooks/rules-of-hooks": "error"
  }
}
```

## [](#changelog)Changelog

### [](#react-1)React

* Add [Hooks](https://reactjs.org/docs/hooks-intro.html) — a way to use state and other React features without writing a class. ([@acdlite](https://github.com/acdlite) et al. in [#13968](https://github.com/facebook/react/pull/13968))
* Improve the `useReducer` Hook lazy initialization API. ([@acdlite](https://github.com/acdlite) in [#14723](https://github.com/facebook/react/pull/14723))

### [](#react-dom)React DOM

* Bail out of rendering on identical values for `useState` and `useReducer` Hooks. ([@acdlite](https://github.com/acdlite) in [#14569](https://github.com/facebook/react/pull/14569))
* Don’t compare the first argument passed to `useEffect`/`useMemo`/`useCallback` Hooks. ([@acdlite](https://github.com/acdlite) in [#14594](https://github.com/facebook/react/pull/14594))
* Use `Object.is` algorithm for comparing `useState` and `useReducer` values. ([@Jessidhia](https://github.com/Jessidhia) in [#14752](https://github.com/facebook/react/pull/14752))
* Support synchronous thenables passed to `React.lazy()`. ([@gaearon](https://github.com/gaearon) in [#14626](https://github.com/facebook/react/pull/14626))
* Render components with Hooks twice in Strict Mode (DEV-only) to match class behavior. ([@gaearon](https://github.com/gaearon) in [#14654](https://github.com/facebook/react/pull/14654))
* Warn about mismatching Hook order in development. ([@threepointone](https://github.com/threepointone) in [#14585](https://github.com/facebook/react/pull/14585) and [@acdlite](https://github.com/acdlite) in [#14591](https://github.com/facebook/react/pull/14591))
* Effect clean-up functions must return either `undefined` or a function. All other values, including `null`, are not allowed. [@acdlite](https://github.com/acdlite) in [#14119](https://github.com/facebook/react/pull/14119)

### [](#react-test-renderer)React Test Renderer

* Support Hooks in the shallow renderer. ([@trueadm](https://github.com/trueadm) in [#14567](https://github.com/facebook/react/pull/14567))
* Fix wrong state in `shouldComponentUpdate` in the presence of `getDerivedStateFromProps` for Shallow Renderer. ([@chenesan](https://github.com/chenesan) in [#14613](https://github.com/facebook/react/pull/14613))
* Add `ReactTestRenderer.act()` and `ReactTestUtils.act()` for batching updates so that tests more closely match real behavior. ([@threepointone](https://github.com/threepointone) in [#14744](https://github.com/facebook/react/pull/14744))

### [](#eslint-plugin-react-hooks)ESLint Plugin: React Hooks

* Initial [release](https://www.npmjs.com/package/eslint-plugin-react-hooks). ([@calebmer](https://github.com/calebmer) in [#13968](https://github.com/facebook/react/pull/13968))
* Fix reporting after encountering a loop. ([@calebmer](https://github.com/calebmer) and [@Yurickh](https://github.com/Yurickh) in [#14661](https://github.com/facebook/react/pull/14661))
* Don’t consider throwing to be a rule violation. ([@sophiebits](https://github.com/sophiebits) in [#14040](https://github.com/facebook/react/pull/14040))

## [](#hooks-changelog-since-alpha-versions)Hooks Changelog Since Alpha Versions

The above changelog contains all notable changes since our last **stable** release (16.7.0). [As with all our minor releases](/docs/faq-versioning.html), none of the changes break backwards compatibility.

If you’re currently using Hooks from an alpha build of React, note that this release does contain some small breaking changes to Hooks. **We don’t recommend depending on alphas in production code.** We publish them so we can make changes in response to community feedback before the API is stable.

Here are all breaking changes to Hooks that have been made since the first alpha release:

* Remove `useMutationEffect`. ([@sophiebits](https://github.com/sophiebits) in [#14336](https://github.com/facebook/react/pull/14336))
* Rename `useImperativeMethods` to `useImperativeHandle`. ([@threepointone](https://github.com/threepointone) in [#14565](https://github.com/facebook/react/pull/14565))
* Bail out of rendering on identical values for `useState` and `useReducer` Hooks. ([@acdlite](https://github.com/acdlite) in [#14569](https://github.com/facebook/react/pull/14569))
* Don’t compare the first argument passed to `useEffect`/`useMemo`/`useCallback` Hooks. ([@acdlite](https://github.com/acdlite) in [#14594](https://github.com/facebook/react/pull/14594))
* Use `Object.is` algorithm for comparing `useState` and `useReducer` values. ([@Jessidhia](https://github.com/Jessidhia) in [#14752](https://github.com/facebook/react/pull/14752))
* Render components with Hooks twice in Strict Mode (DEV-only). ([@gaearon](https://github.com/gaearon) in [#14654](https://github.com/facebook/react/pull/14654))
* Improve the `useReducer` Hook lazy initialization API. ([@acdlite](https://github.com/acdlite) in [#14723](https://github.com/facebook/react/pull/14723))

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2019-02-06-react-v16.8.0.md)

----
url: https://legacy.reactjs.org/blog/2017/12/07/introducing-the-react-rfc-process.html
----

December 07, 2017 by [Andrew Clark](https://twitter.com/acdlite)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

We’re adopting an RFC (“request for comments”) process for contributing ideas to React.

Inspired by [Yarn](https://github.com/yarnpkg/rfcs), [Ember](https://github.com/emberjs/rfcs), and [Rust](https://github.com/rust-lang/rfcs), the goal is to allow React core team members and community members to collaborate on the design of new features. It’s also intended to provide a clear path for ideas to enter the project:

* Create an RFC document detailing your proposal.
* Submit a PR to the [RFC repository](https://github.com/reactjs/rfcs).
* Incorporate feedback into the proposal.
* After discussion, the core team may or may not accept the RFC.
* If the RFC is accepted, the PR is merged.

RFCs are accepted when they are approved for implementation in React. A more thorough description of the process is available in the repository’s [README](https://github.com/reactjs/rfcs/blob/master/README.md). The exact details may be refined in the future.

## [](#who-can-submit-rfcs)Who Can Submit RFCs?

Anyone! No knowledge of React’s internals is required, nor are you expected to implement the proposal yourself.

As with our other repositories, we do ask that you complete a [Contributor License Agreement](https://github.com/reactjs/rfcs#contributor-license-agreement-cla) before we can accept your PR.

## [](#what-types-of-changes-should-be-submitted-as-rfcs)What Types of Changes Should Be Submitted As RFCs?

Generally, any idea that would benefit from additional review or design before being implemented is a good candidate for an RFC. As a rule of thumb, this means any proposal that adds, changes, or removes a React API.

Not every change must go through the RFC process. Bug fixes or performance improvements that don’t touch the API can be submitted directly to the main library.

We now have several repositories where you can submit contributions to React:

* **Issues, bugfixes, and code changes to the main library**: [facebook/react](https://github.com/facebook/react)
* **Website and documentation**: [reactjs/reactjs.org](https://github.com/reactjs/reactjs.org)
* **Ideas for changes that need additional review before being implemented**: [reactjs/rfcs](https://github.com/reactjs/rfcs)

## [](#rfc-for-a-new-context-api)RFC for A New Context API

Coinciding with the launch of our RFC process, we’ve submitted a [proposal for a new version of context](https://github.com/reactjs/rfcs/pull/2). The proposal has already received many valuable comments from the community that we will incorporate into the design of the new API.

The context PR is a good example of how a typical RFC should be structured. We’re excited to start receiving your proposals!

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2017-12-07-introducing-the-react-rfc-process.md)

----
url: https://18.react.dev/learn/tutorial-tic-tac-toe
----

```
import { useState } from 'react';

function Square({ value, onSquareClick }) {
  return (
    <button className="square" onClick={onSquareClick}>
      {value}
    </button>
  );
}

function Board({ xIsNext, squares, onPlay }) {
  function handleClick(i) {
    if (calculateWinner(squares) || squares[i]) {
      return;
    }
    const nextSquares = squares.slice();
    if (xIsNext) {
      nextSquares[i] = 'X';
    } else {
      nextSquares[i] = 'O';
    }
    onPlay(nextSquares);
  }

  const winner = calculateWinner(squares);
  let status;
  if (winner) {
    status = 'Winner: ' + winner;
  } else {
    status = 'Next player: ' + (xIsNext ? 'X' : 'O');
  }

  return (
    <>
      <div className="status">{status}</div>
      <div className="board-row">
        <Square value={squares[0]} onSquareClick={() => handleClick(0)} />
        <Square value={squares[1]} onSquareClick={() => handleClick(1)} />
        <Square value={squares[2]} onSquareClick={() => handleClick(2)} />
      </div>
      <div className="board-row">
        <Square value={squares[3]} onSquareClick={() => handleClick(3)} />
        <Square value={squares[4]} onSquareClick={() => handleClick(4)} />
        <Square value={squares[5]} onSquareClick={() => handleClick(5)} />
      </div>
      <div className="board-row">
        <Square value={squares[6]} onSquareClick={() => handleClick(6)} />
        <Square value={squares[7]} onSquareClick={() => handleClick(7)} />
        <Square value={squares[8]} onSquareClick={() => handleClick(8)} />
      </div>
    </>
  );
}

export default function Game() {
  const [history, setHistory] = useState([Array(9).fill(null)]);
  const [currentMove, setCurrentMove] = useState(0);
  const xIsNext = currentMove % 2 === 0;
  const currentSquares = history[currentMove];

  function handlePlay(nextSquares) {
    const nextHistory = [...history.slice(0, currentMove + 1), nextSquares];
    setHistory(nextHistory);
    setCurrentMove(nextHistory.length - 1);
  }

  function jumpTo(nextMove) {
    setCurrentMove(nextMove);
  }

  const moves = history.map((squares, move) => {
    let description;
    if (move > 0) {
      description = 'Go to move #' + move;
    } else {
      description = 'Go to game start';
    }
    return (
      <li key={move}>
        <button onClick={() => jumpTo(move)}>{description}</button>
      </li>
    );
  });

  return (
    <div className="game">
      <div className="game-board">
        <Board xIsNext={xIsNext} squares={currentSquares} onPlay={handlePlay} />
      </div>
      <div className="game-info">
        <ol>{moves}</ol>
      </div>
    </div>
  );
}

function calculateWinner(squares) {
  const lines = [
    [0, 1, 2],
    [3, 4, 5],
    [6, 7, 8],
    [0, 3, 6],
    [1, 4, 7],
    [2, 5, 8],
    [0, 4, 8],
    [2, 4, 6],
  ];
  for (let i = 0; i < lines.length; i++) {
    const [a, b, c] = lines[i];
    if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
      return squares[a];
    }
  }
  return null;
}
```

If the code doesn’t make sense to you yet, or if you are unfamiliar with the code’s syntax, don’t worry! The goal of this tutorial is to help you understand React and its syntax.

We recommend that you check out the tic-tac-toe game above before continuing with the tutorial. One of the features that you’ll notice is that there is a numbered list to the right of the game’s board. This list gives you a history of all of the moves that have occurred in the game, and it is updated as the game progresses.

Once you’ve played around with the finished tic-tac-toe game, keep scrolling. You’ll start with a simpler template in this tutorial. Our next step is to set you up so that you can start building the game.

## Setup for the tutorial[](#setup-for-the-tutorial "Link for Setup for the tutorial ")

In the live code editor below, click **Fork** in the top-right corner to open the editor in a new tab using the website CodeSandbox. CodeSandbox lets you write code in your browser and preview how your users will see the app you’ve created. The new tab should display an empty square and the starter code for this tutorial.

```
export default function Square() {
  return <button className="square">X</button>;
}
```

1. The *Files* section with a list of files like `App.js`, `index.js`, `styles.css` and a folder called `public`
2. The *code editor* where you’ll see the source code of your selected file
3. The *browser* section where you’ll see how the code you’ve written will be displayed

The `App.js` file should be selected in the *Files* section. The contents of that file in the *code editor* should be:

```
export default function Square() {

  return <button className="square">X</button>;

}
```

The *browser* section should be displaying a square with a X in it like this:

Now let’s have a look at the files in the starter code.

#### `App.js`[](#appjs "Link for this heading")

The code in `App.js` creates a *component*. In React, a component is a piece of reusable code that represents a part of a user interface. Components are used to render, manage, and update the UI elements in your application. Let’s look at the component line by line to see what’s going on:

```
export default function Square() {

  return <button className="square">X</button>;

}
```

The first line defines a function called `Square`. The `export` JavaScript keyword makes this function accessible outside of this file. The `default` keyword tells other files using your code that it’s the main function in your file.

```
export default function Square() {

  return <button className="square">X</button>;

}
```

The second line returns a button. The `return` JavaScript keyword means whatever comes after is returned as a value to the caller of the function. `<button>` is a *JSX element*. A JSX element is a combination of JavaScript code and HTML tags that describes what you’d like to display. `className="square"` is a button property or *prop* that tells CSS how to style the button. `X` is the text displayed inside of the button and `</button>` closes the JSX element to indicate that any following content shouldn’t be placed inside the button.

#### `styles.css`[](#stylescss "Link for this heading")

Click on the file labeled `styles.css` in the *Files* section of CodeSandbox. This file defines the styles for your React app. The first two *CSS selectors* (`*` and `body`) define the style of large parts of your app while the `.square` selector defines the style of any component where the `className` property is set to `square`. In your code, that would match the button from your Square component in the `App.js` file.

#### `index.js`[](#indexjs "Link for this heading")

Click on the file labeled `index.js` in the *Files* section of CodeSandbox. You won’t be editing this file during the tutorial but it is the bridge between the component you created in the `App.js` file and the web browser.

```
import { StrictMode } from 'react';

import { createRoot } from 'react-dom/client';

import './styles.css';



import App from './App';
```

```
export default function Square() {

  return <button className="square">X</button><button className="square">X</button>;

}
```

You’ll get this error:

Console

/src/App.js: Adjacent JSX elements must be wrapped in an enclosing tag. Did you want a JSX Fragment `<>...</>`?

React components need to return a single JSX element and not multiple adjacent JSX elements like two buttons. To fix this you can use *Fragments* (`<>` and `</>`) to wrap multiple adjacent JSX elements like this:

```
export default function Square() {

  return (

    <>

      <button className="square">X</button>

      <button className="square">X</button>

    </>

  );

}
```

Now you should see:

Great! Now you just need to copy-paste a few times to add nine squares and…

Oh no! The squares are all in a single line, not in a grid like you need for our board. To fix this you’ll need to group your squares into rows with `div`s and add some CSS classes. While you’re at it, you’ll give each square a number to make sure you know where each square is displayed.

In the `App.js` file, update the `Square` component to look like this:

```
export default function Square() {

  return (

    <>

      <div className="board-row">

        <button className="square">1</button>

        <button className="square">2</button>

        <button className="square">3</button>

      </div>

      <div className="board-row">

        <button className="square">4</button>

        <button className="square">5</button>

        <button className="square">6</button>

      </div>

      <div className="board-row">

        <button className="square">7</button>

        <button className="square">8</button>

        <button className="square">9</button>

      </div>

    </>

  );

}
```

The CSS defined in `styles.css` styles the divs with the `className` of `board-row`. Now that you’ve grouped your components into rows with the styled `div`s you have your tic-tac-toe board:

But you now have a problem. Your component named `Square`, really isn’t a square anymore. Let’s fix that by changing the name to `Board`:

```
export default function Board() {

  //...

}
```

At this point your code should look something like this:

```
export default function Board() {
  return (
    <>
      <div className="board-row">
        <button className="square">1</button>
        <button className="square">2</button>
        <button className="square">3</button>
      </div>
      <div className="board-row">
        <button className="square">4</button>
        <button className="square">5</button>
        <button className="square">6</button>
      </div>
      <div className="board-row">
        <button className="square">7</button>
        <button className="square">8</button>
        <button className="square">9</button>
      </div>
    </>
  );
}
```

### Note

Psssst… That’s a lot to type! It’s okay to copy and paste code from this page. However, if you’re up for a little challenge, we recommend only copying code that you’ve manually typed at least once yourself.

### Passing data through props[](#passing-data-through-props "Link for Passing data through props ")

Next, you’ll want to change the value of a square from empty to “X” when the user clicks on the square. With how you’ve built the board so far you would need to copy-paste the code that updates the square nine times (once for each square you have)! Instead of copy-pasting, React’s component architecture allows you to create a reusable component to avoid messy, duplicated code.

First, you are going to copy the line defining your first square (`<button className="square">1</button>`) from your `Board` component into a new `Square` component:

```
function Square() {

  return <button className="square">1</button>;

}



export default function Board() {

  // ...

}
```

Then you’ll update the Board component to render that `Square` component using JSX syntax:

```
// ...

export default function Board() {

  return (

    <>

      <div className="board-row">

        <Square />

        <Square />

        <Square />

      </div>

      <div className="board-row">

        <Square />

        <Square />

        <Square />

      </div>

      <div className="board-row">

        <Square />

        <Square />

        <Square />

      </div>

    </>

  );

}
```

Note how unlike the browser `div`s, your own components `Board` and `Square` must start with a capital letter.

Let’s take a look:

Oh no! You lost the numbered squares you had before. Now each square says “1”. To fix this, you will use *props* to pass the value each square should have from the parent component (`Board`) to its child (`Square`).

Update the `Square` component to read the `value` prop that you’ll pass from the `Board`:

```
function Square({ value }) {

  return <button className="square">1</button>;

}
```

`function Square({ value })` indicates the Square component can be passed a prop called `value`.

Now you want to display that `value` instead of `1` inside every square. Try doing it like this:

```
function Square({ value }) {

  return <button className="square">value</button>;

}
```

Oops, this is not what you wanted:

You wanted to render the JavaScript variable called `value` from your component, not the word “value”. To “escape into JavaScript” from JSX, you need curly braces. Add curly braces around `value` in JSX like so:

```
function Square({ value }) {

  return <button className="square">{value}</button>;

}
```

For now, you should see an empty board:

This is because the `Board` component hasn’t passed the `value` prop to each `Square` component it renders yet. To fix it you’ll add the `value` prop to each `Square` component rendered by the `Board` component:

```
export default function Board() {

  return (

    <>

      <div className="board-row">

        <Square value="1" />

        <Square value="2" />

        <Square value="3" />

      </div>

      <div className="board-row">

        <Square value="4" />

        <Square value="5" />

        <Square value="6" />

      </div>

      <div className="board-row">

        <Square value="7" />

        <Square value="8" />

        <Square value="9" />

      </div>

    </>

  );

}
```

Now you should see a grid of numbers again:

Your updated code should look like this:

```
function Square({ value }) {
  return <button className="square">{value}</button>;
}

export default function Board() {
  return (
    <>
      <div className="board-row">
        <Square value="1" />
        <Square value="2" />
        <Square value="3" />
      </div>
      <div className="board-row">
        <Square value="4" />
        <Square value="5" />
        <Square value="6" />
      </div>
      <div className="board-row">
        <Square value="7" />
        <Square value="8" />
        <Square value="9" />
      </div>
    </>
  );
}
```

### Making an interactive component[](#making-an-interactive-component "Link for Making an interactive component ")

Let’s fill the `Square` component with an `X` when you click it. Declare a function called `handleClick` inside of the `Square`. Then, add `onClick` to the props of the button JSX element returned from the `Square`:

```
function Square({ value }) {

  function handleClick() {

    console.log('clicked!');

  }



  return (

    <button

      className="square"

      onClick={handleClick}

    >

      {value}

    </button>

  );

}
```

If you click on a square now, you should see a log saying `"clicked!"` in the *Console* tab at the bottom of the *Browser* section in CodeSandbox. Clicking the square more than once will log `"clicked!"` again. Repeated console logs with the same message will not create more lines in the console. Instead, you will see an incrementing counter next to your first `"clicked!"` log.

### Note

If you are following this tutorial using your local development environment, you need to open your browser’s Console. For example, if you use the Chrome browser, you can view the Console with the keyboard shortcut **Shift + Ctrl + J** (on Windows/Linux) or **Option + ⌘ + J** (on macOS).

As a next step, you want the Square component to “remember” that it got clicked, and fill it with an “X” mark. To “remember” things, components use *state*.

React provides a special function called `useState` that you can call from your component to let it “remember” things. Let’s store the current value of the `Square` in state, and change it when the `Square` is clicked.

Import `useState` at the top of the file. Remove the `value` prop from the `Square` component. Instead, add a new line at the start of the `Square` that calls `useState`. Have it return a state variable called `value`:

```
import { useState } from 'react';



function Square() {

  const [value, setValue] = useState(null);



  function handleClick() {

    //...
```

`value` stores the value and `setValue` is a function that can be used to change the value. The `null` passed to `useState` is used as the initial value for this state variable, so `value` here starts off equal to `null`.

Since the `Square` component no longer accepts props anymore, you’ll remove the `value` prop from all nine of the Square components created by the Board component:

```
// ...

export default function Board() {

  return (

    <>

      <div className="board-row">

        <Square />

        <Square />

        <Square />

      </div>

      <div className="board-row">

        <Square />

        <Square />

        <Square />

      </div>

      <div className="board-row">

        <Square />

        <Square />

        <Square />

      </div>

    </>

  );

}
```

Now you’ll change `Square` to display an “X” when clicked. Replace the `console.log("clicked!");` event handler with `setValue('X');`. Now your `Square` component looks like this:

```
function Square() {

  const [value, setValue] = useState(null);



  function handleClick() {

    setValue('X');

  }



  return (

    <button

      className="square"

      onClick={handleClick}

    >

      {value}

    </button>

  );

}
```

By calling this `set` function from an `onClick` handler, you’re telling React to re-render that `Square` whenever its `<button>` is clicked. After the update, the `Square`’s `value` will be `'X'`, so you’ll see the “X” on the game board. Click on any Square, and “X” should show up:

Each Square has its own state: the `value` stored in each Square is completely independent of the others. When you call a `set` function in a component, React automatically updates the child components inside too.

After you’ve made the above changes, your code will look like this:

```
import { useState } from 'react';

function Square() {
  const [value, setValue] = useState(null);

  function handleClick() {
    setValue('X');
  }

  return (
    <button
      className="square"
      onClick={handleClick}
    >
      {value}
    </button>
  );
}

export default function Board() {
  return (
    <>
      <div className="board-row">
        <Square />
        <Square />
        <Square />
      </div>
      <div className="board-row">
        <Square />
        <Square />
        <Square />
      </div>
      <div className="board-row">
        <Square />
        <Square />
        <Square />
      </div>
    </>
  );
}
```

```
// ...

export default function Board() {

  const [squares, setSquares] = useState(Array(9).fill(null));

  return (

    // ...

  );

}
```

`Array(9).fill(null)` creates an array with nine elements and sets each of them to `null`. The `useState()` call around it declares a `squares` state variable that’s initially set to that array. Each entry in the array corresponds to the value of a square. When you fill the board in later, the `squares` array will look like this:

```
['O', null, 'X', 'X', 'X', 'O', 'O', null, null]
```

Now your `Board` component needs to pass the `value` prop down to each `Square` that it renders:

```
export default function Board() {

  const [squares, setSquares] = useState(Array(9).fill(null));

  return (

    <>

      <div className="board-row">

        <Square value={squares[0]} />

        <Square value={squares[1]} />

        <Square value={squares[2]} />

      </div>

      <div className="board-row">

        <Square value={squares[3]} />

        <Square value={squares[4]} />

        <Square value={squares[5]} />

      </div>

      <div className="board-row">

        <Square value={squares[6]} />

        <Square value={squares[7]} />

        <Square value={squares[8]} />

      </div>

    </>

  );

}
```

Next, you’ll edit the `Square` component to receive the `value` prop from the Board component. This will require removing the Square component’s own stateful tracking of `value` and the button’s `onClick` prop:

```
function Square({value}) {

  return <button className="square">{value}</button>;

}
```

At this point you should see an empty tic-tac-toe board:

And your code should look like this:

```
import { useState } from 'react';

function Square({ value }) {
  return <button className="square">{value}</button>;
}

export default function Board() {
  const [squares, setSquares] = useState(Array(9).fill(null));
  return (
    <>
      <div className="board-row">
        <Square value={squares[0]} />
        <Square value={squares[1]} />
        <Square value={squares[2]} />
      </div>
      <div className="board-row">
        <Square value={squares[3]} />
        <Square value={squares[4]} />
        <Square value={squares[5]} />
      </div>
      <div className="board-row">
        <Square value={squares[6]} />
        <Square value={squares[7]} />
        <Square value={squares[8]} />
      </div>
    </>
  );
}
```

Each Square will now receive a `value` prop that will either be `'X'`, `'O'`, or `null` for empty squares.

Next, you need to change what happens when a `Square` is clicked. The `Board` component now maintains which squares are filled. You’ll need to create a way for the `Square` to update the `Board`’s state. Since state is private to a component that defines it, you cannot update the `Board`’s state directly from `Square`.

Instead, you’ll pass down a function from the `Board` component to the `Square` component, and you’ll have `Square` call that function when a square is clicked. You’ll start with the function that the `Square` component will call when it is clicked. You’ll call that function `onSquareClick`:

```
function Square({ value }) {

  return (

    <button className="square" onClick={onSquareClick}>

      {value}

    </button>

  );

}
```

Next, you’ll add the `onSquareClick` function to the `Square` component’s props:

```
function Square({ value, onSquareClick }) {

  return (

    <button className="square" onClick={onSquareClick}>

      {value}

    </button>

  );

}
```

Now you’ll connect the `onSquareClick` prop to a function in the `Board` component that you’ll name `handleClick`. To connect `onSquareClick` to `handleClick` you’ll pass a function to the `onSquareClick` prop of the first `Square` component:

```
export default function Board() {

  const [squares, setSquares] = useState(Array(9).fill(null));



  return (

    <>

      <div className="board-row">

        <Square value={squares[0]} onSquareClick={handleClick} />

        //...

  );

}
```

Lastly, you will define the `handleClick` function inside the Board component to update the `squares` array holding your board’s state:

```
export default function Board() {

  const [squares, setSquares] = useState(Array(9).fill(null));



  function handleClick() {

    const nextSquares = squares.slice();

    nextSquares[0] = "X";

    setSquares(nextSquares);

  }



  return (

    // ...

  )

}
```

The `handleClick` function creates a copy of the `squares` array (`nextSquares`) with the JavaScript `slice()` Array method. Then, `handleClick` updates the `nextSquares` array to add `X` to the first (`[0]` index) square.

Calling the `setSquares` function lets React know the state of the component has changed. This will trigger a re-render of the components that use the `squares` state (`Board`) as well as its child components (the `Square` components that make up the board).

### Note

JavaScript supports [closures](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures) which means an inner function (e.g. `handleClick`) has access to variables and functions defined in an outer function (e.g. `Board`). The `handleClick` function can read the `squares` state and call the `setSquares` method because they are both defined inside of the `Board` function.

Now you can add X’s to the board… but only to the upper left square. Your `handleClick` function is hardcoded to update the index for the upper left square (`0`). Let’s update `handleClick` to be able to update any square. Add an argument `i` to the `handleClick` function that takes the index of the square to update:

```
export default function Board() {

  const [squares, setSquares] = useState(Array(9).fill(null));



  function handleClick(i) {

    const nextSquares = squares.slice();

    nextSquares[i] = "X";

    setSquares(nextSquares);

  }



  return (

    // ...

  )

}
```

Next, you will need to pass that `i` to `handleClick`. You could try to set the `onSquareClick` prop of square to be `handleClick(0)` directly in the JSX like this, but it won’t work:

```
<Square value={squares[0]} onSquareClick={handleClick(0)} />
```

```
export default function Board() {

  // ...

  return (

    <>

      <div className="board-row">

        <Square value={squares[0]} onSquareClick={() => handleClick(0)} />

        // ...

  );

}
```

Notice the new `() =>` syntax. Here, `() => handleClick(0)` is an *arrow function,* which is a shorter way to define functions. When the square is clicked, the code after the `=>` “arrow” will run, calling `handleClick(0)`.

Now you need to update the other eight squares to call `handleClick` from the arrow functions you pass. Make sure that the argument for each call of the `handleClick` corresponds to the index of the correct square:

```
export default function Board() {

  // ...

  return (

    <>

      <div className="board-row">

        <Square value={squares[0]} onSquareClick={() => handleClick(0)} />

        <Square value={squares[1]} onSquareClick={() => handleClick(1)} />

        <Square value={squares[2]} onSquareClick={() => handleClick(2)} />

      </div>

      <div className="board-row">

        <Square value={squares[3]} onSquareClick={() => handleClick(3)} />

        <Square value={squares[4]} onSquareClick={() => handleClick(4)} />

        <Square value={squares[5]} onSquareClick={() => handleClick(5)} />

      </div>

      <div className="board-row">

        <Square value={squares[6]} onSquareClick={() => handleClick(6)} />

        <Square value={squares[7]} onSquareClick={() => handleClick(7)} />

        <Square value={squares[8]} onSquareClick={() => handleClick(8)} />

      </div>

    </>

  );

};
```

Now you can again add X’s to any square on the board by clicking on them:

But this time all the state management is handled by the `Board` component!

This is what your code should look like:

```
import { useState } from 'react';

function Square({ value, onSquareClick }) {
  return (
    <button className="square" onClick={onSquareClick}>
      {value}
    </button>
  );
}

export default function Board() {
  const [squares, setSquares] = useState(Array(9).fill(null));

  function handleClick(i) {
    const nextSquares = squares.slice();
    nextSquares[i] = 'X';
    setSquares(nextSquares);
  }

  return (
    <>
      <div className="board-row">
        <Square value={squares[0]} onSquareClick={() => handleClick(0)} />
        <Square value={squares[1]} onSquareClick={() => handleClick(1)} />
        <Square value={squares[2]} onSquareClick={() => handleClick(2)} />
      </div>
      <div className="board-row">
        <Square value={squares[3]} onSquareClick={() => handleClick(3)} />
        <Square value={squares[4]} onSquareClick={() => handleClick(4)} />
        <Square value={squares[5]} onSquareClick={() => handleClick(5)} />
      </div>
      <div className="board-row">
        <Square value={squares[6]} onSquareClick={() => handleClick(6)} />
        <Square value={squares[7]} onSquareClick={() => handleClick(7)} />
        <Square value={squares[8]} onSquareClick={() => handleClick(8)} />
      </div>
    </>
  );
}
```

Now that your state handling is in the `Board` component, the parent `Board` component passes props to the child `Square` components so that they can be displayed correctly. When clicking on a `Square`, the child `Square` component now asks the parent `Board` component to update the state of the board. When the `Board`’s state changes, both the `Board` component and every child `Square` re-renders automatically. Keeping the state of all squares in the `Board` component will allow it to determine the winner in the future.

Let’s recap what happens when a user clicks the top left square on your board to add an `X` to it:

1. Clicking on the upper left square runs the function that the `button` received as its `onClick` prop from the `Square`. The `Square` component received that function as its `onSquareClick` prop from the `Board`. The `Board` component defined that function directly in the JSX. It calls `handleClick` with an argument of `0`.
2. `handleClick` uses the argument (`0`) to update the first element of the `squares` array from `null` to `X`.
3. The `squares` state of the `Board` component was updated, so the `Board` and all of its children re-render. This causes the `value` prop of the `Square` component with index `0` to change from `null` to `X`.

In the end the user sees that the upper left square has changed from empty to having a `X` after clicking it.

### Note

The DOM `<button>` element’s `onClick` attribute has a special meaning to React because it is a built-in component. For custom components like Square, the naming is up to you. You could give any name to the `Square`’s `onSquareClick` prop or `Board`’s `handleClick` function, and the code would work the same. In React, it’s conventional to use `onSomething` names for props which represent events and `handleSomething` for the function definitions which handle those events.

### Why immutability is important[](#why-immutability-is-important "Link for Why immutability is important ")

Note how in `handleClick`, you call `.slice()` to create a copy of the `squares` array instead of modifying the existing array. To explain why, we need to discuss immutability and why immutability is important to learn.

There are generally two approaches to changing data. The first approach is to *mutate* the data by directly changing the data’s values. The second approach is to replace the data with a new copy which has the desired changes. Here is what it would look like if you mutated the `squares` array:

```
const squares = [null, null, null, null, null, null, null, null, null];

squares[0] = 'X';

// Now `squares` is ["X", null, null, null, null, null, null, null, null];
```

And here is what it would look like if you changed data without mutating the `squares` array:

```
const squares = [null, null, null, null, null, null, null, null, null];

const nextSquares = ['X', null, null, null, null, null, null, null, null];

// Now `squares` is unchanged, but `nextSquares` first element is 'X' rather than `null`
```

The result is the same but by not mutating (changing the underlying data) directly, you gain several benefits.

Immutability makes complex features much easier to implement. Later in this tutorial, you will implement a “time travel” feature that lets you review the game’s history and “jump back” to past moves. This functionality isn’t specific to games—an ability to undo and redo certain actions is a common requirement for apps. Avoiding direct data mutation lets you keep previous versions of the data intact, and reuse them later.

There is also another benefit of immutability. By default, all child components re-render automatically when the state of a parent component changes. This includes even the child components that weren’t affected by the change. Although re-rendering is not by itself noticeable to the user (you shouldn’t actively try to avoid it!), you might want to skip re-rendering a part of the tree that clearly wasn’t affected by it for performance reasons. Immutability makes it very cheap for components to compare whether their data has changed or not. You can learn more about how React chooses when to re-render a component in [the `memo` API reference](/reference/react/memo).

### Taking turns[](#taking-turns "Link for Taking turns ")

It’s now time to fix a major defect in this tic-tac-toe game: the “O”s cannot be marked on the board.

You’ll set the first move to be “X” by default. Let’s keep track of this by adding another piece of state to the Board component:

```
function Board() {

  const [xIsNext, setXIsNext] = useState(true);

  const [squares, setSquares] = useState(Array(9).fill(null));



  // ...

}
```

Each time a player moves, `xIsNext` (a boolean) will be flipped to determine which player goes next and the game’s state will be saved. You’ll update the `Board`’s `handleClick` function to flip the value of `xIsNext`:

```
export default function Board() {

  const [xIsNext, setXIsNext] = useState(true);

  const [squares, setSquares] = useState(Array(9).fill(null));



  function handleClick(i) {

    const nextSquares = squares.slice();

    if (xIsNext) {

      nextSquares[i] = "X";

    } else {

      nextSquares[i] = "O";

    }

    setSquares(nextSquares);

    setXIsNext(!xIsNext);

  }



  return (

    //...

  );

}
```

Now, as you click on different squares, they will alternate between `X` and `O`, as they should!

But wait, there’s a problem. Try clicking on the same square multiple times:

The `X` is overwritten by an `O`! While this would add a very interesting twist to the game, we’re going to stick to the original rules for now.

When you mark a square with a `X` or an `O` you aren’t first checking to see if the square already has a `X` or `O` value. You can fix this by *returning early*. You’ll check to see if the square already has a `X` or an `O`. If the square is already filled, you will `return` in the `handleClick` function early—before it tries to update the board state.

```
function handleClick(i) {

  if (squares[i]) {

    return;

  }

  const nextSquares = squares.slice();

  //...

}
```

Now you can only add `X`’s or `O`’s to empty squares! Here is what your code should look like at this point:

```
import { useState } from 'react';

function Square({value, onSquareClick}) {
  return (
    <button className="square" onClick={onSquareClick}>
      {value}
    </button>
  );
}

export default function Board() {
  const [xIsNext, setXIsNext] = useState(true);
  const [squares, setSquares] = useState(Array(9).fill(null));

  function handleClick(i) {
    if (squares[i]) {
      return;
    }
    const nextSquares = squares.slice();
    if (xIsNext) {
      nextSquares[i] = 'X';
    } else {
      nextSquares[i] = 'O';
    }
    setSquares(nextSquares);
    setXIsNext(!xIsNext);
  }

  return (
    <>
      <div className="board-row">
        <Square value={squares[0]} onSquareClick={() => handleClick(0)} />
        <Square value={squares[1]} onSquareClick={() => handleClick(1)} />
        <Square value={squares[2]} onSquareClick={() => handleClick(2)} />
      </div>
      <div className="board-row">
        <Square value={squares[3]} onSquareClick={() => handleClick(3)} />
        <Square value={squares[4]} onSquareClick={() => handleClick(4)} />
        <Square value={squares[5]} onSquareClick={() => handleClick(5)} />
      </div>
      <div className="board-row">
        <Square value={squares[6]} onSquareClick={() => handleClick(6)} />
        <Square value={squares[7]} onSquareClick={() => handleClick(7)} />
        <Square value={squares[8]} onSquareClick={() => handleClick(8)} />
      </div>
    </>
  );
}
```

### Declaring a winner[](#declaring-a-winner "Link for Declaring a winner ")

Now that the players can take turns, you’ll want to show when the game is won and there are no more turns to make. To do this you’ll add a helper function called `calculateWinner` that takes an array of 9 squares, checks for a winner and returns `'X'`, `'O'`, or `null` as appropriate. Don’t worry too much about the `calculateWinner` function; it’s not specific to React:

```
export default function Board() {

  //...

}



function calculateWinner(squares) {

  const lines = [

    [0, 1, 2],

    [3, 4, 5],

    [6, 7, 8],

    [0, 3, 6],

    [1, 4, 7],

    [2, 5, 8],

    [0, 4, 8],

    [2, 4, 6]

  ];

  for (let i = 0; i < lines.length; i++) {

    const [a, b, c] = lines[i];

    if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {

      return squares[a];

    }

  }

  return null;

}
```

### Note

It does not matter whether you define `calculateWinner` before or after the `Board`. Let’s put it at the end so that you don’t have to scroll past it every time you edit your components.

You will call `calculateWinner(squares)` in the `Board` component’s `handleClick` function to check if a player has won. You can perform this check at the same time you check if a user has clicked a square that already has a `X` or and `O`. We’d like to return early in both cases:

```
function handleClick(i) {

  if (squares[i] || calculateWinner(squares)) {

    return;

  }

  const nextSquares = squares.slice();

  //...

}
```

To let the players know when the game is over, you can display text such as “Winner: X” or “Winner: O”. To do that you’ll add a `status` section to the `Board` component. The status will display the winner if the game is over and if the game is ongoing you’ll display which player’s turn is next:

```
export default function Board() {

  // ...

  const winner = calculateWinner(squares);

  let status;

  if (winner) {

    status = "Winner: " + winner;

  } else {

    status = "Next player: " + (xIsNext ? "X" : "O");

  }



  return (

    <>

      <div className="status">{status}</div>

      <div className="board-row">

        // ...

  )

}
```

Congratulations! You now have a working tic-tac-toe game. And you’ve just learned the basics of React too. So *you* are the real winner here. Here is what the code should look like:

```
import { useState } from 'react';

function Square({value, onSquareClick}) {
  return (
    <button className="square" onClick={onSquareClick}>
      {value}
    </button>
  );
}

export default function Board() {
  const [xIsNext, setXIsNext] = useState(true);
  const [squares, setSquares] = useState(Array(9).fill(null));

  function handleClick(i) {
    if (calculateWinner(squares) || squares[i]) {
      return;
    }
    const nextSquares = squares.slice();
    if (xIsNext) {
      nextSquares[i] = 'X';
    } else {
      nextSquares[i] = 'O';
    }
    setSquares(nextSquares);
    setXIsNext(!xIsNext);
  }

  const winner = calculateWinner(squares);
  let status;
  if (winner) {
    status = 'Winner: ' + winner;
  } else {
    status = 'Next player: ' + (xIsNext ? 'X' : 'O');
  }

  return (
    <>
      <div className="status">{status}</div>
      <div className="board-row">
        <Square value={squares[0]} onSquareClick={() => handleClick(0)} />
        <Square value={squares[1]} onSquareClick={() => handleClick(1)} />
        <Square value={squares[2]} onSquareClick={() => handleClick(2)} />
      </div>
      <div className="board-row">
        <Square value={squares[3]} onSquareClick={() => handleClick(3)} />
        <Square value={squares[4]} onSquareClick={() => handleClick(4)} />
        <Square value={squares[5]} onSquareClick={() => handleClick(5)} />
      </div>
      <div className="board-row">
        <Square value={squares[6]} onSquareClick={() => handleClick(6)} />
        <Square value={squares[7]} onSquareClick={() => handleClick(7)} />
        <Square value={squares[8]} onSquareClick={() => handleClick(8)} />
      </div>
    </>
  );
}

function calculateWinner(squares) {
  const lines = [
    [0, 1, 2],
    [3, 4, 5],
    [6, 7, 8],
    [0, 3, 6],
    [1, 4, 7],
    [2, 5, 8],
    [0, 4, 8],
    [2, 4, 6],
  ];
  for (let i = 0; i < lines.length; i++) {
    const [a, b, c] = lines[i];
    if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
      return squares[a];
    }
  }
  return null;
}
```

## Adding time travel[](#adding-time-travel "Link for Adding time travel ")

As a final exercise, let’s make it possible to “go back in time” to the previous moves in the game.

### Storing a history of moves[](#storing-a-history-of-moves "Link for Storing a history of moves ")

If you mutated the `squares` array, implementing time travel would be very difficult.

However, you used `slice()` to create a new copy of the `squares` array after every move, and treated it as immutable. This will allow you to store every past version of the `squares` array, and navigate between the turns that have already happened.

You’ll store the past `squares` arrays in another array called `history`, which you’ll store as a new state variable. The `history` array represents all board states, from the first to the last move, and has a shape like this:

```
[

  // Before first move

  [null, null, null, null, null, null, null, null, null],

  // After first move

  [null, null, null, null, 'X', null, null, null, null],

  // After second move

  [null, null, null, null, 'X', null, null, null, 'O'],

  // ...

]
```

### Lifting state up, again[](#lifting-state-up-again "Link for Lifting state up, again ")

You will now write a new top-level component called `Game` to display a list of past moves. That’s where you will place the `history` state that contains the entire game history.

Placing the `history` state into the `Game` component will let you remove the `squares` state from its child `Board` component. Just like you “lifted state up” from the `Square` component into the `Board` component, you will now lift it up from the `Board` into the top-level `Game` component. This gives the `Game` component full control over the `Board`’s data and lets it instruct the `Board` to render previous turns from the `history`.

First, add a `Game` component with `export default`. Have it render the `Board` component and some markup:

```
function Board() {

  // ...

}



export default function Game() {

  return (

    <div className="game">

      <div className="game-board">

        <Board />

      </div>

      <div className="game-info">

        <ol>{/*TODO*/}</ol>

      </div>

    </div>

  );

}
```

Note that you are removing the `export default` keywords before the `function Board() {` declaration and adding them before the `function Game() {` declaration. This tells your `index.js` file to use the `Game` component as the top-level component instead of your `Board` component. The additional `div`s returned by the `Game` component are making room for the game information you’ll add to the board later.

Add some state to the `Game` component to track which player is next and the history of moves:

```
export default function Game() {

  const [xIsNext, setXIsNext] = useState(true);

  const [history, setHistory] = useState([Array(9).fill(null)]);

  // ...
```

Notice how `[Array(9).fill(null)]` is an array with a single item, which itself is an array of 9 `null`s.

To render the squares for the current move, you’ll want to read the last squares array from the `history`. You don’t need `useState` for this—you already have enough information to calculate it during rendering:

```
export default function Game() {

  const [xIsNext, setXIsNext] = useState(true);

  const [history, setHistory] = useState([Array(9).fill(null)]);

  const currentSquares = history[history.length - 1];

  // ...
```

Next, create a `handlePlay` function inside the `Game` component that will be called by the `Board` component to update the game. Pass `xIsNext`, `currentSquares` and `handlePlay` as props to the `Board` component:

```
export default function Game() {

  const [xIsNext, setXIsNext] = useState(true);

  const [history, setHistory] = useState([Array(9).fill(null)]);

  const currentSquares = history[history.length - 1];



  function handlePlay(nextSquares) {

    // TODO

  }



  return (

    <div className="game">

      <div className="game-board">

        <Board xIsNext={xIsNext} squares={currentSquares} onPlay={handlePlay} />

        //...

  )

}
```

Let’s make the `Board` component fully controlled by the props it receives. Change the `Board` component to take three props: `xIsNext`, `squares`, and a new `onPlay` function that `Board` can call with the updated squares array when a player makes a move. Next, remove the first two lines of the `Board` function that call `useState`:

```
function Board({ xIsNext, squares, onPlay }) {

  function handleClick(i) {

    //...

  }

  // ...

}
```

Now replace the `setSquares` and `setXIsNext` calls in `handleClick` in the `Board` component with a single call to your new `onPlay` function so the `Game` component can update the `Board` when the user clicks a square:

```
function Board({ xIsNext, squares, onPlay }) {

  function handleClick(i) {

    if (calculateWinner(squares) || squares[i]) {

      return;

    }

    const nextSquares = squares.slice();

    if (xIsNext) {

      nextSquares[i] = "X";

    } else {

      nextSquares[i] = "O";

    }

    onPlay(nextSquares);

  }

  //...

}
```

The `Board` component is fully controlled by the props passed to it by the `Game` component. You need to implement the `handlePlay` function in the `Game` component to get the game working again.

What should `handlePlay` do when called? Remember that Board used to call `setSquares` with an updated array; now it passes the updated `squares` array to `onPlay`.

The `handlePlay` function needs to update `Game`’s state to trigger a re-render, but you don’t have a `setSquares` function that you can call any more—you’re now using the `history` state variable to store this information. You’ll want to update `history` by appending the updated `squares` array as a new history entry. You also want to toggle `xIsNext`, just as Board used to do:

```
export default function Game() {

  //...

  function handlePlay(nextSquares) {

    setHistory([...history, nextSquares]);

    setXIsNext(!xIsNext);

  }

  //...

}
```

Here, `[...history, nextSquares]` creates a new array that contains all the items in `history`, followed by `nextSquares`. (You can read the `...history` [*spread syntax*](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax) as “enumerate all the items in `history`”.)

For example, if `history` is `[[null,null,null], ["X",null,null]]` and `nextSquares` is `["X",null,"O"]`, then the new `[...history, nextSquares]` array will be `[[null,null,null], ["X",null,null], ["X",null,"O"]]`.

At this point, you’ve moved the state to live in the `Game` component, and the UI should be fully working, just as it was before the refactor. Here is what the code should look like at this point:

```
import { useState } from 'react';

function Square({ value, onSquareClick }) {
  return (
    <button className="square" onClick={onSquareClick}>
      {value}
    </button>
  );
}

function Board({ xIsNext, squares, onPlay }) {
  function handleClick(i) {
    if (calculateWinner(squares) || squares[i]) {
      return;
    }
    const nextSquares = squares.slice();
    if (xIsNext) {
      nextSquares[i] = 'X';
    } else {
      nextSquares[i] = 'O';
    }
    onPlay(nextSquares);
  }

  const winner = calculateWinner(squares);
  let status;
  if (winner) {
    status = 'Winner: ' + winner;
  } else {
    status = 'Next player: ' + (xIsNext ? 'X' : 'O');
  }

  return (
    <>
      <div className="status">{status}</div>
      <div className="board-row">
        <Square value={squares[0]} onSquareClick={() => handleClick(0)} />
        <Square value={squares[1]} onSquareClick={() => handleClick(1)} />
        <Square value={squares[2]} onSquareClick={() => handleClick(2)} />
      </div>
      <div className="board-row">
        <Square value={squares[3]} onSquareClick={() => handleClick(3)} />
        <Square value={squares[4]} onSquareClick={() => handleClick(4)} />
        <Square value={squares[5]} onSquareClick={() => handleClick(5)} />
      </div>
      <div className="board-row">
        <Square value={squares[6]} onSquareClick={() => handleClick(6)} />
        <Square value={squares[7]} onSquareClick={() => handleClick(7)} />
        <Square value={squares[8]} onSquareClick={() => handleClick(8)} />
      </div>
    </>
  );
}

export default function Game() {
  const [xIsNext, setXIsNext] = useState(true);
  const [history, setHistory] = useState([Array(9).fill(null)]);
  const currentSquares = history[history.length - 1];

  function handlePlay(nextSquares) {
    setHistory([...history, nextSquares]);
    setXIsNext(!xIsNext);
  }

  return (
    <div className="game">
      <div className="game-board">
        <Board xIsNext={xIsNext} squares={currentSquares} onPlay={handlePlay} />
      </div>
      <div className="game-info">
        <ol>{/*TODO*/}</ol>
      </div>
    </div>
  );
}

function calculateWinner(squares) {
  const lines = [
    [0, 1, 2],
    [3, 4, 5],
    [6, 7, 8],
    [0, 3, 6],
    [1, 4, 7],
    [2, 5, 8],
    [0, 4, 8],
    [2, 4, 6],
  ];
  for (let i = 0; i < lines.length; i++) {
    const [a, b, c] = lines[i];
    if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
      return squares[a];
    }
  }
  return null;
}
```

### Showing the past moves[](#showing-the-past-moves "Link for Showing the past moves ")

Since you are recording the tic-tac-toe game’s history, you can now display a list of past moves to the player.

React elements like `<button>` are regular JavaScript objects; you can pass them around in your application. To render multiple items in React, you can use an array of React elements.

You already have an array of `history` moves in state, so now you need to transform it to an array of React elements. In JavaScript, to transform one array into another, you can use the [array `map` method:](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map)

```
[1, 2, 3].map((x) => x * 2) // [2, 4, 6]
```

You’ll use `map` to transform your `history` of moves into React elements representing buttons on the screen, and display a list of buttons to “jump” to past moves. Let’s `map` over the `history` in the Game component:

```
export default function Game() {

  const [xIsNext, setXIsNext] = useState(true);

  const [history, setHistory] = useState([Array(9).fill(null)]);

  const currentSquares = history[history.length - 1];



  function handlePlay(nextSquares) {

    setHistory([...history, nextSquares]);

    setXIsNext(!xIsNext);

  }



  function jumpTo(nextMove) {

    // TODO

  }



  const moves = history.map((squares, move) => {

    let description;

    if (move > 0) {

      description = 'Go to move #' + move;

    } else {

      description = 'Go to game start';

    }

    return (

      <li>

        <button onClick={() => jumpTo(move)}>{description}</button>

      </li>

    );

  });



  return (

    <div className="game">

      <div className="game-board">

        <Board xIsNext={xIsNext} squares={currentSquares} onPlay={handlePlay} />

      </div>

      <div className="game-info">

        <ol>{moves}</ol>

      </div>

    </div>

  );

}
```

You can see what your code should look like below. Note that you should see an error in the developer tools console that says:

Console

Warning: Each child in an array or iterator should have a unique “key” prop. Check the render method of \`Game\`.

You’ll fix this error in the next section.

```
import { useState } from 'react';

function Square({ value, onSquareClick }) {
  return (
    <button className="square" onClick={onSquareClick}>
      {value}
    </button>
  );
}

function Board({ xIsNext, squares, onPlay }) {
  function handleClick(i) {
    if (calculateWinner(squares) || squares[i]) {
      return;
    }
    const nextSquares = squares.slice();
    if (xIsNext) {
      nextSquares[i] = 'X';
    } else {
      nextSquares[i] = 'O';
    }
    onPlay(nextSquares);
  }

  const winner = calculateWinner(squares);
  let status;
  if (winner) {
    status = 'Winner: ' + winner;
  } else {
    status = 'Next player: ' + (xIsNext ? 'X' : 'O');
  }

  return (
    <>
      <div className="status">{status}</div>
      <div className="board-row">
        <Square value={squares[0]} onSquareClick={() => handleClick(0)} />
        <Square value={squares[1]} onSquareClick={() => handleClick(1)} />
        <Square value={squares[2]} onSquareClick={() => handleClick(2)} />
      </div>
      <div className="board-row">
        <Square value={squares[3]} onSquareClick={() => handleClick(3)} />
        <Square value={squares[4]} onSquareClick={() => handleClick(4)} />
        <Square value={squares[5]} onSquareClick={() => handleClick(5)} />
      </div>
      <div className="board-row">
        <Square value={squares[6]} onSquareClick={() => handleClick(6)} />
        <Square value={squares[7]} onSquareClick={() => handleClick(7)} />
        <Square value={squares[8]} onSquareClick={() => handleClick(8)} />
      </div>
    </>
  );
}

export default function Game() {
  const [xIsNext, setXIsNext] = useState(true);
  const [history, setHistory] = useState([Array(9).fill(null)]);
  const currentSquares = history[history.length - 1];

  function handlePlay(nextSquares) {
    setHistory([...history, nextSquares]);
    setXIsNext(!xIsNext);
  }

  function jumpTo(nextMove) {
    // TODO
  }

  const moves = history.map((squares, move) => {
    let description;
    if (move > 0) {
      description = 'Go to move #' + move;
    } else {
      description = 'Go to game start';
    }
    return (
      <li>
        <button onClick={() => jumpTo(move)}>{description}</button>
      </li>
    );
  });

  return (
    <div className="game">
      <div className="game-board">
        <Board xIsNext={xIsNext} squares={currentSquares} onPlay={handlePlay} />
      </div>
      <div className="game-info">
        <ol>{moves}</ol>
      </div>
    </div>
  );
}

function calculateWinner(squares) {
  const lines = [
    [0, 1, 2],
    [3, 4, 5],
    [6, 7, 8],
    [0, 3, 6],
    [1, 4, 7],
    [2, 5, 8],
    [0, 4, 8],
    [2, 4, 6],
  ];
  for (let i = 0; i < lines.length; i++) {
    const [a, b, c] = lines[i];
    if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
      return squares[a];
    }
  }
  return null;
}
```

As you iterate through `history` array inside the function you passed to `map`, the `squares` argument goes through each element of `history`, and the `move` argument goes through each array index: `0`, `1`, `2`, …. (In most cases, you’d need the actual array elements, but to render a list of moves you will only need indexes.)

For each move in the tic-tac-toe game’s history, you create a list item `<li>` which contains a button `<button>`. The button has an `onClick` handler which calls a function called `jumpTo` (that you haven’t implemented yet).

For now, you should see a list of the moves that occurred in the game and an error in the developer tools console. Let’s discuss what the “key” error means.

### Picking a key[](#picking-a-key "Link for Picking a key ")

When you render a list, React stores some information about each rendered list item. When you update a list, React needs to determine what has changed. You could have added, removed, re-arranged, or updated the list’s items.

Imagine transitioning from

```
<li>Alexa: 7 tasks left</li>

<li>Ben: 5 tasks left</li>
```

to

```
<li>Ben: 9 tasks left</li>

<li>Claudia: 8 tasks left</li>

<li>Alexa: 5 tasks left</li>
```

In addition to the updated counts, a human reading this would probably say that you swapped Alexa and Ben’s ordering and inserted Claudia between Alexa and Ben. However, React is a computer program and does not know what you intended, so you need to specify a *key* property for each list item to differentiate each list item from its siblings. If your data was from a database, Alexa, Ben, and Claudia’s database IDs could be used as keys.

```
<li key={user.id}>

  {user.name}: {user.taskCount} tasks left

</li>
```

```
const moves = history.map((squares, move) => {

  //...

  return (

    <li key={move}>

      <button onClick={() => jumpTo(move)}>{description}</button>

    </li>

  );

});
```

```
import { useState } from 'react';

function Square({ value, onSquareClick }) {
  return (
    <button className="square" onClick={onSquareClick}>
      {value}
    </button>
  );
}

function Board({ xIsNext, squares, onPlay }) {
  function handleClick(i) {
    if (calculateWinner(squares) || squares[i]) {
      return;
    }
    const nextSquares = squares.slice();
    if (xIsNext) {
      nextSquares[i] = 'X';
    } else {
      nextSquares[i] = 'O';
    }
    onPlay(nextSquares);
  }

  const winner = calculateWinner(squares);
  let status;
  if (winner) {
    status = 'Winner: ' + winner;
  } else {
    status = 'Next player: ' + (xIsNext ? 'X' : 'O');
  }

  return (
    <>
      <div className="status">{status}</div>
      <div className="board-row">
        <Square value={squares[0]} onSquareClick={() => handleClick(0)} />
        <Square value={squares[1]} onSquareClick={() => handleClick(1)} />
        <Square value={squares[2]} onSquareClick={() => handleClick(2)} />
      </div>
      <div className="board-row">
        <Square value={squares[3]} onSquareClick={() => handleClick(3)} />
        <Square value={squares[4]} onSquareClick={() => handleClick(4)} />
        <Square value={squares[5]} onSquareClick={() => handleClick(5)} />
      </div>
      <div className="board-row">
        <Square value={squares[6]} onSquareClick={() => handleClick(6)} />
        <Square value={squares[7]} onSquareClick={() => handleClick(7)} />
        <Square value={squares[8]} onSquareClick={() => handleClick(8)} />
      </div>
    </>
  );
}

export default function Game() {
  const [xIsNext, setXIsNext] = useState(true);
  const [history, setHistory] = useState([Array(9).fill(null)]);
  const currentSquares = history[history.length - 1];

  function handlePlay(nextSquares) {
    setHistory([...history, nextSquares]);
    setXIsNext(!xIsNext);
  }

  function jumpTo(nextMove) {
    // TODO
  }

  const moves = history.map((squares, move) => {
    let description;
    if (move > 0) {
      description = 'Go to move #' + move;
    } else {
      description = 'Go to game start';
    }
    return (
      <li key={move}>
        <button onClick={() => jumpTo(move)}>{description}</button>
      </li>
    );
  });

  return (
    <div className="game">
      <div className="game-board">
        <Board xIsNext={xIsNext} squares={currentSquares} onPlay={handlePlay} />
      </div>
      <div className="game-info">
        <ol>{moves}</ol>
      </div>
    </div>
  );
}

function calculateWinner(squares) {
  const lines = [
    [0, 1, 2],
    [3, 4, 5],
    [6, 7, 8],
    [0, 3, 6],
    [1, 4, 7],
    [2, 5, 8],
    [0, 4, 8],
    [2, 4, 6],
  ];
  for (let i = 0; i < lines.length; i++) {
    const [a, b, c] = lines[i];
    if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
      return squares[a];
    }
  }
  return null;
}
```

Before you can implement `jumpTo`, you need the `Game` component to keep track of which step the user is currently viewing. To do this, define a new state variable called `currentMove`, defaulting to `0`:

```
export default function Game() {

  const [xIsNext, setXIsNext] = useState(true);

  const [history, setHistory] = useState([Array(9).fill(null)]);

  const [currentMove, setCurrentMove] = useState(0);

  const currentSquares = history[history.length - 1];

  //...

}
```

Next, update the `jumpTo` function inside `Game` to update that `currentMove`. You’ll also set `xIsNext` to `true` if the number that you’re changing `currentMove` to is even.

```
export default function Game() {

  // ...

  function jumpTo(nextMove) {

    setCurrentMove(nextMove);

    setXIsNext(nextMove % 2 === 0);

  }

  //...

}
```

You will now make two changes to the `Game`’s `handlePlay` function which is called when you click on a square.

* If you “go back in time” and then make a new move from that point, you only want to keep the history up to that point. Instead of adding `nextSquares` after all items (`...` spread syntax) in `history`, you’ll add it after all items in `history.slice(0, currentMove + 1)` so that you’re only keeping that portion of the old history.
* Each time a move is made, you need to update `currentMove` to point to the latest history entry.

```
function handlePlay(nextSquares) {

  const nextHistory = [...history.slice(0, currentMove + 1), nextSquares];

  setHistory(nextHistory);

  setCurrentMove(nextHistory.length - 1);

  setXIsNext(!xIsNext);

}
```

Finally, you will modify the `Game` component to render the currently selected move, instead of always rendering the final move:

```
export default function Game() {

  const [xIsNext, setXIsNext] = useState(true);

  const [history, setHistory] = useState([Array(9).fill(null)]);

  const [currentMove, setCurrentMove] = useState(0);

  const currentSquares = history[currentMove];



  // ...

}
```

If you click on any step in the game’s history, the tic-tac-toe board should immediately update to show what the board looked like after that step occurred.

```
import { useState } from 'react';

function Square({value, onSquareClick}) {
  return (
    <button className="square" onClick={onSquareClick}>
      {value}
    </button>
  );
}

function Board({ xIsNext, squares, onPlay }) {
  function handleClick(i) {
    if (calculateWinner(squares) || squares[i]) {
      return;
    }
    const nextSquares = squares.slice();
    if (xIsNext) {
      nextSquares[i] = 'X';
    } else {
      nextSquares[i] = 'O';
    }
    onPlay(nextSquares);
  }

  const winner = calculateWinner(squares);
  let status;
  if (winner) {
    status = 'Winner: ' + winner;
  } else {
    status = 'Next player: ' + (xIsNext ? 'X' : 'O');
  }

  return (
    <>
      <div className="status">{status}</div>
      <div className="board-row">
        <Square value={squares[0]} onSquareClick={() => handleClick(0)} />
        <Square value={squares[1]} onSquareClick={() => handleClick(1)} />
        <Square value={squares[2]} onSquareClick={() => handleClick(2)} />
      </div>
      <div className="board-row">
        <Square value={squares[3]} onSquareClick={() => handleClick(3)} />
        <Square value={squares[4]} onSquareClick={() => handleClick(4)} />
        <Square value={squares[5]} onSquareClick={() => handleClick(5)} />
      </div>
      <div className="board-row">
        <Square value={squares[6]} onSquareClick={() => handleClick(6)} />
        <Square value={squares[7]} onSquareClick={() => handleClick(7)} />
        <Square value={squares[8]} onSquareClick={() => handleClick(8)} />
      </div>
    </>
  );
}

export default function Game() {
  const [xIsNext, setXIsNext] = useState(true);
  const [history, setHistory] = useState([Array(9).fill(null)]);
  const [currentMove, setCurrentMove] = useState(0);
  const currentSquares = history[currentMove];

  function handlePlay(nextSquares) {
    const nextHistory = [...history.slice(0, currentMove + 1), nextSquares];
    setHistory(nextHistory);
    setCurrentMove(nextHistory.length - 1);
    setXIsNext(!xIsNext);
  }

  function jumpTo(nextMove) {
    setCurrentMove(nextMove);
    setXIsNext(nextMove % 2 === 0);
  }

  const moves = history.map((squares, move) => {
    let description;
    if (move > 0) {
      description = 'Go to move #' + move;
    } else {
      description = 'Go to game start';
    }
    return (
      <li key={move}>
        <button onClick={() => jumpTo(move)}>{description}</button>
      </li>
    );
  });

  return (
    <div className="game">
      <div className="game-board">
        <Board xIsNext={xIsNext} squares={currentSquares} onPlay={handlePlay} />
      </div>
      <div className="game-info">
        <ol>{moves}</ol>
      </div>
    </div>
  );
}

function calculateWinner(squares) {
  const lines = [
    [0, 1, 2],
    [3, 4, 5],
    [6, 7, 8],
    [0, 3, 6],
    [1, 4, 7],
    [2, 5, 8],
    [0, 4, 8],
    [2, 4, 6],
  ];
  for (let i = 0; i < lines.length; i++) {
    const [a, b, c] = lines[i];
    if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
      return squares[a];
    }
  }
  return null;
}
```

### Final cleanup[](#final-cleanup "Link for Final cleanup ")

If you look at the code very closely, you may notice that `xIsNext === true` when `currentMove` is even and `xIsNext === false` when `currentMove` is odd. In other words, if you know the value of `currentMove`, then you can always figure out what `xIsNext` should be.

There’s no reason for you to store both of these in state. In fact, always try to avoid redundant state. Simplifying what you store in state reduces bugs and makes your code easier to understand. Change `Game` so that it doesn’t store `xIsNext` as a separate state variable and instead figures it out based on the `currentMove`:

```
export default function Game() {

  const [history, setHistory] = useState([Array(9).fill(null)]);

  const [currentMove, setCurrentMove] = useState(0);

  const xIsNext = currentMove % 2 === 0;

  const currentSquares = history[currentMove];



  function handlePlay(nextSquares) {

    const nextHistory = [...history.slice(0, currentMove + 1), nextSquares];

    setHistory(nextHistory);

    setCurrentMove(nextHistory.length - 1);

  }



  function jumpTo(nextMove) {

    setCurrentMove(nextMove);

  }

  // ...

}
```

```
import { useState } from 'react';

function Square({ value, onSquareClick }) {
  return (
    <button className="square" onClick={onSquareClick}>
      {value}
    </button>
  );
}

function Board({ xIsNext, squares, onPlay }) {
  function handleClick(i) {
    if (calculateWinner(squares) || squares[i]) {
      return;
    }
    const nextSquares = squares.slice();
    if (xIsNext) {
      nextSquares[i] = 'X';
    } else {
      nextSquares[i] = 'O';
    }
    onPlay(nextSquares);
  }

  const winner = calculateWinner(squares);
  let status;
  if (winner) {
    status = 'Winner: ' + winner;
  } else {
    status = 'Next player: ' + (xIsNext ? 'X' : 'O');
  }

  return (
    <>
      <div className="status">{status}</div>
      <div className="board-row">
        <Square value={squares[0]} onSquareClick={() => handleClick(0)} />
        <Square value={squares[1]} onSquareClick={() => handleClick(1)} />
        <Square value={squares[2]} onSquareClick={() => handleClick(2)} />
      </div>
      <div className="board-row">
        <Square value={squares[3]} onSquareClick={() => handleClick(3)} />
        <Square value={squares[4]} onSquareClick={() => handleClick(4)} />
        <Square value={squares[5]} onSquareClick={() => handleClick(5)} />
      </div>
      <div className="board-row">
        <Square value={squares[6]} onSquareClick={() => handleClick(6)} />
        <Square value={squares[7]} onSquareClick={() => handleClick(7)} />
        <Square value={squares[8]} onSquareClick={() => handleClick(8)} />
      </div>
    </>
  );
}

export default function Game() {
  const [history, setHistory] = useState([Array(9).fill(null)]);
  const [currentMove, setCurrentMove] = useState(0);
  const xIsNext = currentMove % 2 === 0;
  const currentSquares = history[currentMove];

  function handlePlay(nextSquares) {
    const nextHistory = [...history.slice(0, currentMove + 1), nextSquares];
    setHistory(nextHistory);
    setCurrentMove(nextHistory.length - 1);
  }

  function jumpTo(nextMove) {
    setCurrentMove(nextMove);
  }

  const moves = history.map((squares, move) => {
    let description;
    if (move > 0) {
      description = 'Go to move #' + move;
    } else {
      description = 'Go to game start';
    }
    return (
      <li key={move}>
        <button onClick={() => jumpTo(move)}>{description}</button>
      </li>
    );
  });

  return (
    <div className="game">
      <div className="game-board">
        <Board xIsNext={xIsNext} squares={currentSquares} onPlay={handlePlay} />
      </div>
      <div className="game-info">
        <ol>{moves}</ol>
      </div>
    </div>
  );
}

function calculateWinner(squares) {
  const lines = [
    [0, 1, 2],
    [3, 4, 5],
    [6, 7, 8],
    [0, 3, 6],
    [1, 4, 7],
    [2, 5, 8],
    [0, 4, 8],
    [2, 4, 6],
  ];
  for (let i = 0; i < lines.length; i++) {
    const [a, b, c] = lines[i];
    if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
      return squares[a];
    }
  }
  return null;
}
```

***

----
url: https://18.react.dev/learn/lifecycle-of-reactive-effects
----

```
const serverUrl = 'https://localhost:1234';



function ChatRoom({ roomId }) {

  useEffect(() => {

    const connection = createConnection(serverUrl, roomId);

    connection.connect();

    return () => {

      connection.disconnect();

    };

  }, [roomId]);

  // ...

}
```

Your Effect’s body specifies how to **start synchronizing:**

```
    // ...

    const connection = createConnection(serverUrl, roomId);

    connection.connect();

    return () => {

      connection.disconnect();

    };

    // ...
```

The cleanup function returned by your Effect specifies how to **stop synchronizing:**

```
    // ...

    const connection = createConnection(serverUrl, roomId);

    connection.connect();

    return () => {

      connection.disconnect();

    };

    // ...
```

Intuitively, you might think that React would **start synchronizing** when your component mounts and **stop synchronizing** when your component unmounts. However, this is not the end of the story! Sometimes, it may also be necessary to **start and stop synchronizing multiple times** while the component remains mounted.

Let’s look at *why* this is necessary, *when* it happens, and *how* you can control this behavior.

### Note

Some Effects don’t return a cleanup function at all. [More often than not,](/learn/synchronizing-with-effects#how-to-handle-the-effect-firing-twice-in-development) you’ll want to return one—but if you don’t, React will behave as if you returned an empty cleanup function.

### Why synchronization may need to happen more than once[](#why-synchronization-may-need-to-happen-more-than-once "Link for Why synchronization may need to happen more than once ")

Imagine this `ChatRoom` component receives a `roomId` prop that the user picks in a dropdown. Let’s say that initially the user picks the `"general"` room as the `roomId`. Your app displays the `"general"` chat room:

```
const serverUrl = 'https://localhost:1234';



function ChatRoom({ roomId /* "general" */ }) {

  // ...

  return <h1>Welcome to the {roomId} room!</h1>;

}
```

After the UI is displayed, React will run your Effect to **start synchronizing.** It connects to the `"general"` room:

```
function ChatRoom({ roomId /* "general" */ }) {

  useEffect(() => {

    const connection = createConnection(serverUrl, roomId); // Connects to the "general" room

    connection.connect();

    return () => {

      connection.disconnect(); // Disconnects from the "general" room

    };

  }, [roomId]);

  // ...
```

So far, so good.

Later, the user picks a different room in the dropdown (for example, `"travel"`). First, React will update the UI:

```
function ChatRoom({ roomId /* "travel" */ }) {

  // ...

  return <h1>Welcome to the {roomId} room!</h1>;

}
```

```
function ChatRoom({ roomId /* "general" */ }) {

  useEffect(() => {

    const connection = createConnection(serverUrl, roomId); // Connects to the "general" room

    connection.connect();

    return () => {

      connection.disconnect(); // Disconnects from the "general" room

    };

    // ...
```

Then React will run the Effect that you’ve provided during this render. This time, `roomId` is `"travel"` so it will **start synchronizing** to the `"travel"` chat room (until its cleanup function is eventually called too):

```
function ChatRoom({ roomId /* "travel" */ }) {

  useEffect(() => {

    const connection = createConnection(serverUrl, roomId); // Connects to the "travel" room

    connection.connect();

    // ...
```

```
  useEffect(() => {

    // Your Effect connected to the room specified with roomId...

    const connection = createConnection(serverUrl, roomId);

    connection.connect();

    return () => {

      // ...until it disconnected

      connection.disconnect();

    };

  }, [roomId]);
```

```
import { useState, useEffect } from 'react';
import { createConnection } from './chat.js';

const serverUrl = 'https://localhost:1234';

function ChatRoom({ roomId }) {
  useEffect(() => {
    const connection = createConnection(serverUrl, roomId);
    connection.connect();
    return () => connection.disconnect();
  }, [roomId]);
  return <h1>Welcome to the {roomId} room!</h1>;
}

export default function App() {
  const [roomId, setRoomId] = useState('general');
  const [show, setShow] = useState(false);
  return (
    <>
      <label>
        Choose the chat room:{' '}
        <select
          value={roomId}
          onChange={e => setRoomId(e.target.value)}
        >
          <option value="general">general</option>
          <option value="travel">travel</option>
          <option value="music">music</option>
        </select>
      </label>
      <button onClick={() => setShow(!show)}>
        {show ? 'Close chat' : 'Open chat'}
      </button>
      {show && <hr />}
      {show && <ChatRoom roomId={roomId} />}
    </>
  );
}
```

```
function ChatRoom({ roomId }) { // The roomId prop may change over time

  useEffect(() => {

    const connection = createConnection(serverUrl, roomId); // This Effect reads roomId 

    connection.connect();

    return () => {

      connection.disconnect();

    };

  }, [roomId]); // So you tell React that this Effect "depends on" roomId

  // ...
```

```
function ChatRoom({ roomId }) {

  useEffect(() => {

    logVisit(roomId);

    const connection = createConnection(serverUrl, roomId);

    connection.connect();

    return () => {

      connection.disconnect();

    };

  }, [roomId]);

  // ...

}
```

But imagine you later add another dependency to this Effect that needs to re-establish the connection. If this Effect re-synchronizes, it will also call `logVisit(roomId)` for the same room, which you did not intend. Logging the visit **is a separate process** from connecting. Write them as two separate Effects:

```
function ChatRoom({ roomId }) {

  useEffect(() => {

    logVisit(roomId);

  }, [roomId]);



  useEffect(() => {

    const connection = createConnection(serverUrl, roomId);

    // ...

  }, [roomId]);

  // ...

}
```

**Each Effect in your code should represent a separate and independent synchronization process.**

In the above example, deleting one Effect wouldn’t break the other Effect’s logic. This is a good indication that they synchronize different things, and so it made sense to split them up. On the other hand, if you split up a cohesive piece of logic into separate Effects, the code may look “cleaner” but will be [more difficult to maintain.](/learn/you-might-not-need-an-effect#chains-of-computations) This is why you should think whether the processes are same or separate, not whether the code looks cleaner.

## Effects “react” to reactive values[](#effects-react-to-reactive-values "Link for Effects “react” to reactive values ")

Your Effect reads two variables (`serverUrl` and `roomId`), but you only specified `roomId` as a dependency:

```
const serverUrl = 'https://localhost:1234';



function ChatRoom({ roomId }) {

  useEffect(() => {

    const connection = createConnection(serverUrl, roomId);

    connection.connect();

    return () => {

      connection.disconnect();

    };

  }, [roomId]);

  // ...

}
```

Why doesn’t `serverUrl` need to be a dependency?

This is because the `serverUrl` never changes due to a re-render. It’s always the same no matter how many times the component re-renders and why. Since `serverUrl` never changes, it wouldn’t make sense to specify it as a dependency. After all, dependencies only do something when they change over time!

On the other hand, `roomId` may be different on a re-render. **Props, state, and other values declared inside the component are *reactive* because they’re calculated during rendering and participate in the React data flow.**

If `serverUrl` was a state variable, it would be reactive. Reactive values must be included in dependencies:

```
function ChatRoom({ roomId }) { // Props change over time

  const [serverUrl, setServerUrl] = useState('https://localhost:1234'); // State may change over time



  useEffect(() => {

    const connection = createConnection(serverUrl, roomId); // Your Effect reads props and state

    connection.connect();

    return () => {

      connection.disconnect();

    };

  }, [roomId, serverUrl]); // So you tell React that this Effect "depends on" on props and state

  // ...

}
```

By including `serverUrl` as a dependency, you ensure that the Effect re-synchronizes after it changes.

Try changing the selected chat room or edit the server URL in this sandbox:

```
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();
  }, [roomId, serverUrl]);

  return (
    <>
      <label>
        Server URL:{' '}
        <input
          value={serverUrl}
          onChange={e => setServerUrl(e.target.value)}
        />
      </label>
      <h1>Welcome to the {roomId} room!</h1>
    </>
  );
}

export default function App() {
  const [roomId, setRoomId] = useState('general');
  return (
    <>
      <label>
        Choose the chat room:{' '}
        <select
          value={roomId}
          onChange={e => setRoomId(e.target.value)}
        >
          <option value="general">general</option>
          <option value="travel">travel</option>
          <option value="music">music</option>
        </select>
      </label>
      <hr />
      <ChatRoom roomId={roomId} />
    </>
  );
}
```

Whenever you change a reactive value like `roomId` or `serverUrl`, the Effect re-connects to the chat server.

### What an Effect with empty dependencies means[](#what-an-effect-with-empty-dependencies-means "Link for What an Effect with empty dependencies means ")

What happens if you move both `serverUrl` and `roomId` outside the component?

```
const serverUrl = 'https://localhost:1234';

const roomId = 'general';



function ChatRoom() {

  useEffect(() => {

    const connection = createConnection(serverUrl, roomId);

    connection.connect();

    return () => {

      connection.disconnect();

    };

  }, []); // ✅ All dependencies declared

  // ...

}
```

Now your Effect’s code does not use *any* reactive values, so its dependencies can be empty (`[]`).

Thinking from the component’s perspective, the empty `[]` dependency array means this Effect connects to the chat room only when the component mounts, and disconnects only when the component unmounts. (Keep in mind that React would still [re-synchronize it an extra time](#how-react-verifies-that-your-effect-can-re-synchronize) in development to stress-test your logic.)

```
import { useState, useEffect } from 'react';
import { createConnection } from './chat.js';

const serverUrl = 'https://localhost:1234';
const roomId = 'general';

function ChatRoom() {
  useEffect(() => {
    const connection = createConnection(serverUrl, roomId);
    connection.connect();
    return () => connection.disconnect();
  }, []);
  return <h1>Welcome to the {roomId} room!</h1>;
}

export default function App() {
  const [show, setShow] = useState(false);
  return (
    <>
      <button onClick={() => setShow(!show)}>
        {show ? 'Close chat' : 'Open chat'}
      </button>
      {show && <hr />}
      {show && <ChatRoom />}
    </>
  );
}
```

However, if you [think from the Effect’s perspective,](#thinking-from-the-effects-perspective) you don’t need to think about mounting and unmounting at all. What’s important is you’ve specified what your Effect does to start and stop synchronizing. Today, it has no reactive dependencies. But if you ever want the user to change `roomId` or `serverUrl` over time (and they would become reactive), your Effect’s code won’t change. You will only need to add them to the dependencies.

### All variables declared in the component body are reactive[](#all-variables-declared-in-the-component-body-are-reactive "Link for All variables declared in the component body are reactive ")

Props and state aren’t the only reactive values. Values that you calculate from them are also reactive. If the props or state change, your component will re-render, and the values calculated from them will also change. This is why all variables from the component body used by the Effect should be in the Effect dependency list.

Let’s say that the user can pick a chat server in the dropdown, but they can also configure a default server in settings. Suppose you’ve already put the settings state in a [context](/learn/scaling-up-with-reducer-and-context) so you read the `settings` from that context. Now you calculate the `serverUrl` based on the selected server from props and the default server:

```
function ChatRoom({ roomId, selectedServerUrl }) { // roomId is reactive

  const settings = useContext(SettingsContext); // settings is reactive

  const serverUrl = selectedServerUrl ?? settings.defaultServerUrl; // serverUrl is reactive

  useEffect(() => {

    const connection = createConnection(serverUrl, roomId); // Your Effect reads roomId and serverUrl

    connection.connect();

    return () => {

      connection.disconnect();

    };

  }, [roomId, serverUrl]); // So it needs to re-synchronize when either of them changes!

  // ...

}
```

```
import { useState, useEffect } from 'react';
import { createConnection } from './chat.js';

function ChatRoom({ roomId }) { // roomId is reactive
  const [serverUrl, setServerUrl] = useState('https://localhost:1234'); // serverUrl is reactive

  useEffect(() => {
    const connection = createConnection(serverUrl, roomId);
    connection.connect();
    return () => connection.disconnect();
  }, []); // <-- Something's wrong here!

  return (
    <>
      <label>
        Server URL:{' '}
        <input
          value={serverUrl}
          onChange={e => setServerUrl(e.target.value)}
        />
      </label>
      <h1>Welcome to the {roomId} room!</h1>
    </>
  );
}

export default function App() {
  const [roomId, setRoomId] = useState('general');
  return (
    <>
      <label>
        Choose the chat room:{' '}
        <select
          value={roomId}
          onChange={e => setRoomId(e.target.value)}
        >
          <option value="general">general</option>
          <option value="travel">travel</option>
          <option value="music">music</option>
        </select>
      </label>
      <hr />
      <ChatRoom roomId={roomId} />
    </>
  );
}
```

This may look like a React error, but really React is pointing out a bug in your code. Both `roomId` and `serverUrl` may change over time, but you’re forgetting to re-synchronize your Effect when they change. You will remain connected to the initial `roomId` and `serverUrl` even after the user picks different values in the UI.

To fix the bug, follow the linter’s suggestion to specify `roomId` and `serverUrl` as dependencies of your Effect:

```
function ChatRoom({ roomId }) { // roomId is reactive

  const [serverUrl, setServerUrl] = useState('https://localhost:1234'); // serverUrl is reactive

  useEffect(() => {

    const connection = createConnection(serverUrl, roomId);

    connection.connect();

    return () => {

      connection.disconnect();

    };

  }, [serverUrl, roomId]); // ✅ All dependencies declared

  // ...

}
```

Try this fix in the sandbox above. Verify that the linter error is gone, and the chat re-connects when needed.

### Note

In some cases, React *knows* that a value never changes even though it’s declared inside the component. For example, the [`set` function](/reference/react/useState#setstate) returned from `useState` and the ref object returned by [`useRef`](/reference/react/useRef) are *stable*—they are guaranteed to not change on a re-render. Stable values aren’t reactive, so you may omit them from the list. Including them is allowed: they won’t change, so it doesn’t matter.

### What to do when you don’t want to re-synchronize[](#what-to-do-when-you-dont-want-to-re-synchronize "Link for What to do when you don’t want to re-synchronize ")

In the previous example, you’ve fixed the lint error by listing `roomId` and `serverUrl` as dependencies.

**However, you could instead “prove” to the linter that these values aren’t reactive values,** i.e. that they *can’t* change as a result of a re-render. For example, if `serverUrl` and `roomId` don’t depend on rendering and always have the same values, you can move them outside the component. Now they don’t need to be dependencies:

```
const serverUrl = 'https://localhost:1234'; // serverUrl is not reactive

const roomId = 'general'; // roomId is not reactive



function ChatRoom() {

  useEffect(() => {

    const connection = createConnection(serverUrl, roomId);

    connection.connect();

    return () => {

      connection.disconnect();

    };

  }, []); // ✅ All dependencies declared

  // ...

}
```

You can also move them *inside the Effect.* They aren’t calculated during rendering, so they’re not reactive:

```
function ChatRoom() {

  useEffect(() => {

    const serverUrl = 'https://localhost:1234'; // serverUrl is not reactive

    const roomId = 'general'; // roomId is not reactive

    const connection = createConnection(serverUrl, roomId);

    connection.connect();

    return () => {

      connection.disconnect();

    };

  }, []); // ✅ All dependencies declared

  // ...

}
```

```
useEffect(() => {

  // ...

  // 🔴 Avoid suppressing the linter like this:

  // eslint-ignore-next-line react-hooks/exhaustive-deps

}, []);
```

```
import { useState, useEffect } from 'react';
import { createConnection } from './chat.js';

const serverUrl = 'https://localhost:1234';

function ChatRoom({ roomId }) {
  const [message, setMessage] = useState('');

  useEffect(() => {
    const connection = createConnection(serverUrl, roomId);
    connection.connect();
    return () => connection.disconnect();
  });

  return (
    <>
      <h1>Welcome to the {roomId} room!</h1>
      <input
        value={message}
        onChange={e => setMessage(e.target.value)}
      />
    </>
  );
}

export default function App() {
  const [roomId, setRoomId] = useState('general');
  return (
    <>
      <label>
        Choose the chat room:{' '}
        <select
          value={roomId}
          onChange={e => setRoomId(e.target.value)}
        >
          <option value="general">general</option>
          <option value="travel">travel</option>
          <option value="music">music</option>
        </select>
      </label>
      <hr />
      <ChatRoom roomId={roomId} />
    </>
  );
}
```

[PreviousYou Might Not Need an Effect](/learn/you-might-not-need-an-effect)

[NextSeparating Events from Effects](/learn/separating-events-from-effects)

***

----
url: https://18.react.dev/learn/understanding-your-ui-as-a-tree
----

Trees are a relationship model between items and UI is often represented using tree structures. For example, browsers use tree structures to model HTML ([DOM](https://developer.mozilla.org/docs/Web/API/Document_Object_Model/Introduction)) and CSS ([CSSOM](https://developer.mozilla.org/docs/Web/API/CSS_Object_Model)). Mobile platforms also use trees to represent their view hierarchy.

React creates a UI tree from your components. In this example, the UI tree is then used to render to the DOM.

Like browsers and mobile platforms, React also uses tree structures to manage and model the relationship between components in a React app. These trees are useful tools to understand how data flows through a React app and how to optimize rendering and app size.

## The Render Tree[](#the-render-tree "Link for The Render Tree ")

A major feature of components is the ability to compose components of other components. As we [nest components](/learn/your-first-component#nesting-and-organizing-components), we have the concept of parent and child components, where each parent component may itself be a child of another component.

When we render a React app, we can model this relationship in a tree, known as the render tree.

Here is a React app that renders inspirational quotes.

```
import FancyText from './FancyText';
import InspirationGenerator from './InspirationGenerator';
import Copyright from './Copyright';

export default function App() {
  return (
    <>
      <FancyText title text="Get Inspired App" />
      <InspirationGenerator>
        <Copyright year={2004} />
      </InspirationGenerator>
    </>
  );
}
```

```
import FancyText from './FancyText';
import InspirationGenerator from './InspirationGenerator';
import Copyright from './Copyright';

export default function App() {
  return (
    <>
      <FancyText title text="Get Inspired App" />
      <InspirationGenerator>
        <Copyright year={2004} />
      </InspirationGenerator>
    </>
  );
}
```

***

----
url: https://legacy.reactjs.org/blog/2016/07/11/introducing-reacts-error-code-system.html
----

July 11, 2016 by [Keyan Zhang](https://twitter.com/keyanzhang)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

Building a better developer experience has been one of the things that React deeply cares about, and a crucial part of it is to detect anti-patterns/potential errors early and provide helpful error messages when things (may) go wrong. However, most of these only exist in development mode; in production, we avoid having extra expensive assertions and sending down full error messages in order to reduce the number of bytes sent over the wire.

Prior to this release, we stripped out error messages at build-time and this is why you might have seen this message in production:

> Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.

In order to make debugging in production easier, we’re introducing an Error Code System in [15.2.0](https://github.com/facebook/react/releases/tag/v15.2.0). We developed a [script](https://github.com/facebook/react/blob/main/scripts/error-codes/extract-errors.js) that collects all of our `invariant` error messages and folds them to a [JSON file](https://github.com/facebook/react/blob/main/scripts/error-codes/codes.json), and at build-time Babel uses the JSON to [rewrite](https://github.com/facebook/react/blob/main/scripts/error-codes/transform-error-messages.js) our `invariant` calls in production to reference the corresponding error IDs. Now when things go wrong in production, the error that React throws will contain a URL with an error ID and relevant information. The URL will point you to a page in our documentation where the original error message gets reassembled.

While we hope you don’t see errors often, you can see how it works [here](/docs/error-decoder.html?invariant=109\&args%5B%5D=Foo). This is what the same error from above will look like:

> Minified React error #109; visit [https://reactjs.org/docs/error-decoder.html?invariant=109\&args\[\]=Foo](/docs/error-decoder.html?invariant=109\&args%5B%5D=Foo) for the full message or use the non-minified dev environment for full errors and additional helpful warnings.

We do this so that the developer experience is as good as possible, while also keeping the production bundle size as small as possible. This feature shouldn’t require any changes on your side — use the `min.js` files in production or bundle your application code with `process.env.NODE_ENV === 'production'` and you should be good to go!

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2016-07-11-introducing-reacts-error-code-system.md)

----
url: https://legacy.reactjs.org/blog/2015/08/11/relay-technical-preview.html
----

August 11, 2015 by [Joseph Savona](https://twitter.com/en_JS)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

# [](#relay)Relay

Today we’re excited to share an update on Relay - the technical preview is now open-source and [available on GitHub](http://github.com/facebook/relay).

## [](#why-relay)Why Relay

While React simplified the process of developing complex user-interfaces, it left open the question of how to interact with data on the server. It turns out that this was a significant source of friction for our developers; fragile coupling between client and server caused data-related bugs and made iteration harder. Furthermore, developers were forced to constantly re-implement complex async logic instead of focusing on their apps. Relay addresses these concerns by borrowing important lessons from React: it provides *declarative, component-oriented data fetching for React applications*.

Declarative data-fetching means that Relay applications specify *what* data they need, not *how* to fetch that data. Just as React uses a description of the desired UI to manage view updates, Relay uses a data description in the form of GraphQL queries. Given these descriptions, Relay coalesces queries into batches for efficiency, manages error-prone asynchronous logic, caches data for performance, and automatically updates views as data changes.

Relay is also component-oriented, extending the notion of a React component to include a description of what data is necessary to render it. This collocation allows developers to reason locally about their application and eliminates bugs such as under- or over-fetching data.

Relay is in use at Facebook in production apps, and we’re using it more and more because *Relay lets developers focus on their products and move fast*. It’s working for us and we’d like to share it with the community.

## [](#whats-included)What’s Included

We’re open-sourcing a technical preview of Relay - the core framework that we use internally, with some modifications for use outside Facebook. As this is the first release, it’s good to keep in mind that there may be some incomplete or missing features. We’ll continue to develop Relay and are working closely with the GraphQL community to ensure that Relay tracks updates during GraphQL’s RFC period. But we couldn’t wait any longer to get this in your hands, and we’re looking forward to your feedback and contributions.

Relay is available on [GitHub](http://github.com/facebook/relay) and [npm](https://www.npmjs.com/package/react-relay).

## [](#whats-next)What’s Next

The team is super excited to be releasing Relay - and just as excited about what’s next. Here are some of the things we’ll be focusing on:

* Offline support. This will allow applications to fulfill queries and enqueue updates without connectivity.
* Real-time updates. In collaboration with the GraphQL community, we’re working to define a specification for subscriptions and provide support for them in Relay.
* A generic Relay. Just as the power of React was never about the virtual DOM, Relay is much more than a GraphQL client. We’re working to extend Relay to provide a unified interface for interacting not only with server data, but also in-memory and native device data (and, even better, a mix of all three).
* Finally, it’s all too easy as developers to focus on those people with the newest devices and fastest internet connections. We’re working to make it easier to build applications that are robust in the face of slow or intermittent connectivity.

Thanks!

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2015-08-11-relay-technical-preview.md)

----
url: https://legacy.reactjs.org/redirect-to-codepen/uncontrolled-components/input-type-file
----

[Powered by](https://www.algolia.com/?utm_source=react-instantsearch\&utm_medium=website\&utm_content=codepen.io\&utm_campaign=poweredby)

##### About External Resources

You can apply CSS to your Pen from any stylesheet on the web. Just put a URL to it here and we'll apply it, in the order you have them, before the CSS in the Pen itself.

You can also link to another Pen here (use the `.css` [URL Extension](https://blog.codepen.io/documentation/url-extensions/)) and we'll pull the CSS from that Pen and include it. If it's using a *matching* preprocessor, use the appropriate URL Extension and we'll combine the code before preprocessing, so you can use the linked Pen as a true dependency.

[Learn more](https://blog.codepen.io/documentation/editor/adding-external-resources/)

[Powered by](https://www.algolia.com/?utm_source=react-instantsearch\&utm_medium=website\&utm_content=codepen.io\&utm_campaign=poweredby)

##### About External Resources

You can apply a script from anywhere on the web to your Pen. Just put a URL to it here and we'll add it, in the order you have them, before the JavaScript in the Pen itself.

If the script you link to has the file extension of a preprocessor, we'll attempt to process it before applying.

You can also link to another Pen here, and we'll pull the JavaScript from that Pen and include it. If it's using a matching preprocessor, we'll combine the code before preprocessing, so you can use the linked Pen as a true dependency.

[Learn more](https://blog.codepen.io/documentation/adding-external-resources/)

\+ add another resource

### Packages

#### Add Packages

Search for and use JavaScript packages from [npm](https://www.npmjs.com/) here. By selecting a package, an `import` statement will be added to the top of the JavaScript editor for this package.

*
*
*
*
*
*
*

```
              
                <div id="root"></div>
              
            
```

!

```
              
                
              
            
```

!

## JS

```
              
                class FileInput extends React.Component {
  constructor(props) {
    // highlight-range{3}
    super(props);
    this.handleSubmit = this.handleSubmit.bind(this);
    this.fileInput = React.createRef();
  }
  handleSubmit(event) {
    // highlight-range{3}
    event.preventDefault();
    alert(
      `Selected file - ${this.fileInput.current.files[0].name}`
    );
  }

  render() {
    // highlight-range{5}
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Upload file:
          <input type="file" ref={this.fileInput} />
        </label>
        <br />
        <button type="submit">Submit</button>
      </form>
    );
  }
}

const root = ReactDOM.createRoot(
  document.getElementById('root')
);
root.render(<FileInput />);

              
            
```

!

999px

If you get tired, be like an AJAX request and REST.

----
url: https://18.react.dev/reference/react/Children
----

[API Reference](/reference/react)

[Legacy React APIs](/reference/react/legacy)

# Children[](#undefined "Link for this heading")

### Pitfall

Using `Children` is uncommon and can lead to fragile code. [See common alternatives.](#alternatives)

`Children` lets you manipulate and transform the JSX you received as the [`children` prop.](/learn/passing-props-to-a-component#passing-jsx-as-children)

```
const mappedChildren = Children.map(children, child =>

  <div className="Row">

    {child}

  </div>

);
```

***

## Reference[](#reference "Link for Reference ")

### `Children.count(children)`[](#children-count "Link for this heading")

Call `Children.count(children)` to count the number of children in the `children` data structure.

```
import { Children } from 'react';



function RowList({ children }) {

  return (

    <>

      <h1>Total rows: {Children.count(children)}</h1>

      ...

    </>

  );

}
```

***

### `Children.forEach(children, fn, thisArg?)`[](#children-foreach "Link for this heading")

Call `Children.forEach(children, fn, thisArg?)` to run some code for each child in the `children` data structure.

```
import { Children } from 'react';



function SeparatorList({ children }) {

  const result = [];

  Children.forEach(children, (child, index) => {

    result.push(child);

    result.push(<hr key={index} />);

  });

  // ...
```

***

### `Children.map(children, fn, thisArg?)`[](#children-map "Link for this heading")

Call `Children.map(children, fn, thisArg?)` to map or transform each child in the `children` data structure.

```
import { Children } from 'react';



function RowList({ children }) {

  return (

    <div className="RowList">

      {Children.map(children, child =>

        <div className="Row">

          {child}

        </div>

      )}

    </div>

  );

}
```

***

### `Children.only(children)`[](#children-only "Link for this heading")

Call `Children.only(children)` to assert that `children` represent a single React element.

```
function Box({ children }) {

  const element = Children.only(children);

  // ...
```

***

### `Children.toArray(children)`[](#children-toarray "Link for this heading")

Call `Children.toArray(children)` to create an array out of the `children` data structure.

```
import { Children } from 'react';



export default function ReversedList({ children }) {

  const result = Children.toArray(children);

  result.reverse();

  // ...
```

#### Parameters[](#children-toarray-parameters "Link for Parameters ")

* `children`: The value of the [`children` prop](/learn/passing-props-to-a-component#passing-jsx-as-children) received by your component.

#### Returns[](#children-toarray-returns "Link for Returns ")

Returns a flat array of elements in `children`.

#### Caveats[](#children-toarray-caveats "Link for Caveats ")

* Empty nodes (`null`, `undefined`, and Booleans) will be omitted in the returned array. **The returned elements’ keys will be calculated from the original elements’ keys and their level of nesting and position.** This ensures that flattening the array does not introduce changes in behavior.

***

## Usage[](#usage "Link for Usage ")

### Transforming children[](#transforming-children "Link for Transforming children ")

To transform the children JSX that your component [receives as the `children` prop,](/learn/passing-props-to-a-component#passing-jsx-as-children) call `Children.map`:

```
import { Children } from 'react';



function RowList({ children }) {

  return (

    <div className="RowList">

      {Children.map(children, child =>

        <div className="Row">

          {child}

        </div>

      )}

    </div>

  );

}
```

In the example above, the `RowList` wraps every child it receives into a `<div className="Row">` container. For example, let’s say the parent component passes three `<p>` tags as the `children` prop to `RowList`:

```
<RowList>

  <p>This is the first item.</p>

  <p>This is the second item.</p>

  <p>This is the third item.</p>

</RowList>
```

Then, with the `RowList` implementation above, the final rendered result will look like this:

```
<div className="RowList">

  <div className="Row">

    <p>This is the first item.</p>

  </div>

  <div className="Row">

    <p>This is the second item.</p>

  </div>

  <div className="Row">

    <p>This is the third item.</p>

  </div>

</div>
```

`Children.map` is similar to [to transforming arrays with `map()`.](/learn/rendering-lists) The difference is that the `children` data structure is considered *opaque.* This means that even if it’s sometimes an array, you should not assume it’s an array or any other particular data type. This is why you should use `Children.map` if you need to transform it.

```
import { Children } from 'react';

export default function RowList({ children }) {
  return (
    <div className="RowList">
      {Children.map(children, child =>
        <div className="Row">
          {child}
        </div>
      )}
    </div>
  );
}
```

```
import RowList from './RowList.js';

export default function App() {
  return (
    <RowList>
      <p>This is the first item.</p>
      <MoreRows />
    </RowList>
  );
}

function MoreRows() {
  return (
    <>
      <p>This is the second item.</p>
      <p>This is the third item.</p>
    </>
  );
}
```

**There is no way to get the rendered output of an inner component** like `<MoreRows />` when manipulating `children`. This is why [it’s usually better to use one of the alternative solutions.](#alternatives)

***

### Running some code for each child[](#running-some-code-for-each-child "Link for Running some code for each child ")

Call `Children.forEach` to iterate over each child in the `children` data structure. It does not return any value and is similar to the [array `forEach` method.](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach) You can use it to run custom logic like constructing your own array.

```
import { Children } from 'react';

export default function SeparatorList({ children }) {
  const result = [];
  Children.forEach(children, (child, index) => {
    result.push(child);
    result.push(<hr key={index} />);
  });
  result.pop(); // Remove the last separator
  return result;
}
```

### Pitfall

As mentioned earlier, there is no way to get the rendered output of an inner component when manipulating `children`. This is why [it’s usually better to use one of the alternative solutions.](#alternatives)

***

### Counting children[](#counting-children "Link for Counting children ")

Call `Children.count(children)` to calculate the number of children.

```
import { Children } from 'react';

export default function RowList({ children }) {
  return (
    <div className="RowList">
      <h1 className="RowListHeader">
        Total rows: {Children.count(children)}
      </h1>
      {Children.map(children, child =>
        <div className="Row">
          {child}
        </div>
      )}
    </div>
  );
}
```

### Pitfall

As mentioned earlier, there is no way to get the rendered output of an inner component when manipulating `children`. This is why [it’s usually better to use one of the alternative solutions.](#alternatives)

***

### Converting children to an array[](#converting-children-to-an-array "Link for Converting children to an array ")

Call `Children.toArray(children)` to turn the `children` data structure into a regular JavaScript array. This lets you manipulate the array with built-in array methods like [`filter`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter), [`sort`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort), or [`reverse`.](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse)

```
import { Children } from 'react';

export default function ReversedList({ children }) {
  const result = Children.toArray(children);
  result.reverse();
  return result;
}
```

### Pitfall

As mentioned earlier, there is no way to get the rendered output of an inner component when manipulating `children`. This is why [it’s usually better to use one of the alternative solutions.](#alternatives)

***

## Alternatives[](#alternatives "Link for Alternatives ")

### Note

This section describes alternatives to the `Children` API (with capital `C`) that’s imported like this:

```
import { Children } from 'react';
```

Don’t confuse it with [using the `children` prop](/learn/passing-props-to-a-component#passing-jsx-as-children) (lowercase `c`), which is good and encouraged.

### Exposing multiple components[](#exposing-multiple-components "Link for Exposing multiple components ")

Manipulating children with the `Children` methods often leads to fragile code. When you pass children to a component in JSX, you don’t usually expect the component to manipulate or transform the individual children.

When you can, try to avoid using the `Children` methods. For example, if you want every child of `RowList` to be wrapped in `<div className="Row">`, export a `Row` component, and manually wrap every row into it like this:

```
import { RowList, Row } from './RowList.js';

export default function App() {
  return (
    <RowList>
      <Row>
        <p>This is the first item.</p>
      </Row>
      <Row>
        <p>This is the second item.</p>
      </Row>
      <Row>
        <p>This is the third item.</p>
      </Row>
    </RowList>
  );
}
```

Unlike using `Children.map`, this approach does not wrap every child automatically. **However, this approach has a significant benefit compared to the [earlier example with `Children.map`](#transforming-children) because it works even if you keep extracting more components.** For example, it still works if you extract your own `MoreRows` component:

```
import { RowList, Row } from './RowList.js';

export default function App() {
  return (
    <RowList>
      <Row>
        <p>This is the first item.</p>
      </Row>
      <MoreRows />
    </RowList>
  );
}

function MoreRows() {
  return (
    <>
      <Row>
        <p>This is the second item.</p>
      </Row>
      <Row>
        <p>This is the third item.</p>
      </Row>
    </>
  );
}
```

This wouldn’t work with `Children.map` because it would “see” `<MoreRows />` as a single child (and a single row).

***

### Accepting an array of objects as a prop[](#accepting-an-array-of-objects-as-a-prop "Link for Accepting an array of objects as a prop ")

You can also explicitly pass an array as a prop. For example, this `RowList` accepts a `rows` array as a prop:

```
import { RowList, Row } from './RowList.js';

export default function App() {
  return (
    <RowList rows={[
      { id: 'first', content: <p>This is the first item.</p> },
      { id: 'second', content: <p>This is the second item.</p> },
      { id: 'third', content: <p>This is the third item.</p> }
    ]} />
  );
}
```

Since `rows` is a regular JavaScript array, the `RowList` component can use built-in array methods like [`map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) on it.

This pattern is especially useful when you want to be able to pass more information as structured data together with children. In the below example, the `TabSwitcher` component receives an array of objects as the `tabs` prop:

```
import TabSwitcher from './TabSwitcher.js';

export default function App() {
  return (
    <TabSwitcher tabs={[
      {
        id: 'first',
        header: 'First',
        content: <p>This is the first item.</p>
      },
      {
        id: 'second',
        header: 'Second',
        content: <p>This is the second item.</p>
      },
      {
        id: 'third',
        header: 'Third',
        content: <p>This is the third item.</p>
      }
    ]} />
  );
}
```

Unlike passing the children as JSX, this approach lets you associate some extra data like `header` with each item. Because you are working with the `tabs` directly, and it is an array, you do not need the `Children` methods.

***

### Calling a render prop to customize rendering[](#calling-a-render-prop-to-customize-rendering "Link for Calling a render prop to customize rendering ")

Instead of producing JSX for every single item, you can also pass a function that returns JSX, and call that function when necessary. In this example, the `App` component passes a `renderContent` function to the `TabSwitcher` component. The `TabSwitcher` component calls `renderContent` only for the selected tab:

```
import TabSwitcher from './TabSwitcher.js';

export default function App() {
  return (
    <TabSwitcher
      tabIds={['first', 'second', 'third']}
      getHeader={tabId => {
        return tabId[0].toUpperCase() + tabId.slice(1);
      }}
      renderContent={tabId => {
        return <p>This is the {tabId} item.</p>;
      }}
    />
  );
}
```

A prop like `renderContent` is called a *render prop* because it is a prop that specifies how to render a piece of the user interface. However, there is nothing special about it: it is a regular prop which happens to be a function.

Render props are functions, so you can pass information to them. For example, this `RowList` component passes the `id` and the `index` of each row to the `renderRow` render prop, which uses `index` to highlight even rows:

```
import { RowList, Row } from './RowList.js';

export default function App() {
  return (
    <RowList
      rowIds={['first', 'second', 'third']}
      renderRow={(id, index) => {
        return (
          <Row isHighlighted={index % 2 === 0}>
            <p>This is the {id} item.</p>
          </Row> 
        );
      }}
    />
  );
}
```

This is another example of how parent and child components can cooperate without manipulating the children.

***

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### I pass a custom component, but the `Children` methods don’t show its render result[](#i-pass-a-custom-component-but-the-children-methods-dont-show-its-render-result "Link for this heading")

Suppose you pass two children to `RowList` like this:

```
<RowList>

  <p>First item</p>

  <MoreRows />

</RowList>
```

If you do `Children.count(children)` inside `RowList`, you will get `2`. Even if `MoreRows` renders 10 different items, or if it returns `null`, `Children.count(children)` will still be `2`. From the `RowList`’s perspective, it only “sees” the JSX it has received. It does not “see” the internals of the `MoreRows` component.

The limitation makes it hard to extract a component. This is why [alternatives](#alternatives) are preferred to using `Children`.

[PreviousLegacy React APIs](/reference/react/legacy)

[NextcloneElement](/reference/react/cloneElement)

***

----
url: https://react.dev/reference/eslint-plugin-react-hooks/lints/set-state-in-effect
----

[API Reference](/reference/react)

[Lints](/reference/eslint-plugin-react-hooks)

# set-state-in-effect[](#undefined "Link for this heading")

Validates against calling setState synchronously in an effect, which can lead to re-renders that degrade performance.

## Rule Details[](#rule-details "Link for Rule Details ")

Setting state immediately inside an effect forces React to restart the entire render cycle. When you update state in an effect, React must re-render your component, apply changes to the DOM, and then run effects again. This creates an extra render pass that could have been avoided by transforming data directly during render or deriving state from props. Transform data at the top level of your component instead. This code will naturally re-run when props or state change without triggering additional render cycles.

Synchronous `setState` calls in effects trigger immediate re-renders before the browser can paint, causing performance issues and visual jank. React has to render twice: once to apply the state update, then again after effects run. This double rendering is wasteful when the same result could be achieved with a single render.

In many cases, you may also not need an effect at all. Please see [You Might Not Need an Effect](/learn/you-might-not-need-an-effect) for more information.

## Common Violations[](#common-violations "Link for Common Violations ")

This rule catches several patterns where synchronous setState is used unnecessarily:

* Setting loading state synchronously
* Deriving state from props in effects
* Transforming data in effects instead of render

### Invalid[](#invalid "Link for Invalid ")

Examples of incorrect code for this rule:

```
// ❌ Synchronous setState in effect

function Component({data}) {

  const [items, setItems] = useState([]);



  useEffect(() => {

    setItems(data); // Extra render, use initial state instead

  }, [data]);

}



// ❌ Setting loading state synchronously

function Component() {

  const [loading, setLoading] = useState(false);



  useEffect(() => {

    setLoading(true); // Synchronous, causes extra render

    fetchData().then(() => setLoading(false));

  }, []);

}



// ❌ Transforming data in effect

function Component({rawData}) {

  const [processed, setProcessed] = useState([]);



  useEffect(() => {

    setProcessed(rawData.map(transform)); // Should derive in render

  }, [rawData]);

}



// ❌ Deriving state from props

function Component({selectedId, items}) {

  const [selected, setSelected] = useState(null);



  useEffect(() => {

    setSelected(items.find(i => i.id === selectedId));

  }, [selectedId, items]);

}
```

### Valid[](#valid "Link for Valid ")

Examples of correct code for this rule:

```
// ✅ setState in an effect is fine if the value comes from a ref

function Tooltip() {

  const ref = useRef(null);

  const [tooltipHeight, setTooltipHeight] = useState(0);



  useLayoutEffect(() => {

    const { height } = ref.current.getBoundingClientRect();

    setTooltipHeight(height);

  }, []);

}



// ✅ Calculate during render

function Component({selectedId, items}) {

  const selected = items.find(i => i.id === selectedId);

  return <div>{selected?.name}</div>;

}
```

**When something can be calculated from the existing props or state, don’t put it in state.** Instead, calculate it during rendering. This makes your code faster, simpler, and less error-prone. Learn more in [You Might Not Need an Effect](/learn/you-might-not-need-an-effect).

[Previousrefs](/reference/eslint-plugin-react-hooks/lints/refs)

[Nextset-state-in-render](/reference/eslint-plugin-react-hooks/lints/set-state-in-render)

***

----
url: https://react.dev/blog/2025/10/07/react-compiler-1
----

[Blog](/blog)

# React Compiler v1.0[](#undefined "Link for this heading")

Oct 7, 2025 by [Lauren Tan](https://x.com/potetotes), [Joe Savona](https://x.com/en_JS), and [Mofei Zhang](https://x.com/zmofei).

***

The React team is excited to share new updates:

1. React Compiler 1.0 is available today.
2. Compiler-powered lint rules ship in `eslint-plugin-react-hooks`’s `recommended` and `recommended-latest` preset.
3. We’ve published an incremental adoption guide, and partnered with Expo, Vite, and Next.js so new apps can start with the compiler enabled.

***

We are releasing the compiler’s first stable release today. React Compiler works on both React and React Native, and automatically optimizes components and hooks without requiring rewrites. The compiler has been battle tested on major apps at Meta and is fully production-ready.

[React Compiler](/learn/react-compiler) is a build-time tool that optimizes your React app through automatic memoization. Last year, we published React Compiler’s [first beta](/blog/2024/10/21/react-compiler-beta-release) and received lots of great feedback and contributions. We’re excited about the wins we’ve seen from folks adopting the compiler (see case studies from [Sanity Studio](https://github.com/reactwg/react-compiler/discussions/33) and [Wakelet](https://github.com/reactwg/react-compiler/discussions/52)) and are excited to bring the compiler to more users in the React community.

This release is the culmination of a huge and complex engineering effort spanning almost a decade. The React team’s first exploration into compilers started with [Prepack](https://github.com/facebookarchive/prepack) in 2017. While this project was eventually shut down, there were many learnings that informed the team on the design of Hooks, which were designed with a future compiler in mind. In 2021, [Xuan Huang](https://x.com/Huxpro) demoed the [first iteration](https://www.youtube.com/watch?v=lGEMwh32soc) of a new take on React Compiler.

Although this first version of the new React Compiler was eventually rewritten, the first prototype gave us increased confidence that this was a tractable problem, and the learnings that an alternative compiler architecture could precisely give us the memoization characteristics we wanted. [Joe Savona](https://x.com/en_JS), [Sathya Gunasekaran](https://x.com/_gsathya), [Mofei Zhang](https://x.com/zmofei), and [Lauren Tan](https://x.com/potetotes) worked through our first rewrite, moving the compiler’s architecture into a Control Flow Graph (CFG) based High-Level Intermediate Representation (HIR). This paved the way for much more precise analysis and even type inference within React Compiler. Since then, many significant portions of the compiler have been rewritten, with each rewrite informed by our learnings from the previous attempt. And we have received significant help and contributions from many members of the [React team](/community/team) along the way.

This stable release is our first of many. The compiler will continue to evolve and improve, and we expect to see it become a new foundation and era for the next decade and more of React.

You can jump straight to the [quickstart](/learn/react-compiler), or read on for the highlights from React Conf 2025.

##### Deep Dive#### How does React Compiler work?[](#how-does-react-compiler-work "Link for How does React Compiler work? ")

React Compiler is an optimizing compiler that optimizes components and hooks through automatic memoization. While it is implemented as a Babel plugin currently, the compiler is largely decoupled from Babel and lowers the Abstract Syntax Tree (AST) provided by Babel into its own novel HIR, and through multiple compiler passes, carefully understands data-flow and mutability of your React code. This allows the compiler to granularly memoize values used in rendering, including the ability to memoize conditionally, which is not possible through manual memoization.

```
import { use } from 'react';



export default function ThemeProvider(props) {

  if (!props.children) {

    return null;

  }

  // The compiler can still memoize code after a conditional return

  const theme = mergeTheme(props.theme, use(ThemeContext));

  return (

    <ThemeContext value={theme}>

      {props.children}

    </ThemeContext>

  );

}
```

*See this example in the [React Compiler Playground](https://playground.react.dev/#N4Igzg9grgTgxgUxALhASwLYAcIwC4AEwBUYCBAvgQGYwQYEDkMCAhnHowNwA6AdvwQAPHPgIATBNVZQANoWpQ+HNBD4EAKgAsEGBAAU6ANzSSYACix0sYAJRF+BAmmoFzAQisQbAOjha0WXEWPntgRycCFjxYdT45WV51Sgi4NTBCPB09AgBeAj0YAHMEbV0ES2swHyzygBoSMnMyvQBhNTxhPFtbJKdo2LcIpwAeFoR2vk6hQiNWWSgEXOBavQoAPmHI4C9ff0DghD4KLZGAenHJ6bxN5N7+ChA6kDS+ajQilHRsXEyATyw5GI+gWRTQfAA8lg8Ko+GBKDQ6AxGAAjVgohCyAC0WFB4KxLHYeCxaWwgQQMDO4jQGW4-H45nCyTOZ1JWECrBhagAshBJMgCDwQPNZEKHgQwJyae8EPCQVAwZDobC7FwnuAtBAAO4ASSmFL48zAKGksjIFCAA)*

In addition to automatic memoization, React Compiler also has validation passes that run on your React code. These passes encode the [Rules of React](/reference/rules), and uses the compiler’s understanding of data-flow and mutability to provide diagnostics where the Rules of React are broken. These diagnostics often expose latent bugs hiding in React code, and are primarily surfaced through `eslint-plugin-react-hooks`.

To learn more about how the compiler optimizes your code, visit the [Playground](https://playground.react.dev).

## Use React Compiler Today[](#use-react-compiler-today "Link for Use React Compiler Today ")

To install the compiler:

npm

Terminal

```
npm install --save-dev --save-exact babel-plugin-react-compiler@latest
```

pnpm

Terminal

```
pnpm add --save-dev --save-exact babel-plugin-react-compiler@latest
```

yarn

Terminal

```
yarn add --dev --exact babel-plugin-react-compiler@latest
```

As part of the stable release, we’ve been making React Compiler easier to add to your projects and added optimizations to how the compiler generates memoization. React Compiler now supports optional chains and array indices as dependencies. These improvements ultimately result in fewer re-renders and more responsive UIs, while letting you keep writing idiomatic declarative code.

You can find more details on using the Compiler in [our docs](/learn/react-compiler).

## What we’re seeing in production[](#react-compiler-at-meta "Link for What we’re seeing in production ")

[The compiler has already shipped in apps like Meta Quest Store](https://youtu.be/lyEKhv8-3n0?t=3002). We’ve seen initial loads and cross-page navigations improve by up to 12%, while certain interactions are more than 2.5× faster. Memory usage stays neutral even with these wins. Although your mileage may vary, we recommend experimenting with the compiler in your app to see similar performance gains.

## Backwards Compatibility[](#backwards-compatibility "Link for Backwards Compatibility ")

As noted in the Beta announcement, React Compiler is compatible with React 17 and up. If you are not yet on React 19, you can use React Compiler by specifying a minimum target in your compiler config, and adding `react-compiler-runtime` as a dependency. You can find docs on this [here](/reference/react-compiler/target#targeting-react-17-or-18).

## Enforce the Rules of React with compiler-powered linting[](#migrating-from-eslint-plugin-react-compiler-to-eslint-plugin-react-hooks "Link for Enforce the Rules of React with compiler-powered linting ")

React Compiler includes an ESLint rule that helps identify code that breaks the [Rules of React](/reference/rules). The linter does not require the compiler to be installed, so there’s no risk in upgrading eslint-plugin-react-hooks. We recommend everyone upgrade today.

If you have already installed `eslint-plugin-react-compiler`, you can now remove it and use `eslint-plugin-react-hooks@latest`. Many thanks to [@michaelfaith](https://bsky.app/profile/michael.faith) for contributing to this improvement!

To install:

npm

Terminal

```
npm install --save-dev eslint-plugin-react-hooks@latest
```

pnpm

Terminal

```
pnpm add --save-dev eslint-plugin-react-hooks@latest
```

yarn

Terminal

```
yarn add --dev eslint-plugin-react-hooks@latest
```

```
// eslint.config.js (Flat Config)

import reactHooks from 'eslint-plugin-react-hooks';

import { defineConfig } from 'eslint/config';



export default defineConfig([

  reactHooks.configs.flat.recommended,

]);
```

```
// eslintrc.json (Legacy Config)

{

  "extends": ["plugin:react-hooks/recommended"],

  // ...

}
```

To enable React Compiler rules, we recommend using the `recommended` preset. You can also check out the [README](https://github.com/facebook/react/blob/main/packages/eslint-plugin-react-hooks/README.md) for more instructions. Here are a few examples we featured at React Conf:

* Catching `setState` patterns that cause render loops with [`set-state-in-render`](/reference/eslint-plugin-react-hooks/lints/set-state-in-render).
* Flagging expensive work inside effects via [`set-state-in-effect`](/reference/eslint-plugin-react-hooks/lints/set-state-in-effect).
* Preventing unsafe ref access during render with [`refs`](/reference/eslint-plugin-react-hooks/lints/refs).

## What should I do about useMemo, useCallback, and React.memo?[](#what-should-i-do-about-usememo-usecallback-and-reactmemo "Link for What should I do about useMemo, useCallback, and React.memo? ")

By default, React Compiler will memoize your code based on its analysis and heuristics. In most cases, this memoization will be as precise, or moreso, than what you may have written — and as noted above, the compiler can memoize even in cases where `useMemo`/`useCallback` cannot be used, such as after an early return.

However, in some cases developers may need more control over memoization. The `useMemo` and `useCallback` hooks can continue to be used with React Compiler as an escape hatch to provide control over which values are memoized. A common use-case for this is if a memoized value is used as an effect dependency, in order to ensure that an effect does not fire repeatedly even when its dependencies do not meaningfully change.

For new code, we recommend relying on the compiler for memoization and using `useMemo`/`useCallback` where needed to achieve precise control.

For existing code, we recommend either leaving existing memoization in place (removing it can change compilation output) or carefully testing before removing the memoization.

## New apps should use React Compiler[](#new-apps-should-use-react-compiler "Link for New apps should use React Compiler ")

We have partnered with the Expo, Vite, and Next.js teams to add the compiler to the new app experience.

[Expo SDK 54](https://docs.expo.dev/guides/react-compiler/) and up has the compiler enabled by default, so new apps will automatically be able to take advantage of the compiler from the start.

Terminal

```
npx create-expo-app@latest
```

[Vite](https://vite.dev/guide/) and [Next.js](https://nextjs.org/docs/app/api-reference/cli/create-next-app) users can choose the compiler enabled templates in `create-vite` and `create-next-app`.

Terminal

```
npm create vite@latest
```



Terminal

```
npx create-next-app@latest
```

## Adopt React Compiler incrementally[](#adopt-react-compiler-incrementally "Link for Adopt React Compiler incrementally ")

If you’re maintaining an existing application, you can roll out the compiler at your own pace. We published a step-by-step [incremental adoption guide](/learn/react-compiler/incremental-adoption) that covers gating strategies, compatibility checks, and rollout tooling so you can enable the compiler with confidence.

## swc support (experimental)[](#swc-support-experimental "Link for swc support (experimental) ")

React Compiler can be installed across [several build tools](/learn/react-compiler#installation) such as Babel, Vite, and Rsbuild.

In addition to those tools, we have been collaborating with Kang Dongyoon ([@kdy1dev](https://x.com/kdy1dev)) from the [swc](https://swc.rs/) team on adding additional support for React Compiler as an swc plugin. While this work isn’t done, Next.js build performance should now be considerably faster when the [React Compiler is enabled in your Next.js app](https://nextjs.org/docs/app/api-reference/config/next-config-js/reactCompiler).

We recommend using Next.js [15.3.1](https://github.com/vercel/next.js/releases/tag/v15.3.1) or greater to get the best build performance.

Vite users can continue to use [vite-plugin-react](https://github.com/vitejs/vite-plugin-react) to enable the compiler, by adding it as a [Babel plugin](/learn/react-compiler/installation#vite). We are also working with the [oxc](https://oxc.rs/) team to [add support for the compiler](https://github.com/oxc-project/oxc/issues/10048). Once [rolldown](https://github.com/rolldown/rolldown) is officially released and supported in Vite and oxc support is added for React Compiler, we’ll update the docs with information on how to migrate.

## Upgrading React Compiler[](#upgrading-react-compiler "Link for Upgrading React Compiler ")

React Compiler works best when the auto-memoization applied is strictly for performance. Future versions of the compiler may change how memoization is applied, for example it could become more granular and precise.

However, because product code may sometimes break the [rules of React](/reference/rules) in ways that aren’t always statically detectable in JavaScript, changing memoization can occasionally have unexpected results. For example, a previously memoized value might be used as a dependency for a `useEffect` somewhere in the component tree. Changing how or whether this value is memoized can cause over or under-firing of that `useEffect`. While we encourage [useEffect only for synchronization](/learn/synchronizing-with-effects), your codebase may have `useEffect`s that cover other use cases, such as effects that needs to only run in response to specific values changing.

In other words, changing memoization may under rare circumstances cause unexpected behavior. For this reason, we recommend following the Rules of React and employing continuous end-to-end testing of your app so you can upgrade the compiler with confidence and identify any rules of React violations that might cause issues.

If you don’t have good test coverage, we recommend pinning the compiler to an exact version (eg `1.0.0`) rather than a SemVer range (eg `^1.0.0`). You can do this by passing the `--save-exact` (npm/pnpm) or `--exact` flags (yarn) when upgrading the compiler. You should then do any upgrades of the compiler manually, taking care to check that your app still works as expected.

***

Thanks to [Jason Bonta](https://x.com/someextent), [Jimmy Lai](https://x.com/feedthejim), [Kang Dongyoon](https://x.com/kdy1dev) (@kdy1dev), and [Dan Abramov](https://bsky.app/profile/danabra.mov) for reviewing and editing this post.

[PreviousReact Conf 2025 Recap](/blog/2025/10/16/react-conf-2025-recap)

[NextIntroducing the React Foundation](/blog/2025/10/07/introducing-the-react-foundation)

***

----
url: https://react.dev/reference/eslint-plugin-react-hooks/lints/static-components
----

[API Reference](/reference/react)

[Lints](/reference/eslint-plugin-react-hooks)

# static-components[](#undefined "Link for this heading")

Validates that components are static, not recreated every render. Components that are recreated dynamically can reset state and trigger excessive re-rendering.

## Rule Details[](#rule-details "Link for Rule Details ")

Components defined inside other components are recreated on every render. React sees each as a brand new component type, unmounting the old one and mounting the new one, destroying all state and DOM nodes in the process.

### Invalid[](#invalid "Link for Invalid ")

Examples of incorrect code for this rule:

```
// ❌ Component defined inside component

function Parent() {

  const ChildComponent = () => { // New component every render!

    const [count, setCount] = useState(0);

    return <button onClick={() => setCount(count + 1)}>{count}</button>;

  };



  return <ChildComponent />; // State resets every render

}



// ❌ Dynamic component creation

function Parent({type}) {

  const Component = type === 'button'

    ? () => <button>Click</button>

    : () => <div>Text</div>;



  return <Component />;

}
```

### Valid[](#valid "Link for Valid ")

Examples of correct code for this rule:

```
// ✅ Components at module level

const ButtonComponent = () => <button>Click</button>;

const TextComponent = () => <div>Text</div>;



function Parent({type}) {

  const Component = type === 'button'

    ? ButtonComponent  // Reference existing component

    : TextComponent;



  return <Component />;

}
```

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### I need to render different components conditionally[](#conditional-components "Link for I need to render different components conditionally ")

You might define components inside to access local state:

```
// ❌ Wrong: Inner component to access parent state

function Parent() {

  const [theme, setTheme] = useState('light');



  function ThemedButton() { // Recreated every render!

    return (

      <button className={theme}>

        Click me

      </button>

    );

  }



  return <ThemedButton />;

}
```

Pass data as props instead:

```
// ✅ Better: Pass props to static component

function ThemedButton({theme}) {

  return (

    <button className={theme}>

      Click me

    </button>

  );

}



function Parent() {

  const [theme, setTheme] = useState('light');

  return <ThemedButton theme={theme} />;

}
```

### Note

If you find yourself wanting to define components inside other components to access local variables, that’s a sign you should be passing props instead. This makes components more reusable and testable.

[Previousset-state-in-render](/reference/eslint-plugin-react-hooks/lints/set-state-in-render)

[Nextunsupported-syntax](/reference/eslint-plugin-react-hooks/lints/unsupported-syntax)

***

----
url: https://18.react.dev/learn/importing-and-exporting-components
----

```
function Profile() {
  return (
    <img
      src="https://i.imgur.com/MK3eW3As.jpg"
      alt="Katherine Johnson"
    />
  );
}

export default function Gallery() {
  return (
    <section>
      <h1>Amazing scientists</h1>
      <Profile />
      <Profile />
      <Profile />
    </section>
  );
}
```

```
import Gallery from './Gallery.js';

export default function App() {
  return (
    <Gallery />
  );
}
```

```
import Gallery from './Gallery';
```

Either `'./Gallery.js'` or `'./Gallery'` will work with React, though the former is closer to how [native ES Modules](https://developer.mozilla.org/docs/Web/JavaScript/Guide/Modules) work.

##### Deep Dive#### Default vs named exports[](#default-vs-named-exports "Link for Default vs named exports ")

There are two primary ways to export values with JavaScript: default exports and named exports. So far, our examples have only used default exports. But you can use one or both of them in the same file. **A file can have no more than one *default* export, but it can have as many *named* exports as you like.**

How you export your component dictates how you must import it. You will get an error if you try to import a default export the same way you would a named export! This chart can help you keep track:

| Syntax  | Export statement                      | Import statement                        |
| ------- | ------------------------------------- | --------------------------------------- |
| Default | `export default function Button() {}` | `import Button from './Button.js';`     |
| Named   | `export function Button() {}`         | `import { Button } from './Button.js';` |

```
export function Profile() {

  // ...

}
```

Then, **import** `Profile` from `Gallery.js` to `App.js` using a named import (with the curly braces):

```
import { Profile } from './Gallery.js';
```

Finally, **render** `<Profile />` from the `App` component:

```
export default function App() {

  return <Profile />;

}
```

Now `Gallery.js` contains two exports: a default `Gallery` export, and a named `Profile` export. `App.js` imports both of them. Try editing `<Profile />` to `<Gallery />` and back in this example:

```
import Gallery from './Gallery.js';
import { Profile } from './Gallery.js';

export default function App() {
  return (
    <Profile />
  );
}
```

| Syntax  | Export statement                      | Import statement                        |
| ------- | ------------------------------------- | --------------------------------------- |
| Default | `export default function Button() {}` | `import Button from './Button.js';`     |
| Named   | `export function Button() {}`         | `import { Button } from './Button.js';` |

```
// Move me to Profile.js!
export function Profile() {
  return (
    <img
      src="https://i.imgur.com/QIrZWGIs.jpg"
      alt="Alan L. Hart"
    />
  );
}

export default function Gallery() {
  return (
    <section>
      <h1>Amazing scientists</h1>
      <Profile />
      <Profile />
      <Profile />
    </section>
  );
}
```

After you get it working with one kind of exports, make it work with the other kind.

[PreviousYour First Component](/learn/your-first-component)

[NextWriting Markup with JSX](/learn/writing-markup-with-jsx)

***

----
url: https://18.react.dev/reference/react-dom/components/input
----

[API Reference](/reference/react)

[Components](/reference/react-dom/components)

# \<input>[](#undefined "Link for this heading")

The [built-in browser `<input>` component](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input) lets you render different kinds of form inputs.

```
<input />
```

***

## Reference[](#reference "Link for Reference ")

### `<input>`[](#input "Link for this heading")

To display an input, render the [built-in browser `<input>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input) component.

```
<input name="myInput" />
```

[See more examples below.](#usage)

#### Props[](#props "Link for Props ")

`<input>` supports all [common element props.](/reference/react-dom/components/common#props)

### Canary

React’s extensions to the `formAction` prop are currently only available in React’s Canary and experimental channels. In stable releases of React, `formAction` works only as a [built-in browser HTML component](/reference/react-dom/components#all-html-components). Learn more about [React’s release channels here](/community/versioning-policy#all-release-channels).

[`formAction`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#formaction): A string or function. Overrides the parent `<form action>` for `type="submit"` and `type="image"`. When a URL is passed to `action` the form will behave like a standard HTML form. When a function is passed to `formAction` the function will handle the form submission. See [`<form action>`](/reference/react-dom/components/form#props).

You can [make an input controlled](#controlling-an-input-with-a-state-variable) by passing one of these props:

* [`checked`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement#checked): A boolean. For a checkbox input or a radio button, controls whether it is selected.
* [`value`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement#value): A string. For a text input, controls its text. (For a radio button, specifies its form data.)

When you pass either of them, you must also pass an `onChange` handler that updates the passed value.

These `<input>` props are only relevant for uncontrolled inputs:

* [`defaultChecked`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement#defaultChecked): A boolean. Specifies [the initial value](#providing-an-initial-value-for-an-input) for `type="checkbox"` and `type="radio"` inputs.
* [`defaultValue`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement#defaultValue): A string. Specifies [the initial value](#providing-an-initial-value-for-an-input) for a text input.

These `<input>` props are relevant both for uncontrolled and controlled inputs:

* [`accept`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#accept): A string. Specifies which filetypes are accepted by a `type="file"` input.
* [`alt`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#alt): A string. Specifies the alternative image text for a `type="image"` input.
* [`capture`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#capture): A string. Specifies the media (microphone, video, or camera) captured by a `type="file"` input.
* [`autoComplete`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#autocomplete): A string. Specifies one of the possible [autocomplete behaviors.](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete#values)
* [`autoFocus`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#autofocus): A boolean. If `true`, React will focus the element on mount.
* [`dirname`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#dirname): A string. Specifies the form field name for the element’s directionality.
* [`disabled`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#disabled): A boolean. If `true`, the input will not be interactive and will appear dimmed.
* `children`: `<input>` does not accept children.
* [`form`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#form): A string. Specifies the `id` of the `<form>` this input belongs to. If omitted, it’s the closest parent form.
* [`formAction`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#formaction): A string. Overrides the parent `<form action>` for `type="submit"` and `type="image"`.
* [`formEnctype`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#formenctype): A string. Overrides the parent `<form enctype>` for `type="submit"` and `type="image"`.
* [`formMethod`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#formmethod): A string. Overrides the parent `<form method>` for `type="submit"` and `type="image"`.
* [`formNoValidate`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#formnovalidate): A string. Overrides the parent `<form noValidate>` for `type="submit"` and `type="image"`.
* [`formTarget`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#formtarget): A string. Overrides the parent `<form target>` for `type="submit"` and `type="image"`.
* [`height`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#height): A string. Specifies the image height for `type="image"`.
* [`list`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#list): A string. Specifies the `id` of the `<datalist>` with the autocomplete options.
* [`max`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#max): A number. Specifies the maximum value of numerical and datetime inputs.
* [`maxLength`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#maxlength): A number. Specifies the maximum length of text and other inputs.
* [`min`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#min): A number. Specifies the minimum value of numerical and datetime inputs.
* [`minLength`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#minlength): A number. Specifies the minimum length of text and other inputs.
* [`multiple`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#multiple): A boolean. Specifies whether multiple values are allowed for `<type="file"` and `type="email"`.
* [`name`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#name): A string. Specifies the name for this input that’s [submitted with the form.](#reading-the-input-values-when-submitting-a-form)
* `onChange`: An [`Event` handler](/reference/react-dom/components/common#event-handler) function. Required for [controlled inputs.](#controlling-an-input-with-a-state-variable) Fires immediately when the input’s value is changed by the user (for example, it fires on every keystroke). Behaves like the browser [`input` event.](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/input_event)
* `onChangeCapture`: A version of `onChange` that fires in the [capture phase.](/learn/responding-to-events#capture-phase-events)
* [`onInput`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/input_event): An [`Event` handler](/reference/react-dom/components/common#event-handler) function. Fires immediately when the value is changed by the user. For historical reasons, in React it is idiomatic to use `onChange` instead which works similarly.
* `onInputCapture`: A version of `onInput` that fires in the [capture phase.](/learn/responding-to-events#capture-phase-events)
* [`onInvalid`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/invalid_event): An [`Event` handler](/reference/react-dom/components/common#event-handler) function. Fires if an input fails validation on form submit. Unlike the built-in `invalid` event, the React `onInvalid` event bubbles.
* `onInvalidCapture`: A version of `onInvalid` that fires in the [capture phase.](/learn/responding-to-events#capture-phase-events)
* [`onSelect`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/select_event): An [`Event` handler](/reference/react-dom/components/common#event-handler) function. Fires after the selection inside the `<input>` changes. React extends the `onSelect` event to also fire for empty selection and on edits (which may affect the selection).
* `onSelectCapture`: A version of `onSelect` that fires in the [capture phase.](/learn/responding-to-events#capture-phase-events)
* [`pattern`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#pattern): A string. Specifies the pattern that the `value` must match.
* [`placeholder`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#placeholder): A string. Displayed in a dimmed color when the input value is empty.
* [`readOnly`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#readonly): A boolean. If `true`, the input is not editable by the user.
* [`required`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#required): A boolean. If `true`, the value must be provided for the form to submit.
* [`size`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#size): A number. Similar to setting width, but the unit depends on the control.
* [`src`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#src): A string. Specifies the image source for a `type="image"` input.
* [`step`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#step): A positive number or an `'any'` string. Specifies the distance between valid values.
* [`type`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#type): A string. One of the [input types.](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#input_types)
* [`width`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#width): A string. Specifies the image width for a `type="image"` input.

#### Caveats[](#caveats "Link for Caveats ")

* Checkboxes need `checked` (or `defaultChecked`), not `value` (or `defaultValue`).
* If a text input receives a string `value` prop, it will be [treated as controlled.](#controlling-an-input-with-a-state-variable)
* If a checkbox or a radio button receives a boolean `checked` prop, it will be [treated as controlled.](#controlling-an-input-with-a-state-variable)
* An input can’t be both controlled and uncontrolled at the same time.
* An input cannot switch between being controlled or uncontrolled over its lifetime.
* Every controlled input needs an `onChange` event handler that synchronously updates its backing value.

***

## Usage[](#usage "Link for Usage ")

### Displaying inputs of different types[](#displaying-inputs-of-different-types "Link for Displaying inputs of different types ")

To display an input, render an `<input>` component. By default, it will be a text input. You can pass `type="checkbox"` for a checkbox, `type="radio"` for a radio button, [or one of the other input types.](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#input_types)

```
export default function MyForm() {
  return (
    <>
      <label>
        Text input: <input name="myInput" />
      </label>
      <hr />
      <label>
        Checkbox: <input type="checkbox" name="myCheckbox" />
      </label>
      <hr />
      <p>
        Radio buttons:
        <label>
          <input type="radio" name="myRadio" value="option1" />
          Option 1
        </label>
        <label>
          <input type="radio" name="myRadio" value="option2" />
          Option 2
        </label>
        <label>
          <input type="radio" name="myRadio" value="option3" />
          Option 3
        </label>
      </p>
    </>
  );
}
```

***

### Providing a label for an input[](#providing-a-label-for-an-input "Link for Providing a label for an input ")

Typically, you will place every `<input>` inside a [`<label>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/label) tag. This tells the browser that this label is associated with that input. When the user clicks the label, the browser will automatically focus the input. It’s also essential for accessibility: a screen reader will announce the label caption when the user focuses the associated input.

If you can’t nest `<input>` into a `<label>`, associate them by passing the same ID to `<input id>` and [`<label htmlFor>`.](https://developer.mozilla.org/en-US/docs/Web/API/HTMLLabelElement/htmlFor) To avoid conflicts between multiple instances of one component, generate such an ID with [`useId`.](/reference/react/useId)

```
import { useId } from 'react';

export default function Form() {
  const ageInputId = useId();
  return (
    <>
      <label>
        Your first name:
        <input name="firstName" />
      </label>
      <hr />
      <label htmlFor={ageInputId}>Your age:</label>
      <input id={ageInputId} name="age" type="number" />
    </>
  );
}
```

***

### Providing an initial value for an input[](#providing-an-initial-value-for-an-input "Link for Providing an initial value for an input ")

You can optionally specify the initial value for any input. Pass it as the `defaultValue` string for text inputs. Checkboxes and radio buttons should specify the initial value with the `defaultChecked` boolean instead.

```
export default function MyForm() {
  return (
    <>
      <label>
        Text input: <input name="myInput" defaultValue="Some initial value" />
      </label>
      <hr />
      <label>
        Checkbox: <input type="checkbox" name="myCheckbox" defaultChecked={true} />
      </label>
      <hr />
      <p>
        Radio buttons:
        <label>
          <input type="radio" name="myRadio" value="option1" />
          Option 1
        </label>
        <label>
          <input
            type="radio"
            name="myRadio"
            value="option2"
            defaultChecked={true} 
          />
          Option 2
        </label>
        <label>
          <input type="radio" name="myRadio" value="option3" />
          Option 3
        </label>
      </p>
    </>
  );
}
```

***

### Reading the input values when submitting a form[](#reading-the-input-values-when-submitting-a-form "Link for Reading the input values when submitting a form ")

Add a [`<form>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form) around your inputs with a [`<button type="submit">`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button) inside. It will call your `<form onSubmit>` event handler. By default, the browser will send the form data to the current URL and refresh the page. You can override that behavior by calling `e.preventDefault()`. Read the form data with [`new FormData(e.target)`](https://developer.mozilla.org/en-US/docs/Web/API/FormData).

```
export default function MyForm() {
  function handleSubmit(e) {
    // Prevent the browser from reloading the page
    e.preventDefault();

    // Read the form data
    const form = e.target;
    const formData = new FormData(form);

    // You can pass formData as a fetch body directly:
    fetch('/some-api', { method: form.method, body: formData });

    // Or you can work with it as a plain object:
    const formJson = Object.fromEntries(formData.entries());
    console.log(formJson);
  }

  return (
    <form method="post" onSubmit={handleSubmit}>
      <label>
        Text input: <input name="myInput" defaultValue="Some initial value" />
      </label>
      <hr />
      <label>
        Checkbox: <input type="checkbox" name="myCheckbox" defaultChecked={true} />
      </label>
      <hr />
      <p>
        Radio buttons:
        <label><input type="radio" name="myRadio" value="option1" /> Option 1</label>
        <label><input type="radio" name="myRadio" value="option2" defaultChecked={true} /> Option 2</label>
        <label><input type="radio" name="myRadio" value="option3" /> Option 3</label>
      </p>
      <hr />
      <button type="reset">Reset form</button>
      <button type="submit">Submit form</button>
    </form>
  );
}
```

### Note

Give a `name` to every `<input>`, for example `<input name="firstName" defaultValue="Taylor" />`. The `name` you specified will be used as a key in the form data, for example `{ firstName: "Taylor" }`.

### Pitfall

By default, *any* `<button>` inside a `<form>` will submit it. This can be surprising! If you have your own custom `Button` React component, consider returning [`<button type="button">`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/button) instead of `<button>`. Then, to be explicit, use `<button type="submit">` for buttons that *are* supposed to submit the form.

***

### Controlling an input with a state variable[](#controlling-an-input-with-a-state-variable "Link for Controlling an input with a state variable ")

An input like `<input />` is *uncontrolled.* Even if you [pass an initial value](#providing-an-initial-value-for-an-input) like `<input defaultValue="Initial text" />`, your JSX only specifies the initial value. It does not control what the value should be right now.

**To render a *controlled* input, pass the `value` prop to it (or `checked` for checkboxes and radios).** React will force the input to always have the `value` you passed. Usually, you would do this by declaring a [state variable:](/reference/react/useState)

```
function Form() {

  const [firstName, setFirstName] = useState(''); // Declare a state variable...

  // ...

  return (

    <input

      value={firstName} // ...force the input's value to match the state variable...

      onChange={e => setFirstName(e.target.value)} // ... and update the state variable on any edits!

    />

  );

}
```

A controlled input makes sense if you needed state anyway—for example, to re-render your UI on every edit:

```
function Form() {

  const [firstName, setFirstName] = useState('');

  return (

    <>

      <label>

        First name:

        <input value={firstName} onChange={e => setFirstName(e.target.value)} />

      </label>

      {firstName !== '' && <p>Your name is {firstName}.</p>}

      ...
```

It’s also useful if you want to offer multiple ways to adjust the input state (for example, by clicking a button):

```
function Form() {

  // ...

  const [age, setAge] = useState('');

  const ageAsNumber = Number(age);

  return (

    <>

      <label>

        Age:

        <input

          value={age}

          onChange={e => setAge(e.target.value)}

          type="number"

        />

        <button onClick={() => setAge(ageAsNumber + 10)}>

          Add 10 years

        </button>
```

The `value` you pass to controlled components should not be `undefined` or `null`. If you need the initial value to be empty (such as with the `firstName` field below), initialize your state variable to an empty string (`''`).

```
import { useState } from 'react';

export default function Form() {
  const [firstName, setFirstName] = useState('');
  const [age, setAge] = useState('20');
  const ageAsNumber = Number(age);
  return (
    <>
      <label>
        First name:
        <input
          value={firstName}
          onChange={e => setFirstName(e.target.value)}
        />
      </label>
      <label>
        Age:
        <input
          value={age}
          onChange={e => setAge(e.target.value)}
          type="number"
        />
        <button onClick={() => setAge(ageAsNumber + 10)}>
          Add 10 years
        </button>
      </label>
      {firstName !== '' &&
        <p>Your name is {firstName}.</p>
      }
      {ageAsNumber > 0 &&
        <p>Your age is {ageAsNumber}.</p>
      }
    </>
  );
}
```

### Pitfall

**If you pass `value` without `onChange`, it will be impossible to type into the input.** When you control an input by passing some `value` to it, you *force* it to always have the value you passed. So if you pass a state variable as a `value` but forget to update that state variable synchronously during the `onChange` event handler, React will revert the input after every keystroke back to the `value` that you specified.

***

### Optimizing re-rendering on every keystroke[](#optimizing-re-rendering-on-every-keystroke "Link for Optimizing re-rendering on every keystroke ")

When you use a controlled input, you set the state on every keystroke. If the component containing your state re-renders a large tree, this can get slow. There’s a few ways you can optimize re-rendering performance.

For example, suppose you start with a form that re-renders all page content on every keystroke:

```
function App() {

  const [firstName, setFirstName] = useState('');

  return (

    <>

      <form>

        <input value={firstName} onChange={e => setFirstName(e.target.value)} />

      </form>

      <PageContent />

    </>

  );

}
```

Since `<PageContent />` doesn’t rely on the input state, you can move the input state into its own component:

```
function App() {

  return (

    <>

      <SignupForm />

      <PageContent />

    </>

  );

}



function SignupForm() {

  const [firstName, setFirstName] = useState('');

  return (

    <form>

      <input value={firstName} onChange={e => setFirstName(e.target.value)} />

    </form>

  );

}
```

This significantly improves performance because now only `SignupForm` re-renders on every keystroke.

If there is no way to avoid re-rendering (for example, if `PageContent` depends on the search input’s value), [`useDeferredValue`](/reference/react/useDeferredValue#deferring-re-rendering-for-a-part-of-the-ui) lets you keep the controlled input responsive even in the middle of a large re-render.

***

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### My text input doesn’t update when I type into it[](#my-text-input-doesnt-update-when-i-type-into-it "Link for My text input doesn’t update when I type into it ")

If you render an input with `value` but no `onChange`, you will see an error in the console:

```
// 🔴 Bug: controlled text input with no onChange handler

<input value={something} />
```

Console

You provided a `value` prop to a form field without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultValue`. Otherwise, set either `onChange` or `readOnly`.

As the error message suggests, if you only wanted to [specify the *initial* value,](#providing-an-initial-value-for-an-input) pass `defaultValue` instead:

```
// ✅ Good: uncontrolled input with an initial value

<input defaultValue={something} />
```

If you want [to control this input with a state variable,](#controlling-an-input-with-a-state-variable) specify an `onChange` handler:

```
// ✅ Good: controlled input with onChange

<input value={something} onChange={e => setSomething(e.target.value)} />
```

If the value is intentionally read-only, add a `readOnly` prop to suppress the error:

```
// ✅ Good: readonly controlled input without on change

<input value={something} readOnly={true} />
```

***

### My checkbox doesn’t update when I click on it[](#my-checkbox-doesnt-update-when-i-click-on-it "Link for My checkbox doesn’t update when I click on it ")

If you render a checkbox with `checked` but no `onChange`, you will see an error in the console:

```
// 🔴 Bug: controlled checkbox with no onChange handler

<input type="checkbox" checked={something} />
```

Console

You provided a `checked` prop to a form field without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultChecked`. Otherwise, set either `onChange` or `readOnly`.

As the error message suggests, if you only wanted to [specify the *initial* value,](#providing-an-initial-value-for-an-input) pass `defaultChecked` instead:

```
// ✅ Good: uncontrolled checkbox with an initial value

<input type="checkbox" defaultChecked={something} />
```

If you want [to control this checkbox with a state variable,](#controlling-an-input-with-a-state-variable) specify an `onChange` handler:

```
// ✅ Good: controlled checkbox with onChange

<input type="checkbox" checked={something} onChange={e => setSomething(e.target.checked)} />
```

### Pitfall

You need to read `e.target.checked` rather than `e.target.value` for checkboxes.

If the checkbox is intentionally read-only, add a `readOnly` prop to suppress the error:

```
// ✅ Good: readonly controlled input without on change

<input type="checkbox" checked={something} readOnly={true} />
```

***

### My input caret jumps to the beginning on every keystroke[](#my-input-caret-jumps-to-the-beginning-on-every-keystroke "Link for My input caret jumps to the beginning on every keystroke ")

If you [control an input,](#controlling-an-input-with-a-state-variable) you must update its state variable to the input’s value from the DOM during `onChange`.

You can’t update it to something other than `e.target.value` (or `e.target.checked` for checkboxes):

```
function handleChange(e) {

  // 🔴 Bug: updating an input to something other than e.target.value

  setFirstName(e.target.value.toUpperCase());

}
```

You also can’t update it asynchronously:

```
function handleChange(e) {

  // 🔴 Bug: updating an input asynchronously

  setTimeout(() => {

    setFirstName(e.target.value);

  }, 100);

}
```

To fix your code, update it synchronously to `e.target.value`:

```
function handleChange(e) {

  // ✅ Updating a controlled input to e.target.value synchronously

  setFirstName(e.target.value);

}
```

If this doesn’t fix the problem, it’s possible that the input gets removed and re-added from the DOM on every keystroke. This can happen if you’re accidentally [resetting state](/learn/preserving-and-resetting-state) on every re-render, for example if the input or one of its parents always receives a different `key` attribute, or if you nest component function definitions (which is not supported and causes the “inner” component to always be considered a different tree).

***

***

----
url: https://legacy.reactjs.org/docs/error-boundaries.html
----

> These docs are old and won’t be updated. Go to [react.dev](https://react.dev/) for the new React docs.
>
> These new documentation pages teach modern React:
>
> * [`React.Component`: Catching rendering errors with an error boundary](https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary)

In the past, JavaScript errors inside components used to corrupt React’s internal state and cause it to [emit](https://github.com/facebook/react/issues/4026) [cryptic](https://github.com/facebook/react/issues/6895) [errors](https://github.com/facebook/react/issues/8579) on next renders. These errors were always caused by an earlier error in the application code, but React did not provide a way to handle them gracefully in components, and could not recover from them.

## [](#introducing-error-boundaries)Introducing Error Boundaries

A JavaScript error in a part of the UI shouldn’t break the whole app. To solve this problem for React users, React 16 introduces a new concept of an “error boundary”.

Error boundaries are React components that **catch JavaScript errors anywhere in their child component tree, log those errors, and display a fallback UI** instead of the component tree that crashed. Error boundaries catch errors during rendering, in lifecycle methods, and in constructors of the whole tree below them.

> Note
>
> Error boundaries do **not** catch errors for:
>
> * Event handlers ([learn more](#how-about-event-handlers))
> * Asynchronous code (e.g. `setTimeout` or `requestAnimationFrame` callbacks)
> * Server side rendering
> * Errors thrown in the error boundary itself (rather than its children)

A class component becomes an error boundary if it defines either (or both) of the lifecycle methods [`static getDerivedStateFromError()`](/docs/react-component.html#static-getderivedstatefromerror) or [`componentDidCatch()`](/docs/react-component.html#componentdidcatch). Use `static getDerivedStateFromError()` to render a fallback UI after an error has been thrown. Use `componentDidCatch()` to log error information.

```
class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error) {    // Update state so the next render will show the fallback UI.    return { hasError: true };  }
  componentDidCatch(error, errorInfo) {    // You can also log the error to an error reporting service    logErrorToMyService(error, errorInfo);  }
  render() {
    if (this.state.hasError) {      // You can render any custom fallback UI      return <h1>Something went wrong.</h1>;    }
    return this.props.children; 
  }
}
```

Then you can use it as a regular component:

```
<ErrorBoundary>
  <MyWidget />
</ErrorBoundary>
```

Error boundaries work like a JavaScript `catch {}` block, but for components. Only class components can be error boundaries. In practice, most of the time you’ll want to declare an error boundary component once and use it throughout your application.

Note that **error boundaries only catch errors in the components below them in the tree**. An error boundary can’t catch an error within itself. If an error boundary fails trying to render the error message, the error will propagate to the closest error boundary above it. This, too, is similar to how the `catch {}` block works in JavaScript.

## [](#live-demo)Live Demo

Check out [this example of declaring and using an error boundary](https://codepen.io/gaearon/pen/wqvxGa?editors=0010).

## [](#where-to-place-error-boundaries)Where to Place Error Boundaries

The granularity of error boundaries is up to you. You may wrap top-level route components to display a “Something went wrong” message to the user, just like how server-side frameworks often handle crashes. You may also wrap individual widgets in an error boundary to protect them from crashing the rest of the application.

If you don’t use Create React App, you can add [this plugin](https://www.npmjs.com/package/@babel/plugin-transform-react-jsx-source) manually to your Babel configuration. Note that it’s intended only for development and **must be disabled in production**.

> Note
>
> Component names displayed in the stack traces depend on the [`Function.name`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name) property. If you support older browsers and devices which may not yet provide this natively (e.g. IE 11), consider including a `Function.name` polyfill in your bundled application, such as [`function.name-polyfill`](https://github.com/JamesMGreene/Function.name). Alternatively, you may explicitly set the [`displayName`](/docs/react-component.html#displayname) property on all your components.

## [](#how-about-trycatch)How About try/catch?

`try` / `catch` is great but it only works for imperative code:

```
try {
  showButton();
} catch (error) {
  // ...
}
```

However, React components are declarative and specify *what* should be rendered:

```
<Button />
```

Error boundaries preserve the declarative nature of React, and behave as you would expect. For example, even if an error occurs in a `componentDidUpdate` method caused by a `setState` somewhere deep in the tree, it will still correctly propagate to the closest error boundary.

## [](#how-about-event-handlers)How About Event Handlers?

Error boundaries **do not** catch errors inside event handlers.

React doesn’t need error boundaries to recover from errors in event handlers. Unlike the render method and lifecycle methods, the event handlers don’t happen during rendering. So if they throw, React still knows what to display on the screen.

If you need to catch an error inside an event handler, use the regular JavaScript `try` / `catch` statement:

```
class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = { error: null };
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    try {      // Do something that could throw    } catch (error) {      this.setState({ error });    }  }

  render() {
    if (this.state.error) {      return <h1>Caught an error.</h1>    }    return <button onClick={this.handleClick}>Click Me</button>  }
}
```

Note that the above example is demonstrating regular JavaScript behavior and doesn’t use error boundaries.

## [](#naming-changes-from-react-15)Naming Changes from React 15

React 15 included a very limited support for error boundaries under a different method name: `unstable_handleError`. This method no longer works, and you will need to change it to `componentDidCatch` in your code starting from the first 16 beta release.

For this change, we’ve provided a [codemod](https://github.com/reactjs/react-codemod#error-boundaries) to automatically migrate your code.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/error-boundaries.md)

----
url: https://react.dev/reference/react/useDebugValue
----

[API Reference](/reference/react)

[Hooks](/reference/react/hooks)

# useDebugValue[](#undefined "Link for this heading")

`useDebugValue` is a React Hook that lets you add a label to a custom Hook in [React DevTools.](/learn/react-developer-tools)

```
useDebugValue(value, format?)
```

* [Reference](#reference)
  * [`useDebugValue(value, format?)`](#usedebugvalue)

* [Usage](#usage)

  * [Adding a label to a custom Hook](#adding-a-label-to-a-custom-hook)
  * [Deferring formatting of a debug value](#deferring-formatting-of-a-debug-value)

***

## Reference[](#reference "Link for Reference ")

### `useDebugValue(value, format?)`[](#usedebugvalue "Link for this heading")

Call `useDebugValue` at the top level of your [custom Hook](/learn/reusing-logic-with-custom-hooks) to display a readable debug value:

```
import { useDebugValue } from 'react';



function useOnlineStatus() {

  // ...

  useDebugValue(isOnline ? 'Online' : 'Offline');

  // ...

}
```

```
import { useDebugValue } from 'react';



function useOnlineStatus() {

  // ...

  useDebugValue(isOnline ? 'Online' : 'Offline');

  // ...

}
```

This gives components calling `useOnlineStatus` a label like `OnlineStatus: "Online"` when you inspect them:

Without the `useDebugValue` call, only the underlying data (in this example, `true`) would be displayed.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useSyncExternalStore, useDebugValue } from 'react';

export function useOnlineStatus() {
  const isOnline = useSyncExternalStore(subscribe, () => navigator.onLine, () => true);
  useDebugValue(isOnline ? 'Online' : 'Offline');
  return isOnline;
}

function subscribe(callback) {
  window.addEventListener('online', callback);
  window.addEventListener('offline', callback);
  return () => {
    window.removeEventListener('online', callback);
    window.removeEventListener('offline', callback);
  };
}
```

### Note

Don’t add debug values to every custom Hook. It’s most valuable for custom Hooks that are part of shared libraries and that have a complex internal data structure that’s difficult to inspect.

***

### Deferring formatting of a debug value[](#deferring-formatting-of-a-debug-value "Link for Deferring formatting of a debug value ")

You can also pass a formatting function as the second argument to `useDebugValue`:

```
useDebugValue(date, date => date.toDateString());
```

Your formatting function will receive the debug value as a parameter and should return a formatted display value. When your component is inspected, React DevTools will call this function and display its result.

This lets you avoid running potentially expensive formatting logic unless the component is actually inspected. For example, if `date` is a Date value, this avoids calling `toDateString()` on it for every render.

[PrevioususeContext](/reference/react/useContext)

[NextuseDeferredValue](/reference/react/useDeferredValue)

***

----
url: https://legacy.reactjs.org/docs/faq-structure.html
----

### [](#is-there-a-recommended-way-to-structure-react-projects)Is there a recommended way to structure React projects?

React doesn’t have opinions on how you put files into folders. That said there are a few common approaches popular in the ecosystem you may want to consider.

#### [](#grouping-by-features-or-routes)Grouping by features or routes

One common way to structure projects is to locate CSS, JS, and tests together inside folders grouped by feature or route.

```
common/
  Avatar.js
  Avatar.css
  APIUtils.js
  APIUtils.test.js
feed/
  index.js
  Feed.js
  Feed.css
  FeedStory.js
  FeedStory.test.js
  FeedAPI.js
profile/
  index.js
  Profile.js
  ProfileHeader.js
  ProfileHeader.css
  ProfileAPI.js
```

The definition of a “feature” is not universal, and it is up to you to choose the granularity. If you can’t come up with a list of top-level folders, you can ask the users of your product what major parts it consists of, and use their mental model as a blueprint.

#### [](#grouping-by-file-type)Grouping by file type

Another popular way to structure projects is to group similar files together, for example:

```
api/
  APIUtils.js
  APIUtils.test.js
  ProfileAPI.js
  UserAPI.js
components/
  Avatar.js
  Avatar.css
  Feed.js
  Feed.css
  FeedStory.js
  FeedStory.test.js
  Profile.js
  ProfileHeader.js
  ProfileHeader.css
```

Some people also prefer to go further, and separate components into different folders depending on their role in the application. For example, [Atomic Design](http://bradfrost.com/blog/post/atomic-web-design/) is a design methodology built on this principle. Remember that it’s often more productive to treat such methodologies as helpful examples rather than strict rules to follow.

#### [](#avoid-too-much-nesting)Avoid too much nesting

There are many pain points associated with deep directory nesting in JavaScript projects. It becomes harder to write relative imports between them, or to update those imports when the files are moved. Unless you have a very compelling reason to use a deep folder structure, consider limiting yourself to a maximum of three or four nested folders within a single project. Of course, this is only a recommendation, and it may not be relevant to your project.

#### [](#dont-overthink-it)Don’t overthink it

If you’re just starting a project, [don’t spend more than five minutes](https://en.wikipedia.org/wiki/Analysis_paralysis) on choosing a file structure. Pick any of the above approaches (or come up with your own) and start writing code! You’ll likely want to rethink it anyway after you’ve written some real code.

If you feel completely stuck, start by keeping all files in a single folder. Eventually it will grow large enough that you will want to separate some files from the rest. By that time you’ll have enough knowledge to tell which files you edit together most often. In general, it is a good idea to keep files that often change together close to each other. This principle is called “colocation”.

As projects grow larger, they often use a mix of both of the above approaches in practice. So choosing the “right” one in the beginning isn’t very important.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/faq-structure.md)

----
url: https://legacy.reactjs.org/blog/2018/03/01/sneak-peek-beyond-react-16.html
----

March 01, 2018 by [Sophie Alpert](https://sophiebits.com/)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

[Dan Abramov](https://twitter.com/dan_abramov) from our team just spoke at [JSConf Iceland 2018](https://2018.jsconf.is/) with a preview of some new features we’ve been working on in React. The talk opens with a question: “With vast differences in computing power and network speed, how do we deliver the best user experience for everyone?”

Here’s the video courtesy of JSConf Iceland:



I think you’ll enjoy the talk more if you stop reading here and just watch the video. If you don’t have time to watch, a (very) brief summary follows.

## [](#about-the-two-demos)About the Two Demos

On the first demo, Dan says: “We’ve built a generic way to ensure that high-priority updates don’t get blocked by a low-priority update, called **time slicing**. If my device is fast enough, it feels almost like it’s synchronous; if my device is slow, the app still feels responsive. It adapts to the device thanks to the [requestIdleCallback](https://developers.google.com/web/updates/2015/08/using-requestidlecallback) API. Notice that only the final state was displayed; the rendered screen is always consistent and we don’t see visual artifacts of slow rendering causing a janky user experience.”

On the second demo, Dan explains: “We’ve built a generic way for components to suspend rendering while they load async data, which we call **suspense**. You can pause any state update until the data is ready, and you can add async loading to any component deep in the tree without plumbing all the props and state through your app and hoisting the logic. On a fast network, updates appear very fluid and instantaneous without a jarring cascade of spinners that appear and disappear. On a slow network, you can intentionally design which loading states the user should see and how granular or coarse they should be, instead of showing spinners based on how the code is written. The app stays responsive throughout.”

“Importantly, this is still the React you know. This is still the declarative component paradigm that you probably like about React.”

We can’t wait to release these new async rendering features later this year. Follow this blog and [@reactjs on Twitter](https://twitter.com/reactjs) for updates.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2018-03-01-sneak-peek-beyond-react-16.md)

----
url: https://react.dev/reference/react/useLayoutEffect
----

[API Reference](/reference/react)

[Hooks](/reference/react/hooks)

# useLayoutEffect[](#undefined "Link for this heading")

### Pitfall

`useLayoutEffect` can hurt performance. Prefer [`useEffect`](/reference/react/useEffect) when possible.

`useLayoutEffect` is a version of [`useEffect`](/reference/react/useEffect) that fires before the browser repaints the screen.

```
useLayoutEffect(setup, dependencies?)
```

* [Reference](#reference)
  * [`useLayoutEffect(setup, dependencies?)`](#useinsertioneffect)
* [Usage](#usage)
  * [Measuring layout before the browser repaints the screen](#measuring-layout-before-the-browser-repaints-the-screen)
* [Troubleshooting](#troubleshooting)
  * [I’m getting an error: “`useLayoutEffect` does nothing on the server”](#im-getting-an-error-uselayouteffect-does-nothing-on-the-server)

***

## Reference[](#reference "Link for Reference ")

### `useLayoutEffect(setup, dependencies?)`[](#useinsertioneffect "Link for this heading")

Call `useLayoutEffect` to perform the layout measurements before the browser repaints the screen:

```
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);

  }, []);

  // ...
```

[See more examples below.](#usage)

#### Parameters[](#parameters "Link for Parameters ")

* `setup`: The function with your Effect’s logic. Your setup function may also optionally return a *cleanup* function. After your [component commits](/learn/render-and-commit#step-3-react-commits-changes-to-the-dom) to the DOM and before the browser repaints the screen, React will run your setup function. After every commit with changed dependencies, React will first run the cleanup function (if you provided it) with the old values, and then run your setup function with the new values. Before your component is removed from the DOM, React will run your cleanup function.

* **optional** `dependencies`: The list of all reactive values referenced inside of the `setup` code. Reactive values include props, state, and all the variables and functions declared directly inside your component body. If your linter is [configured for React](/learn/editor-setup#linting), it will verify that every reactive value is correctly specified as a dependency. The list of dependencies must have a constant number of items and be written inline like `[dep1, dep2, dep3]`. React will compare each dependency with its previous value using the [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) comparison. If you omit this argument, your Effect will re-run after every commit of the component.

***

```
function Tooltip() {

  const ref = useRef(null);

  const [tooltipHeight, setTooltipHeight] = useState(0); // You don't know real height yet



  useLayoutEffect(() => {

    const { height } = ref.current.getBoundingClientRect();

    setTooltipHeight(height); // Re-render now that you know the real height

  }, []);



  // ...use tooltipHeight in the rendering logic below...

}
```

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useRef, useLayoutEffect, useState } from 'react';
import { createPortal } from 'react-dom';
import TooltipContainer from './TooltipContainer.js';

export default function Tooltip({ children, targetRect }) {
  const ref = useRef(null);
  const [tooltipHeight, setTooltipHeight] = useState(0);

  useLayoutEffect(() => {
    const { height } = ref.current.getBoundingClientRect();
    setTooltipHeight(height);
    console.log('Measured tooltip height: ' + height);
  }, []);

  let tooltipX = 0;
  let tooltipY = 0;
  if (targetRect !== null) {
    tooltipX = targetRect.left;
    tooltipY = targetRect.top - tooltipHeight;
    if (tooltipY < 0) {
      // It doesn't fit above, so place below.
      tooltipY = targetRect.bottom;
    }
  }

  return createPortal(
    <TooltipContainer x={tooltipX} y={tooltipY} contentRef={ref}>
      {children}
    </TooltipContainer>,
    document.body
  );
}
```

Notice that even though the `Tooltip` component has to render in two passes (first, with `tooltipHeight` initialized to `0` and then with the real measured height), you only see the final result. This is why you need `useLayoutEffect` instead of [`useEffect`](/reference/react/useEffect) for this example. Let’s look at the difference in detail below.

#### useLayoutEffect vs useEffect[](#examples "Link for useLayoutEffect vs useEffect")

#### Example 1 of 2:`useLayoutEffect` blocks the browser from repainting[](#uselayouteffect-blocks-the-browser-from-repainting "Link for this heading")

React guarantees that the code inside `useLayoutEffect` and any state updates scheduled inside it will be processed **before the browser repaints the screen.** This lets you render the tooltip, measure it, and re-render the tooltip again without the user noticing the first extra render. In other words, `useLayoutEffect` blocks the browser from painting.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useRef, useLayoutEffect, useState } from 'react';
import { createPortal } from 'react-dom';
import TooltipContainer from './TooltipContainer.js';

export default function Tooltip({ children, targetRect }) {
  const ref = useRef(null);
  const [tooltipHeight, setTooltipHeight] = useState(0);

  useLayoutEffect(() => {
    const { height } = ref.current.getBoundingClientRect();
    setTooltipHeight(height);
  }, []);

  let tooltipX = 0;
  let tooltipY = 0;
  if (targetRect !== null) {
    tooltipX = targetRect.left;
    tooltipY = targetRect.top - tooltipHeight;
    if (tooltipY < 0) {
      // It doesn't fit above, so place below.
      tooltipY = targetRect.bottom;
    }
  }

  return createPortal(
    <TooltipContainer x={tooltipX} y={tooltipY} contentRef={ref}>
      {children}
    </TooltipContainer>,
    document.body
  );
}
```

### Note

Rendering in two passes and blocking the browser hurts performance. Try to avoid this when you can.

***

***

----
url: https://react.dev/reference/rules
----

[API Reference](/reference/react)

# Rules of React[](#undefined "Link for this heading")

Just as different programming languages have their own ways of expressing concepts, React has its own idioms — or rules — for how to express patterns in a way that is easy to understand and yields high-quality applications.

* [Components and Hooks must be pure](#components-and-hooks-must-be-pure)
* [React calls Components and Hooks](#react-calls-components-and-hooks)
* [Rules of Hooks](#rules-of-hooks)

***

### Note

To learn more about expressing UIs with React, we recommend reading [Thinking in React](/learn/thinking-in-react).

This section describes the rules you need to follow to write idiomatic React code. Writing idiomatic React code can help you write well organized, safe, and composable applications. These properties make your app more resilient to changes and makes it easier to work with other developers, libraries, and tools.

These rules are known as the **Rules of React**. They are rules – and not just guidelines – in the sense that if they are broken, your app likely has bugs. Your code also becomes unidiomatic and harder to understand and reason about.

We strongly recommend using [Strict Mode](/reference/react/StrictMode) alongside React’s [ESLint plugin](https://www.npmjs.com/package/eslint-plugin-react-hooks) to help your codebase follow the Rules of React. By following the Rules of React, you’ll be able to find and address these bugs and keep your application maintainable.

***

## Components and Hooks must be pure[](#components-and-hooks-must-be-pure "Link for Components and Hooks must be pure ")

[Purity in Components and Hooks](/reference/rules/components-and-hooks-must-be-pure) is a key rule of React that makes your app predictable, easy to debug, and allows React to automatically optimize your code.

* [Components must be idempotent](/reference/rules/components-and-hooks-must-be-pure#components-and-hooks-must-be-idempotent) – React components are assumed to always return the same output with respect to their inputs – props, state, and context.
* [Side effects must run outside of render](/reference/rules/components-and-hooks-must-be-pure#side-effects-must-run-outside-of-render) – Side effects should not run in render, as React can render components multiple times to create the best possible user experience.
* [Props and state are immutable](/reference/rules/components-and-hooks-must-be-pure#props-and-state-are-immutable) – A component’s props and state are immutable snapshots with respect to a single render. Never mutate them directly.
* [Return values and arguments to Hooks are immutable](/reference/rules/components-and-hooks-must-be-pure#return-values-and-arguments-to-hooks-are-immutable) – Once values are passed to a Hook, you should not modify them. Like props in JSX, values become immutable when passed to a Hook.
* [Values are immutable after being passed to JSX](/reference/rules/components-and-hooks-must-be-pure#values-are-immutable-after-being-passed-to-jsx) – Don’t mutate values after they’ve been used in JSX. Move the mutation before the JSX is created.

***

## React calls Components and Hooks[](#react-calls-components-and-hooks "Link for React calls Components and Hooks ")

[React is responsible for rendering components and hooks when necessary to optimize the user experience.](/reference/rules/react-calls-components-and-hooks) It is declarative: you tell React what to render in your component’s logic, and React will figure out how best to display it to your user.

* [Never call component functions directly](/reference/rules/react-calls-components-and-hooks#never-call-component-functions-directly) – Components should only be used in JSX. Don’t call them as regular functions.
* [Never pass around hooks as regular values](/reference/rules/react-calls-components-and-hooks#never-pass-around-hooks-as-regular-values) – Hooks should only be called inside of components. Never pass it around as a regular value.

***

## Rules of Hooks[](#rules-of-hooks "Link for Rules of Hooks ")

Hooks are defined using JavaScript functions, but they represent a special type of reusable UI logic with restrictions on where they can be called. You need to follow the [Rules of Hooks](/reference/rules/rules-of-hooks) when using them.

* [Only call Hooks at the top level](/reference/rules/rules-of-hooks#only-call-hooks-at-the-top-level) – Don’t call Hooks inside loops, conditions, or nested functions. Instead, always use Hooks at the top level of your React function, before any early returns.
* [Only call Hooks from React functions](/reference/rules/rules-of-hooks#only-call-hooks-from-react-functions) – Don’t call Hooks from regular JavaScript functions.

[NextComponents and Hooks must be pure](/reference/rules/components-and-hooks-must-be-pure)

***

----
url: https://legacy.reactjs.org/docs/testing.html
----

You can test React components similar to testing other JavaScript code.

There are a few ways to test React components. Broadly, they divide into two categories:

* **Rendering component trees** in a simplified test environment and asserting on their output.
* **Running a complete app** in a realistic browser environment (also known as “end-to-end” tests).

This documentation section focuses on testing strategies for the first case. While full end-to-end tests can be very useful to prevent regressions to important workflows, such tests are not concerned with React components in particular, and are out of the scope of this section.

### [](#tradeoffs)Tradeoffs

When choosing testing tools, it is worth considering a few tradeoffs:

* **Iteration speed vs Realistic environment:** Some tools offer a very quick feedback loop between making a change and seeing the result, but don’t model the browser behavior precisely. Other tools might use a real browser environment, but reduce the iteration speed and are flakier on a continuous integration server.
* **How much to mock:** With components, the distinction between a “unit” and “integration” test can be blurry. If you’re testing a form, should its test also test the buttons inside of it? Or should a button component have its own test suite? Should refactoring a button ever break the form test?

Different answers may work for different teams and products.

### [](#tools)Recommended Tools

**[Jest](https://facebook.github.io/jest/)** is a JavaScript test runner that lets you access the DOM via [`jsdom`](/docs/testing-environments.html#mocking-a-rendering-surface). While jsdom is only an approximation of how the browser works, it is often good enough for testing React components. Jest provides a great iteration speed combined with powerful features like mocking [modules](/docs/testing-environments.html#mocking-modules) and [timers](/docs/testing-environments.html#mocking-timers) so you can have more control over how the code executes.

**[React Testing Library](https://testing-library.com/react)** is a set of helpers that let you test React components without relying on their implementation details. This approach makes refactoring a breeze and also nudges you towards best practices for accessibility. Although it doesn’t provide a way to “shallowly” render a component without its children, a test runner like Jest lets you do this by [mocking](/docs/testing-recipes.html#mocking-modules).

### [](#learn-more)Learn More

This section is divided in two pages:

* [Recipes](/docs/testing-recipes.html): Common patterns when writing tests for React components.
* [Environments](/docs/testing-environments.html): What to consider when setting up a testing environment for React components.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/testing.md)

*

* Next article

  [Testing Recipes](/docs/testing-recipes.html)

----
url: https://legacy.reactjs.org/docs/faq-ajax.html
----

### [](#how-can-i-make-an-ajax-call)How can I make an AJAX call?

You can use any AJAX library you like with React. Some popular ones are [Axios](https://github.com/axios/axios), [jQuery AJAX](https://api.jquery.com/jQuery.ajax/), and the browser built-in [window.fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API).

### [](#where-in-the-component-lifecycle-should-i-make-an-ajax-call)Where in the component lifecycle should I make an AJAX call?

You should populate data with AJAX calls in the [`componentDidMount`](/docs/react-component.html#mounting) lifecycle method. This is so you can use `setState` to update your component when the data is retrieved.

### [](#example-using-ajax-results-to-set-local-state)Example: Using AJAX results to set local state

The component below demonstrates how to make an AJAX call in `componentDidMount` to populate local component state.

The example API returns a JSON object like this:

```
{
  "items": [
    { "id": 1, "name": "Apples",  "price": "$2" },
    { "id": 2, "name": "Peaches", "price": "$5" }
  ] 
}
```

```
class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      error: null,
      isLoaded: false,
      items: []
    };
  }

  componentDidMount() {
    fetch("https://api.example.com/items")
      .then(res => res.json())
      .then(
        (result) => {
          this.setState({
            isLoaded: true,
            items: result.items
          });
        },
        // Note: it's important to handle errors here
        // instead of a catch() block so that we don't swallow
        // exceptions from actual bugs in components.
        (error) => {
          this.setState({
            isLoaded: true,
            error
          });
        }
      )
  }

  render() {
    const { error, isLoaded, items } = this.state;
    if (error) {
      return <div>Error: {error.message}</div>;
    } else if (!isLoaded) {
      return <div>Loading...</div>;
    } else {
      return (
        <ul>
          {items.map(item => (
            <li key={item.id}>
              {item.name} {item.price}
            </li>
          ))}
        </ul>
      );
    }
  }
}
```

Here is the equivalent with [Hooks](https://reactjs.org/docs/hooks-intro.html):

```
function MyComponent() {
  const [error, setError] = useState(null);
  const [isLoaded, setIsLoaded] = useState(false);
  const [items, setItems] = useState([]);

  // Note: the empty deps array [] means
  // this useEffect will run once
  // similar to componentDidMount()
  useEffect(() => {
    fetch("https://api.example.com/items")
      .then(res => res.json())
      .then(
        (result) => {
          setIsLoaded(true);
          setItems(result);
        },
        // Note: it's important to handle errors here
        // instead of a catch() block so that we don't swallow
        // exceptions from actual bugs in components.
        (error) => {
          setIsLoaded(true);
          setError(error);
        }
      )
  }, [])

  if (error) {
    return <div>Error: {error.message}</div>;
  } else if (!isLoaded) {
    return <div>Loading...</div>;
  } else {
    return (
      <ul>
        {items.map(item => (
          <li key={item.id}>
            {item.name} {item.price}
          </li>
        ))}
      </ul>
    );
  }
}
```

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/faq-ajax.md)

----
url: https://react.dev/reference/dev-tools/react-performance-tracks
----

[API Reference](/reference/react)

# React Performance tracks[](#undefined "Link for this heading")

React Performance tracks are specialized custom entries that appear on the Performance panel’s timeline in your browser developer tools.

These tracks are designed to provide developers with comprehensive insights into their React application’s performance by visualizing React-specific events and metrics alongside other critical data sources such as network requests, JavaScript execution, and event loop activity, all synchronized on a unified timeline within the Performance panel for a complete understanding of application behavior.

* [Usage](#usage)
  * [Using profiling builds](#using-profiling-builds)

* [Tracks](#tracks)

  * [Scheduler](#scheduler)
  * [Components](#components)
  * [Server](#server)

***

## Usage[](#usage "Link for Usage ")

React Performance tracks are only available in development and profiling builds of React:

* **Development**: enabled by default.
* **Profiling**: Only Scheduler tracks are enabled by default. The Components track only lists Components that are in subtrees wrapped with [`<Profiler>`](/reference/react/Profiler). If you have [React Developer Tools extension](/learn/react-developer-tools) enabled, all Components are included in the Components track even if they’re not wrapped in `<Profiler>`. Server tracks are not available in profiling builds.

If enabled, tracks should appear automatically in the traces you record with the Performance panel of browsers that provide [extensibility APIs](https://developer.chrome.com/docs/devtools/performance/extension).

### Pitfall

The profiling instrumentation that powers React Performance tracks adds some additional overhead, so it is disabled in production builds by default. Server Components and Server Requests tracks are only available in development builds.

### Using profiling builds[](#using-profiling-builds "Link for Using profiling builds ")

In addition to production and development builds, React also includes a special profiling build. To use profiling builds, you have to use `react-dom/profiling` instead of `react-dom/client`. We recommend that you alias `react-dom/client` to `react-dom/profiling` at build time via bundler aliases instead of manually updating each `react-dom/client` import. Your framework might have built-in support for enabling React’s profiling build.

***

## Tracks[](#tracks "Link for Tracks ")

### Scheduler[](#scheduler "Link for Scheduler ")

The Scheduler is an internal React concept used for managing tasks with different priorities. This track consists of 4 subtracks, each representing work of a specific priority:

* **Blocking** - The synchronous updates, which could’ve been initiated by user interactions.
* **Transition** - Non-blocking work that happens in the background, usually initiated via [`startTransition`](/reference/react/startTransition).
* **Suspense** - Work related to Suspense boundaries, such as displaying fallbacks or revealing content.
* **Idle** - The lowest priority work that is done when there are no other tasks with higher priority.

#### Renders[](#renders "Link for Renders ")

Every render pass consists of multiple phases that you can see on a timeline:

* **Update** - this is what caused a new render pass.
* **Render** - React renders the updated subtree by calling render functions of components. You can see the rendered components subtree on [Components track](#components), which follows the same color scheme.
* **Commit** - After rendering components, React will submit the changes to the DOM and run layout effects, like [`useLayoutEffect`](/reference/react/useLayoutEffect).
* **Remaining Effects** - React runs passive effects of a rendered subtree. This usually happens after the paint, and this is when React runs hooks like [`useEffect`](/reference/react/useEffect). One known exception is user interactions, like clicks, or other discrete events. In this scenario, this phase could run before the paint.

[Learn more about renders and commits](/learn/render-and-commit).

#### Cascading updates[](#cascading-updates "Link for Cascading updates ")

Cascading updates is one of the patterns for performance regressions. If an update was scheduled during a render pass, React could discard completed work and start a new pass.

In development builds, React can show you which Component scheduled a new update. This includes both general updates and cascading ones. You can see the enhanced stack trace by clicking on the “Cascading update” entry, which should also display the name of the method that scheduled an update.

[Learn more about Effects](/learn/you-might-not-need-an-effect).

### Components[](#components "Link for Components ")

The Components track visualizes the durations of React components. They are displayed as a flamegraph, where each entry represents the duration of the corresponding component render and all its descendant children components.

Similar to render durations, effect durations are also represented as a flamegraph, but with a different color scheme that aligns with the corresponding phase on the Scheduler track.

### Note

Unlike renders, not all effects are shown on the Components track by default.

To maintain performance and prevent UI clutter, React will only display those effects, which had a duration of 0.05ms or longer, or triggered an update.

Additional events may be displayed during the render and effects phases:

* Mount - A corresponding subtree of component renders or effects was mounted.
* Unmount - A corresponding subtree of component renders or effects was unmounted.
* Reconnect - Similar to Mount, but limited to cases when [`<Activity>`](/reference/react/Activity) is used.
* Disconnect - Similar to Unmount, but limited to cases when [`<Activity>`](/reference/react/Activity) is used.

#### Changed props[](#changed-props "Link for Changed props ")

In development builds, when you click on a component render entry, you can inspect potential changes in props. You can use this information to identify unnecessary renders.

### Server[](#server "Link for Server ")

#### Server Requests[](#server-requests "Link for Server Requests ")

The Server Requests track visualized all Promises that eventually end up in a React Server Component. This includes any `async` operations like calling `fetch` or async Node.js file operations.

React will try to combine Promises that are started from inside third-party code into a single span representing the the duration of the entire operation blocking 1st party code. For example, a third party library method called `getUser` that calls `fetch` internally multiple times will be represented as a single span called `getUser`, instead of showing multiple `fetch` spans.

Clicking on spans will show you a stack trace of where the Promise was created as well as a view of the value that the Promise resolved to, if available.

Rejected Promises are displayed as red with their rejected value.

#### Server Components[](#server-components "Link for Server Components ")

The Server Components tracks visualize the durations of React Server Components Promises they awaited. Timings are displayed as a flamegraph, where each entry represents the duration of the corresponding component render and all its descendant children components.

If you await a Promise, React will display duration of that Promise. To see all I/O operations, use the Server Requests track.

Different colors are used to indicate the duration of the component render. The darker the color, the longer the duration.

The Server Components track group will always contain a “Primary” track. If React is able to render Server Components concurrently, it will display addititional “Parallel” tracks. If more than 8 Server Components are rendered concurrently, React will associate them with the last “Parallel” track instead of adding more tracks.

***

----
url: https://18.react.dev/reference/react/useId
----

[API Reference](/reference/react)

[Hooks](/reference/react/hooks)

# useId[](#undefined "Link for this heading")

`useId` is a React Hook for generating unique IDs that can be passed to accessibility attributes.

```
const id = useId()
```

***

## Reference[](#reference "Link for Reference ")

### `useId()`[](#useid "Link for this heading")

Call `useId` at the top level of your component to generate a unique ID:

```
import { useId } from 'react';



function PasswordField() {

  const passwordHintId = useId();

  // ...
```

* `useId` **should not be used to generate keys** in a list. [Keys should be generated from your data.](/learn/rendering-lists#where-to-get-your-key)

***

## Usage[](#usage "Link for Usage ")

### Pitfall

**Do not call `useId` to generate keys in a list.** [Keys should be generated from your data.](/learn/rendering-lists#where-to-get-your-key)

### Generating unique IDs for accessibility attributes[](#generating-unique-ids-for-accessibility-attributes "Link for Generating unique IDs for accessibility attributes ")

Call `useId` at the top level of your component to generate a unique ID:

```
import { useId } from 'react';



function PasswordField() {

  const passwordHintId = useId();

  // ...
```

You can then pass the generated ID to different attributes:

```
<>

  <input type="password" aria-describedby={passwordHintId} />

  <p id={passwordHintId}>

</>
```

**Let’s walk through an example to see when this is useful.**

[HTML accessibility attributes](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA) like [`aria-describedby`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-describedby) let you specify that two tags are related to each other. For example, you can specify that an element (like an input) is described by another element (like a paragraph).

In regular HTML, you would write it like this:

```
<label>

  Password:

  <input

    type="password"

    aria-describedby="password-hint"

  />

</label>

<p id="password-hint">

  The password should contain at least 18 characters

</p>
```

However, hardcoding IDs like this is not a good practice in React. A component may be rendered more than once on the page—but IDs have to be unique! Instead of hardcoding an ID, generate a unique ID with `useId`:

```
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>

    </>

  );

}
```

Now, even if `PasswordField` appears multiple times on the screen, the generated IDs won’t clash.

```
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>
    </>
  );
}

export default function App() {
  return (
    <>
      <h2>Choose password</h2>
      <PasswordField />
      <h2>Confirm password</h2>
      <PasswordField />
    </>
  );
}
```

***

### Generating IDs for several related elements[](#generating-ids-for-several-related-elements "Link for Generating IDs for several related elements ")

If you need to give IDs to multiple related elements, you can call `useId` to generate a shared prefix for them:

```
import { useId } from 'react';

export default function Form() {
  const id = useId();
  return (
    <form>
      <label htmlFor={id + '-firstName'}>First Name:</label>
      <input id={id + '-firstName'} type="text" />
      <hr />
      <label htmlFor={id + '-lastName'}>Last Name:</label>
      <input id={id + '-lastName'} type="text" />
    </form>
  );
}
```

This lets you avoid calling `useId` for every single element that needs a unique ID.

***

### Specifying a shared prefix for all generated IDs[](#specifying-a-shared-prefix-for-all-generated-ids "Link for Specifying a shared prefix for all generated IDs ")

If you render multiple independent React applications on a single page, pass `identifierPrefix` as an option to your [`createRoot`](/reference/react-dom/client/createRoot#parameters) or [`hydrateRoot`](/reference/react-dom/client/hydrateRoot) calls. This ensures that the IDs generated by the two different apps never clash because every identifier generated with `useId` will start with the distinct prefix you’ve specified.

```
import { createRoot } from 'react-dom/client';
import App from './App.js';
import './styles.css';

const root1 = createRoot(document.getElementById('root1'), {
  identifierPrefix: 'my-first-app-'
});
root1.render(<App />);

const root2 = createRoot(document.getElementById('root2'), {
  identifierPrefix: 'my-second-app-'
});
root2.render(<App />);
```

***

### Using the same ID prefix on the client and the server[](#using-the-same-id-prefix-on-the-client-and-the-server "Link for Using the same ID prefix on the client and the server ")

If you [render multiple independent React apps on the same page](#specifying-a-shared-prefix-for-all-generated-ids), and some of these apps are server-rendered, make sure that the `identifierPrefix` you pass to the [`hydrateRoot`](/reference/react-dom/client/hydrateRoot) call on the client side is the same as the `identifierPrefix` you pass to the [server APIs](/reference/react-dom/server) such as [`renderToPipeableStream`.](/reference/react-dom/server/renderToPipeableStream)

```
// Server

import { renderToPipeableStream } from 'react-dom/server';



const { pipe } = renderToPipeableStream(

  <App />,

  { identifierPrefix: 'react-app1' }

);
```

```
// Client

import { hydrateRoot } from 'react-dom/client';



const domNode = document.getElementById('root');

const root = hydrateRoot(

  domNode,

  reactNode,

  { identifierPrefix: 'react-app1' }

);
```

You do not need to pass `identifierPrefix` if you only have one React app on the page.

[PrevioususeEffect](/reference/react/useEffect)

[NextuseImperativeHandle](/reference/react/useImperativeHandle)

***

----
url: https://legacy.reactjs.org/docs/javascript-environment-requirements.html
----

React 18 supports all modern browsers (Edge, Firefox, Chrome, Safari, etc).

If you support older browsers and devices such as Internet Explorer which do not provide modern browser features natively or have non-compliant implementations, consider including a global polyfill in your bundled application.

Here is a list of the modern features React 18 uses:

* [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)
* [`Symbol`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol)
* [`Object.assign`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)

The correct polyfill for these features depend on your environment. For many users, you can configure your [Browserlist](https://github.com/browserslist/browserslist) settings. For others, you may need to import polyfills like [`core-js`](https://github.com/zloirock/core-js) directly.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/reference-javascript-environment-requirements.md)

----
url: https://legacy.reactjs.org/docs/concurrent-mode-adoption.html
----

> Caution:
>
> This page is **severely outdated** and only exists for historical purposes.
>
> React 18 was released with support for concurrency. However, **there is no “mode” anymore,** and the new behavior is fully opt-in and only enabled [when you use the new features](https://reactjs.org/blog/2022/03/29/react-v18.html#gradually-adopting-concurrent-features).
>
> **For up-to-date high-level information, refer to:**
>
> * [React 18 Announcement](https://reactjs.org/blog/2022/03/29/react-v18.html)
> * [Upgrading to React 18](https://reactjs.org/blog/2022/03/08/react-18-upgrade-guide.html)
> * [React Conf 2021 Videos](https://reactjs.org/blog/2021/12/17/react-conf-2021-recap.html)
>
> **For details about concurrent APIs in React 18, refer to:**
>
> * [`React.Suspense`](https://reactjs.org/docs/react-api.html#reactsuspense) reference
> * [`React.startTransition`](https://reactjs.org/docs/react-api.html#starttransition) reference
> * [`React.useTransition`](https://reactjs.org/docs/hooks-reference.html#usetransition) reference
> * [`React.useDeferredValue`](https://reactjs.org/docs/hooks-reference.html#usedeferredvalue) reference
>
> The rest of this page includes content that’s stale, broken, or incorrect.

* [Installation](#installation)

  * [Who Is This Experimental Release For?](#who-is-this-experimental-release-for)
  * [Enabling Concurrent Mode](#enabling-concurrent-mode)

* [What to Expect](#what-to-expect)

  * [Migration Step: Blocking Mode](#migration-step-blocking-mode)
  * [Why So Many Modes?](#why-so-many-modes)
  * [Feature Comparison](#feature-comparison)

## [](#installation)Installation

Concurrent Mode is only available in the [experimental builds](/blog/2019/10/22/react-release-channels.html#experimental-channel) of React. To install them, run:

```
npm install react@experimental react-dom@experimental
```

**There are no semantic versioning guarantees for the experimental builds.**\
APIs may be added, changed, or removed with any `@experimental` release.

**Experimental releases will have frequent breaking changes.**

You can try these builds on personal projects or in a branch, but we don’t recommend running them in production. At Facebook, we *do* run them in production, but that’s because we’re also there to fix bugs when something breaks. You’ve been warned!

### [](#who-is-this-experimental-release-for)Who Is This Experimental Release For?

This release is primarily aimed at early adopters, library authors, and curious people.

We’re using this code in production (and it works for us) but there are still some bugs, missing features, and gaps in the documentation. We’d like to hear more about what breaks in Concurrent Mode so we can better prepare it for an official stable release in the future.

### [](#enabling-concurrent-mode)Enabling Concurrent Mode

> Caution:
>
> This explanation is outdated. The strategy of a separate “mode” was abandoned in React 18. Instead, concurrent rendering is only enabled when you use concurrent features.

Normally, when we add features to React, you can start using them immediately. Fragments, Context, and even Hooks are examples of such features. You can use them in new code without making any changes to the existing code.

Concurrent Mode is different. It introduces semantic changes to how React works. Otherwise, the [new features](/docs/concurrent-mode-patterns.html) enabled by it *wouldn’t be possible*. This is why they’re grouped into a new “mode” rather than released one by one in isolation.

You can’t opt into Concurrent Mode on a per-subtree basis. Instead, to opt in, you have to do it in the place where today you call `ReactDOM.render()`.

**This will enable Concurrent Mode for the whole `<App />` tree:**

```
import ReactDOM from 'react-dom';

// If you previously had:
//
// ReactDOM.render(<App />, document.getElementById('root'));
//
// You can opt into Concurrent Mode by writing:

ReactDOM.unstable_createRoot(
  document.getElementById('root')
).render(<App />);
```

> Note:
>
> Concurrent Mode APIs such as `createRoot` only exist in the experimental builds of React.

In Concurrent Mode, the lifecycle methods [previously marked](/blog/2018/03/27/update-on-async-rendering.html) as “unsafe” actually *are* unsafe, and lead to bugs even more than in today’s React. We don’t recommend trying Concurrent Mode until your app is [Strict Mode](/docs/strict-mode.html)-compatible.

## [](#what-to-expect)What to Expect

> Caution:
>
> This explanation is outdated. The strategy of a separate “mode” was abandoned in React 18. Instead, concurrent rendering is only enabled when you use concurrent features.

If you have a large existing app, or if your app depends on a lot of third-party packages, please don’t expect that you can use the Concurrent Mode immediately. **For example, at Facebook we are using Concurrent Mode for the new website, but we’re not planning to enable it on the old website.** This is because our old website still uses unsafe lifecycle methods in the product code, incompatible third-party libraries, and patterns that don’t work well with the Concurrent Mode.

In our experience, code that uses idiomatic React patterns and doesn’t rely on external state management solutions is the easiest to get running in the Concurrent Mode. We will describe common problems we’ve seen and the solutions to them separately in the coming weeks.

### [](#migration-step-blocking-mode)Migration Step: Blocking Mode

> Caution:
>
> This explanation is outdated. The strategy of a separate “mode” was abandoned in React 18. Instead, concurrent rendering is only enabled when you use concurrent features.

For older codebases, Concurrent Mode might be a step too far. This is why we also provide a new “Blocking Mode” in the experimental React builds. You can try it by substituting `createRoot` with `createBlockingRoot`. It only offers a *small subset* of the Concurrent Mode features, but it is closer to how React works today and can serve as a migration step.

To recap:

* **Legacy Mode:** `ReactDOM.render(<App />, rootNode)`. This is what React apps use today. There are no plans to remove the legacy mode in the observable future — but it won’t be able to support these new features.
* **Blocking Mode:** `ReactDOM.createBlockingRoot(rootNode).render(<App />)`. It is currently experimental. It is intended as a first migration step for apps that want to get a subset of Concurrent Mode features.
* **Concurrent Mode:** `ReactDOM.createRoot(rootNode).render(<App />)`. It is currently experimental. In the future, after it stabilizes, we intend to make it the default React mode. This mode enables *all* the new features.

### [](#why-so-many-modes)Why So Many Modes?

> Caution:
>
> This explanation is outdated. The strategy of a separate “mode” was abandoned in React 18. Instead, concurrent rendering is only enabled when you use concurrent features.

We think it is better to offer a [gradual migration strategy](/docs/faq-versioning.html#commitment-to-stability) than to make huge breaking changes — or to let React stagnate into irrelevance.

In practice, we expect that most apps using Legacy Mode today should be able to migrate at least to the Blocking Mode (if not Concurrent Mode). This fragmentation can be annoying for libraries that aim to support all Modes in the short term. However, gradually moving the ecosystem away from the Legacy Mode will also *solve* problems that affect major libraries in the React ecosystem, such as [confusing Suspense behavior when reading layout](https://github.com/facebook/react/issues/14536) and [lack of consistent batching guarantees](https://github.com/facebook/react/issues/15080). There’s a number of bugs that can’t be fixed in Legacy Mode without changing semantics, but don’t exist in Blocking and Concurrent Modes.

You can think of the Blocking Mode as a “gracefully degraded” version of the Concurrent Mode. **As a result, in longer term we should be able to converge and stop thinking about different Modes altogether.** But for now, Modes are an important migration strategy. They let everyone decide when a migration is worth it, and upgrade at their own pace.

### [](#feature-comparison)Feature Comparison

> Caution:
>
> This explanation is outdated. The strategy of a separate “mode” was abandoned in React 18. Instead, concurrent rendering is only enabled when you use concurrent features.

|                                                                                                       | Legacy Mode | Blocking Mode | Concurrent Mode |
| ----------------------------------------------------------------------------------------------------- | ----------- | ------------- | --------------- |
| [String Refs](/docs/refs-and-the-dom.html#legacy-api-string-refs)                                     | ✅           | 🚫\*\*        | 🚫\*\*          |
| [Legacy Context](/docs/legacy-context.html)                                                           | ✅           | 🚫\*\*        | 🚫\*\*          |
| [findDOMNode](/docs/strict-mode.html#warning-about-deprecated-finddomnode-usage)                      | ✅           | 🚫\*\*        | 🚫\*\*          |
| [Suspense](/docs/concurrent-mode-suspense.html#what-is-suspense-exactly)                              | ✅           | ✅             | ✅               |
| [SuspenseList](/docs/concurrent-mode-patterns.html#suspenselist)                                      | 🚫          | ✅             | ✅               |
| Suspense SSR + Hydration                                                                              | 🚫          | ✅             | ✅               |
| Progressive Hydration                                                                                 | 🚫          | ✅             | ✅               |
| Selective Hydration                                                                                   | 🚫          | 🚫            | ✅               |
| Cooperative Multitasking                                                                              | 🚫          | 🚫            | ✅               |
| Automatic batching of multiple setStates                                                              | 🚫\*        | ✅             | ✅               |
| [Priority-based Rendering](/docs/concurrent-mode-patterns.html#splitting-high-and-low-priority-state) | 🚫          | 🚫            | ✅               |
| [Interruptible Prerendering](/docs/concurrent-mode-intro.html#interruptible-rendering)                | 🚫          | 🚫            | ✅               |
| [useTransition](/docs/concurrent-mode-patterns.html#transitions)                                      | 🚫          | 🚫            | ✅               |
| [useDeferredValue](/docs/concurrent-mode-patterns.html#deferring-a-value)                             | 🚫          | 🚫            | ✅               |
| [Suspense Reveal “Train”](/docs/concurrent-mode-patterns.html#suspense-reveal-train)                  | 🚫          | 🚫            | ✅               |

\*: Legacy mode has automatic batching in React-managed events but it’s limited to one browser task. Non-React events must opt-in using `unstable_batchedUpdates`. In Blocking Mode and Concurrent Mode, all `setState`s are batched by default.

\*\*: Warns in development.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/concurrent-mode-adoption.md)

----
url: https://react.dev/community/videos
----

[Community](/community)

# React Videos[](#undefined "Link for this heading")

Videos dedicated to the discussion of React and the React ecosystem.

## React Conf 2024[](#react-conf-2024 "Link for React Conf 2024 ")

At React Conf 2024, Meta CTO [Andrew “Boz” Bosworth](https://www.threads.net/@boztank) shared a welcome message to kick off the conference:

### React 19 Keynote[](#react-19-keynote "Link for React 19 Keynote ")

In the Day 1 keynote, we shared vision for React starting with React 19 and the React Compiler. Watch the full keynote from [Joe Savona](https://twitter.com/en_JS), [Lauren Tan](https://twitter.com/potetotes), [Andrew Clark](https://twitter.com/acdlite), [Josh Story](https://twitter.com/joshcstory), [Sathya Gunasekaran](https://twitter.com/_gsathya), and [Mofei Zhang](https://twitter.com/zmofei):

### React Unpacked: A Roadmap to React 19[](#react-unpacked-a-roadmap-to-react-19 "Link for React Unpacked: A Roadmap to React 19 ")

React 19 introduced new features including Actions, `use()`, `useOptimistic` and more. For a deep dive on using new features in React 19, see [Sam Selikoff’s](https://twitter.com/samselikoff) talk:

### What’s New in React 19[](#whats-new-in-react-19 "Link for What’s New in React 19 ")

[Lydia Hallie](https://twitter.com/lydiahallie) gave a visual deep dive of React 19’s new features:

### React 19 Deep Dive: Coordinating HTML[](#react-19-deep-dive-coordinating-html "Link for React 19 Deep Dive: Coordinating HTML ")

[Josh Story](https://twitter.com/joshcstory) provided a deep dive on the document and resource streaming APIs in React 19:

### React for Two Computers[](#react-for-two-computers "Link for React for Two Computers ")

[Dan Abramov](https://bsky.app/profile/danabra.mov) imagined an alternate history where React started server-first:

### Forget About Memo[](#forget-about-memo "Link for Forget About Memo ")

[Lauren Tan](https://twitter.com/potetotes) gave a talk on using the React Compiler in practice:

### React Compiler Deep Dive[](#react-compiler-deep-dive "Link for React Compiler Deep Dive ")

[Sathya Gunasekaran](https://twitter.com/_gsathya) and [Mofei Zhang](https://twitter.com/zmofei) provided a deep dive on how the React Compiler works:

### And more…[](#and-more-2024 "Link for And more… ")

**We also heard talks from the community on Server Components:**

* [Enhancing Forms with React Server Components](https://www.youtube.com/embed/0ckOUBiuxVY\&t=25280s) by [Aurora Walberg Scharff](https://twitter.com/aurorascharff)
* [And Now You Understand React Server Components](https://www.youtube.com/embed/pOo7x8OiAec) by [Kent C. Dodds](https://twitter.com/kentcdodds)
* [Real-time Server Components](https://www.youtube.com/embed/6sMANTHWtLM) by [Sunil Pai](https://twitter.com/threepointone)

**Talks from React frameworks using new features:**

* [Vanilla React](https://www.youtube.com/embed/ZcwA0xt8FlQ) by [Ryan Florence](https://twitter.com/ryanflorence)
* [React Rhythm & Blues](https://www.youtube.com/embed/rs9X5MjvC4s) by [Lee Robinson](https://twitter.com/leeerob)
* [RedwoodJS, now with React Server Components](https://www.youtube.com/embed/sjyY4MTECUU) by [Amy Dutton](https://twitter.com/selfteachme)
* [Introducing Universal React Server Components in Expo Router](https://www.youtube.com/embed/djhEgxQf3Kw) by [Evan Bacon](https://twitter.com/Baconbrix)

**And Q\&As with the React and React Native teams:**

* [React Q\&A](https://www.youtube.com/embed/T8TZQ6k4SLE\&t=27518s) hosted by [Michael Chan](https://twitter.com/chantastic)
* [React Native Q\&A](https://www.youtube.com/embed/0ckOUBiuxVY\&t=27935s) hosted by [Jamon Holmgren](https://twitter.com/jamonholmgren)

You can watch all of the talks at React Conf 2024 at [conf2024.react.dev](https://conf2024.react.dev/talks).

***

----
url: https://react.dev/learn/add-react-to-an-existing-project
----

1. **Build the React part of your app** using one of the [React-based frameworks](/learn/creating-a-react-app).
2. **Specify `/some-app` as the *base path*** in your framework’s configuration (here’s how: [Next.js](https://nextjs.org/docs/app/api-reference/config/next-config-js/basePath), [Gatsby](https://www.gatsbyjs.com/docs/how-to/previews-deploys-hosting/path-prefix/)).
3. **Configure your server or a proxy** so that all requests under `/some-app/` are handled by your React app.

This ensures the React part of your app can [benefit from the best practices](/learn/build-a-react-app-from-scratch#consider-using-a-framework) baked into those frameworks.

* **If your app doesn’t have an existing setup for compiling JavaScript modules,** set it up with [Vite](https://vite.dev/). The Vite community maintains [many integrations with backend frameworks](https://github.com/vitejs/awesome-vite#integrations-with-backends), including Rails, Django, and Laravel. If your backend framework is not listed, [follow this guide](https://vite.dev/guide/backend-integration.html) to manually integrate Vite builds with your backend.

To check whether your setup works, run this command in your project folder:

Terminal

```
npm install react react-dom
```

Then add these lines of code at the top of your main JavaScript file (it might be called `index.js` or `main.js`):

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { createRoot } from 'react-dom/client';

// Clear the existing HTML content
document.body.innerHTML = '<div id="app"></div>';

// Render your React component instead
const root = createRoot(document.getElementById('app'));
root.render(<h1>Hello, world</h1>);
```

If the entire content of your page was replaced by a “Hello, world!”, everything worked! Keep reading.

### Note

Integrating a modular JavaScript environment into an existing project for the first time can feel intimidating, but it’s worth it! If you get stuck, try our [community resources](/community) or the [Vite Chat](https://chat.vite.dev/).

### Step 2: Render React components anywhere on the page[](#step-2-render-react-components-anywhere-on-the-page "Link for Step 2: Render React components anywhere on the page ")

In the previous step, you put this code at the top of your main file:

```
import { createRoot } from 'react-dom/client';



// Clear the existing HTML content

document.body.innerHTML = '<div id="app"></div>';



// Render your React component instead

const root = createRoot(document.getElementById('app'));

root.render(<h1>Hello, world</h1>);
```

Of course, you don’t actually want to clear the existing HTML content!

Delete this code.

Instead, you probably want to render your React components in specific places in your HTML. Open your HTML page (or the server templates that generate it) and add a unique [`id`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/id) attribute to any tag, for example:

```
<!-- ... somewhere in your html ... -->

<nav id="navigation"></nav>

<!-- ... more html ... -->
```

This lets you find that HTML element with [`document.getElementById`](https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementById) and pass it to [`createRoot`](/reference/react-dom/client/createRoot) so that you can render your own React component inside:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { createRoot } from 'react-dom/client';

function NavigationBar() {
  // TODO: Actually implement a navigation bar
  return <h1>Hello from React!</h1>;
}

const domNode = document.getElementById('navigation');
const root = createRoot(domNode);
root.render(<NavigationBar />);
```

Notice how the original HTML content from `index.html` is preserved, but your own `NavigationBar` React component now appears inside the `<nav id="navigation">` from your HTML. Read the [`createRoot` usage documentation](/reference/react-dom/client/createRoot#rendering-a-page-partially-built-with-react) to learn more about rendering React components inside an existing HTML page.

When you adopt React in an existing project, it’s common to start with small interactive components (like buttons), and then gradually keep “moving upwards” until eventually your entire page is built with React. If you ever reach that point, we recommend migrating to [a React framework](/learn/creating-a-react-app) right after to get the most out of React.

## Using React Native in an existing native mobile app[](#using-react-native-in-an-existing-native-mobile-app "Link for Using React Native in an existing native mobile app ")

[React Native](https://reactnative.dev/) can also be integrated into existing native apps incrementally. If you have an existing native app for Android (Java or Kotlin) or iOS (Objective-C or Swift), [follow this guide](https://reactnative.dev/docs/integration-with-existing-apps) to add a React Native screen to it.

[PreviousBuild a React App from Scratch](/learn/build-a-react-app-from-scratch)

[NextSetup](/learn/setup)

***

----
url: https://react.dev/reference/react
----

React DOM contains features that are only supported for web applications (which run in the browser DOM environment). This section is broken into the following:

* [Hooks](/reference/react-dom/hooks) - Hooks for web applications which run in the browser DOM environment.
* [Components](/reference/react-dom/components) - React supports all of the browser built-in HTML and SVG components.
* [APIs](/reference/react-dom) - The `react-dom` package contains methods supported only in web applications.
* [Client APIs](/reference/react-dom/client) - The `react-dom/client` APIs let you render React components on the client (in the browser).
* [Server APIs](/reference/react-dom/server) - The `react-dom/server` APIs let you render React components to HTML on the server.
* [Static APIs](/reference/react-dom/static) - The `react-dom/static` APIs let you generate static HTML for React components.

## React Compiler[](#react-compiler "Link for React Compiler ")

The React Compiler is a build-time optimization tool that automatically memoizes your React components and values:

* [Configuration](/reference/react-compiler/configuration) - Configuration options for React Compiler.
* [Directives](/reference/react-compiler/directives) - Function-level directives to control compilation.
* [Compiling Libraries](/reference/react-compiler/compiling-libraries) - Guide for shipping pre-compiled library code.

## ESLint Plugin React Hooks[](#eslint-plugin-react-hooks "Link for ESLint Plugin React Hooks ")

The [ESLint plugin for React Hooks](/reference/eslint-plugin-react-hooks) helps enforce the Rules of React:

* [Lints](/reference/eslint-plugin-react-hooks) - Detailed documentation for each lint with examples.

***

----
url: https://18.react.dev/reference/rules/components-and-hooks-must-be-pure
----

*Rendering* refers to calculating what the next version of your UI should look like. After rendering, [Effects](/reference/react/useEffect) are *flushed* (meaning they are run until there are no more left) and may update the calculation if the Effects have impacts on layout. React takes this new calculation and compares it to the calculation used to create the previous version of your UI, then *commits* just the minimum changes needed to the [DOM](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model) (what your user actually sees) to catch it up to the latest version.

##### Deep Dive#### How to tell if code runs in render[](#how-to-tell-if-code-runs-in-render "Link for How to tell if code runs in render ")

One quick heuristic to tell if code runs during render is to examine where it is: if it’s written at the top level like in the example below, there’s a good chance it runs during render.

```
function Dropdown() {

  const selectedItems = new Set(); // created during render

  // ...

}
```

Event handlers and Effects don’t run in render:

```
function Dropdown() {

  const selectedItems = new Set();

  const onSelect = (item) => {

    // this code is in an event handler, so it's only run when the user triggers this

    selectedItems.add(item);

  }

}
```

```
function Dropdown() {

  const selectedItems = new Set();

  useEffect(() => {

    // this code is inside of an Effect, so it only runs after rendering

    logForAnalytics(selectedItems);

  }, [selectedItems]);

}
```

***

## Components and Hooks must be idempotent[](#components-and-hooks-must-be-idempotent "Link for Components and Hooks must be idempotent ")

Components must always return the same output with respect to their inputs – props, state, and context. This is known as *idempotency*. [Idempotency](https://en.wikipedia.org/wiki/Idempotence) is a term popularized in functional programming. It refers to the idea that you [always get the same result every time](/learn/keeping-components-pure) you run that piece of code with the same inputs.

This means that *all* code that runs [during render](#how-does-react-run-your-code) must also be idempotent in order for this rule to hold. For example, this line of code is not idempotent (and therefore, neither is the component):

```
function Clock() {

  const time = new Date(); // 🔴 Bad: always returns a different result!

  return <span>{time.toLocaleString()}</span>

}
```

`new Date()` is not idempotent as it always returns the current date and changes its result every time it’s called. When you render the above component, the time displayed on the screen will stay stuck on the time that the component was rendered. Similarly, functions like `Math.random()` also aren’t idempotent, because they return different results every time they’re called, even when the inputs are the same.

This doesn’t mean you shouldn’t use non-idempotent functions like `new Date()` *at all* – you should just avoid using them [during render](#how-does-react-run-your-code). In this case, we can *synchronize* the latest date to this component using an [Effect](/reference/react/useEffect):

```
import { useState, useEffect } from 'react';

function useTime() {
  // 1. Keep track of the current date's state. `useState` receives an initializer function as its
  //    initial state. It only runs once when the hook is called, so only the current date at the
  //    time the hook is called is set first.
  const [time, setTime] = useState(() => new Date());

  useEffect(() => {
    // 2. Update the current date every second using `setInterval`.
    const id = setInterval(() => {
      setTime(new Date()); // ✅ Good: non-idempotent code no longer runs in render
    }, 1000);
    // 3. Return a cleanup function so we don't leak the `setInterval` timer.
    return () => clearInterval(id);
  }, []);

  return time;
}

export default function Clock() {
  const time = useTime();
  return <span>{time.toLocaleString()}</span>;
}
```

By wrapping the non-idempotent `new Date()` call in an Effect, it moves that calculation [outside of rendering](#how-does-react-run-your-code).

If you don’t need to synchronize some external state with React, you can also consider using an [event handler](/learn/responding-to-events) if it only needs to be updated in response to a user interaction.

***

```
function FriendList({ friends }) {

  const items = []; // ✅ Good: locally created

  for (let i = 0; i < friends.length; i++) {

    const friend = friends[i];

    items.push(

      <Friend key={friend.id} friend={friend} />

    ); // ✅ Good: local mutation is okay

  }

  return <section>{items}</section>;

}
```

There is no need to contort your code to avoid local mutation. [`Array.map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) could also be used here for brevity, but there is nothing wrong with creating a local array and then pushing items into it [during render](#how-does-react-run-your-code).

Even though it looks like we are mutating `items`, the key point to note is that this code only does so *locally* – the mutation isn’t “remembered” when the component is rendered again. In other words, `items` only stays around as long as the component does. Because `items` is always *recreated* every time `<FriendList />` is rendered, the component will always return the same result.

On the other hand, if `items` was created outside of the component, it holds on to its previous values and remembers changes:

```
const items = []; // 🔴 Bad: created outside of the component

function FriendList({ friends }) {

  for (let i = 0; i < friends.length; i++) {

    const friend = friends[i];

    items.push(

      <Friend key={friend.id} friend={friend} />

    ); // 🔴 Bad: mutates a value created outside of render

  }

  return <section>{items}</section>;

}
```

When `<FriendList />` runs again, we will continue appending `friends` to `items` every time that component is run, leading to multiple duplicated results. This version of `<FriendList />` has observable side effects [during render](#how-does-react-run-your-code) and **breaks the rule**.

#### Lazy initialization[](#lazy-initialization "Link for Lazy initialization ")

Lazy initialization is also fine despite not being fully “pure”:

```
function ExpenseForm() {

  SuperCalculator.initializeIfNotReady(); // ✅ Good: if it doesn't affect other components

  // Continue rendering...

}
```

#### Changing the DOM[](#changing-the-dom "Link for Changing the DOM ")

Side effects that are directly visible to the user are not allowed in the render logic of React components. In other words, merely calling a component function shouldn’t by itself produce a change on the screen.

```
function ProductDetailPage({ product }) {

  document.title = product.title; // 🔴 Bad: Changes the DOM

}
```

One way to achieve the desired result of updating `document.title` outside of render is to [synchronize the component with `document`](/learn/synchronizing-with-effects).

As long as calling a component multiple times is safe and doesn’t affect the rendering of other components, React doesn’t care if it’s 100% pure in the strict functional programming sense of the word. It is more important that [components must be idempotent](/reference/rules/components-and-hooks-must-be-pure).

***

## Props and state are immutable[](#props-and-state-are-immutable "Link for Props and state are immutable ")

A component’s props and state are immutable [snapshots](/learn/state-as-a-snapshot). Never mutate them directly. Instead, pass new props down, and use the setter function from `useState`.

You can think of the props and state values as snapshots that are updated after rendering. For this reason, you don’t modify the props or state variables directly: instead you pass new props, or use the setter function provided to you to tell React that state needs to update the next time the component is rendered.

### Don’t mutate Props[](#props "Link for Don’t mutate Props ")

Props are immutable because if you mutate them, the application will produce inconsistent output, which can be hard to debug since it may or may not work depending on the circumstance.

```
function Post({ item }) {

  item.url = new Url(item.url, base); // 🔴 Bad: never mutate props directly

  return <Link url={item.url}>{item.title}</Link>;

}
```

```
function Post({ item }) {

  const url = new Url(item.url, base); // ✅ Good: make a copy instead

  return <Link url={url}>{item.title}</Link>;

}
```

### Don’t mutate State[](#state "Link for Don’t mutate State ")

`useState` returns the state variable and a setter to update that state.

```
const [stateVariable, setter] = useState(0);
```

Rather than updating the state variable in-place, we need to update it using the setter function that is returned by `useState`. Changing values on the state variable doesn’t cause the component to update, leaving your users with an outdated UI. Using the setter function informs React that the state has changed, and that we need to queue a re-render to update the UI.

```
function Counter() {

  const [count, setCount] = useState(0);



  function handleClick() {

    count = count + 1; // 🔴 Bad: never mutate state directly

  }



  return (

    <button onClick={handleClick}>

      You pressed me {count} times

    </button>

  );

}
```

```
function Counter() {

  const [count, setCount] = useState(0);



  function handleClick() {

    setCount(count + 1); // ✅ Good: use the setter function returned by useState

  }



  return (

    <button onClick={handleClick}>

      You pressed me {count} times

    </button>

  );

}
```

***

## Return values and arguments to Hooks are immutable[](#return-values-and-arguments-to-hooks-are-immutable "Link for Return values and arguments to Hooks are immutable ")

Once values are passed to a hook, you should not modify them. Like props in JSX, values become immutable when passed to a hook.

```
function useIconStyle(icon) {

  const theme = useContext(ThemeContext);

  if (icon.enabled) {

    icon.className = computeStyle(icon, theme); // 🔴 Bad: never mutate hook arguments directly

  }

  return icon;

}
```

```
function useIconStyle(icon) {

  const theme = useContext(ThemeContext);

  const newIcon = { ...icon }; // ✅ Good: make a copy instead

  if (icon.enabled) {

    newIcon.className = computeStyle(icon, theme);

  }

  return newIcon;

}
```

One important principle in React is *local reasoning*: the ability to understand what a component or hook does by looking at its code in isolation. Hooks should be treated like “black boxes” when they are called. For example, a custom hook might have used its arguments as dependencies to memoize values inside it:

```
function useIconStyle(icon) {

  const theme = useContext(ThemeContext);



  return useMemo(() => {

    const newIcon = { ...icon };

    if (icon.enabled) {

      newIcon.className = computeStyle(icon, theme);

    }

    return newIcon;

  }, [icon, theme]);

}
```

If you were to mutate the Hooks arguments, the custom hook’s memoization will become incorrect, so it’s important to avoid doing that.

```
style = useIconStyle(icon);         // `style` is memoized based on `icon`

icon.enabled = false;               // Bad: 🔴 never mutate hook arguments directly

style = useIconStyle(icon);         // previously memoized result is returned
```

```
style = useIconStyle(icon);         // `style` is memoized based on `icon`

icon = { ...icon, enabled: false }; // Good: ✅ make a copy instead

style = useIconStyle(icon);         // new value of `style` is calculated
```

Similarly, it’s important to not modify the return values of Hooks, as they may have been memoized.

***

## Values are immutable after being passed to JSX[](#values-are-immutable-after-being-passed-to-jsx "Link for Values are immutable after being passed to JSX ")

Don’t mutate values after they’ve been used in JSX. Move the mutation before the JSX is created.

When you use JSX in an expression, React may eagerly evaluate the JSX before the component finishes rendering. This means that mutating values after they’ve been passed to JSX can lead to outdated UIs, as React won’t know to update the component’s output.

```
function Page({ colour }) {

  const styles = { colour, size: "large" };

  const header = <Header styles={styles} />;

  styles.size = "small"; // 🔴 Bad: styles was already used in the JSX above

  const footer = <Footer styles={styles} />;

  return (

    <>

      {header}

      <Content />

      {footer}

    </>

  );

}
```

```
function Page({ colour }) {

  const headerStyles = { colour, size: "large" };

  const header = <Header styles={headerStyles} />;

  const footerStyles = { colour, size: "small" }; // ✅ Good: we created a new value

  const footer = <Footer styles={footerStyles} />;

  return (

    <>

      {header}

      <Content />

      {footer}

    </>

  );

}
```

[PreviousOverview](/reference/rules)

[NextReact calls Components and Hooks](/reference/rules/react-calls-components-and-hooks)

***

----
url: https://legacy.reactjs.org/blog/2022/03/08/react-18-upgrade-guide.html
----

March 08, 2022 by [Rick Hanlon](https://twitter.com/rickhanlonii)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

As we shared in the [release post](/blog/2022/03/29/react-v18.html), React 18 introduces features powered by our new concurrent renderer, with a gradual adoption strategy for existing applications. In this post, we will guide you through the steps for upgrading to React 18.

Please [report any issues](https://github.com/facebook/react/issues/new/choose) you encounter while upgrading to React 18.

*Note for React Native users: React 18 will ship in a future version of React Native. This is because React 18 relies on the New React Native Architecture to benefit from the new capabilities presented in this blogpost. For more information, see the [React Conf keynote here](https://www.youtube.com/watch?v=FZ0cG47msEk\&t=1530s).*

## [](#installing)Installing

To install the latest version of React:

```
npm install react react-dom
```

Or if you’re using yarn:

```
yarn add react react-dom
```

## [](#updates-to-client-rendering-apis)Updates to Client Rendering APIs

When you first install React 18, you will see a warning in the console:

> ReactDOM.render is no longer supported in React 18. Use createRoot instead. Until you switch to the new API, your app will behave as if it’s running React 17. Learn more: <https://reactjs.org/link/switch-to-createroot>

React 18 introduces a new root API which provides better ergonomics for managing roots. The new root API also enables the new concurrent renderer, which allows you to opt-into concurrent features.

```
// Before
import { render } from 'react-dom';
const container = document.getElementById('app');
render(<App tab="home" />, container);

// After
import { createRoot } from 'react-dom/client';
const container = document.getElementById('app');
const root = createRoot(container); // createRoot(container!) if you use TypeScript
root.render(<App tab="home" />);
```

We’ve also changed `unmountComponentAtNode` to `root.unmount`:

```
// Before
unmountComponentAtNode(container);

// After
root.unmount();
```

We’ve also removed the callback from render, since it usually does not have the expected result when using Suspense:

```
// Before
const container = document.getElementById('app');
render(<App tab="home" />, container, () => {
  console.log('rendered');
});

// After
function AppWithCallbackAfterRender() {
  useEffect(() => {
    console.log('rendered');
  });

  return <App tab="home" />
}

const container = document.getElementById('app');
const root = createRoot(container);
root.render(<AppWithCallbackAfterRender />);
```

> Note:
>
> There is no one-to-one replacement for the old render callback API — it depends on your use case. See the working group post for [Replacing render with createRoot](https://github.com/reactwg/react-18/discussions/5) for more information.

Finally, if your app uses server-side rendering with hydration, upgrade `hydrate` to `hydrateRoot`:

```
// Before
import { hydrate } from 'react-dom';
const container = document.getElementById('app');
hydrate(<App tab="home" />, container);

// After
import { hydrateRoot } from 'react-dom/client';
const container = document.getElementById('app');
const root = hydrateRoot(container, <App tab="home" />);
// Unlike with createRoot, you don't need a separate root.render() call here.
```

For more information, see the [working group discussion here](https://github.com/reactwg/react-18/discussions/5).

> Note
>
> **If your app doesn’t work after upgrading, check whether it’s wrapped in `<StrictMode>`.** [Strict Mode has gotten stricter in React 18](#updates-to-strict-mode), and not all your components may be resilient to the new checks it adds in development mode. If removing Strict Mode fixes your app, you can remove it during the upgrade, and then add it back (either at the top or for a part of the tree) after you fix the issues that it’s pointing out.

## [](#updates-to-server-rendering-apis)Updates to Server Rendering APIs

## [](#updates-to-typescript-definitions)Updates to TypeScript definitions

If your project uses TypeScript, you will need to update your `@types/react` and `@types/react-dom` dependencies to the latest versions. The new types are safer and catch issues that used to be ignored by the type checker. The most notable change is that the `children` prop now needs to be listed explicitly when defining props, for example:

```
interface MyButtonProps {
  color: string;
  children?: React.ReactNode;}
```

See the [React 18 typings pull request](https://github.com/DefinitelyTyped/DefinitelyTyped/pull/56210) for a full list of type-only changes. It links to example fixes in library types so you can see how to adjust your code. You can use the [automated migration script](https://github.com/eps1lon/types-react-codemod) to help port your application code to the new and safer typings faster.

If you find a bug in the typings, please [file an issue](https://github.com/DefinitelyTyped/DefinitelyTyped/discussions/new?category=issues-with-a-types-package) in the DefinitelyTyped repo.

## [](#automatic-batching)Automatic Batching

React 18 adds out-of-the-box performance improvements by doing more batching by default. Batching is when React groups multiple state updates into a single re-render for better performance. Before React 18, we only batched updates inside React event handlers. Updates inside of promises, setTimeout, native event handlers, or any other event were not batched in React by default:

```
// Before React 18 only React events were batched

function handleClick() {
  setCount(c => c + 1);
  setFlag(f => !f);
  // React will only re-render once at the end (that's batching!)
}

setTimeout(() => {
  setCount(c => c + 1);
  setFlag(f => !f);
  // React will render twice, once for each state update (no batching)
}, 1000);
```

Starting in React 18 with `createRoot`, all updates will be automatically batched, no matter where they originate from. This means that updates inside of timeouts, promises, native event handlers or any other event will batch the same way as updates inside of React events:

```
// After React 18 updates inside of timeouts, promises,
// native event handlers or any other event are batched.

function handleClick() {
  setCount(c => c + 1);
  setFlag(f => !f);
  // React will only re-render once at the end (that's batching!)
}

setTimeout(() => {
  setCount(c => c + 1);
  setFlag(f => !f);
  // React will only re-render once at the end (that's batching!)
}, 1000);
```

This is a breaking change, but we expect this to result in less work rendering, and therefore better performance in your applications. To opt-out of automatic batching, you can use `flushSync`:

```
import { flushSync } from 'react-dom';

function handleClick() {
  flushSync(() => {
    setCounter(c => c + 1);
  });
  // React has updated the DOM by now
  flushSync(() => {
    setFlag(f => !f);
  });
  // React has updated the DOM by now
}
```

For more information, see the [Automatic batching deep dive](https://github.com/reactwg/react-18/discussions/21).

## [](#new-apis-for-libraries)New APIs for Libraries

In the React 18 Working Group we worked with library maintainers to create new APIs needed to support concurrent rendering for use cases specific to their use case in areas like styles, and external stores. To support React 18, some libraries may need to switch to one of the following APIs:

* `useSyncExternalStore` is a new hook that allows external stores to support concurrent reads by forcing updates to the store to be synchronous. This new API is recommended for any library that integrates with state external to React. For more information, see the [useSyncExternalStore overview post](https://github.com/reactwg/react-18/discussions/70) and [useSyncExternalStore API details](https://github.com/reactwg/react-18/discussions/86).
* `useInsertionEffect` is a new hook that allows CSS-in-JS libraries to address performance issues of injecting styles in render. Unless you’ve already built a CSS-in-JS library we don’t expect you to ever use this. This hook will run after the DOM is mutated, but before layout effects read the new layout. This solves an issue that already exists in React 17 and below, but is even more important in React 18 because React yields to the browser during concurrent rendering, giving it a chance to recalculate layout. For more information, see the [Library Upgrade Guide for `<style>`](https://github.com/reactwg/react-18/discussions/110).

React 18 also introduces new APIs for concurrent rendering such as `startTransition`, `useDeferredValue` and `useId`, which we share more about in the [release post](/blog/2022/03/29/react-v18.html).

## [](#updates-to-strict-mode)Updates to Strict Mode

In the future, we’d like to add a feature that allows React to add and remove sections of the UI while preserving state. For example, when a user tabs away from a screen and back, React should be able to immediately show the previous screen. To do this, React would unmount and remount trees using the same component state as before.

This feature will give React better performance out-of-the-box, but requires components to be resilient to effects being mounted and destroyed multiple times. Most effects will work without any changes, but some effects assume they are only mounted or destroyed once.

To help surface these issues, React 18 introduces a new development-only check to Strict Mode. This new check will automatically unmount and remount every component, whenever a component mounts for the first time, restoring the previous state on the second mount.

Before this change, React would mount the component and create the effects:

```
* React mounts the component.
    * Layout effects are created.
    * Effect effects are created.
```

With Strict Mode in React 18, React will simulate unmounting and remounting the component in development mode:

```
* React mounts the component.
    * Layout effects are created.
    * Effect effects are created.
* React simulates unmounting the component.
    * Layout effects are destroyed.
    * Effects are destroyed.
* React simulates mounting the component with the previous state.
    * Layout effect setup code runs
    * Effect setup code runs
```

For more information, see the Working Group posts for [Adding Reusable State to StrictMode](https://github.com/reactwg/react-18/discussions/19) and [How to support Reusable State in Effects](https://github.com/reactwg/react-18/discussions/18).

## [](#configuring-your-testing-environment)Configuring Your Testing Environment

When you first update your tests to use `createRoot`, you may see this warning in your test console:

> The current testing environment is not configured to support act(…)

To fix this, set `globalThis.IS_REACT_ACT_ENVIRONMENT` to `true` before running your test:

```
// In your test setup file
globalThis.IS_REACT_ACT_ENVIRONMENT = true;
```

The purpose of the flag is to tell React that it’s running in a unit test-like environment. React will log helpful warnings if you forget to wrap an update with `act`.

You can also set the flag to `false` to tell React that `act` isn’t needed. This can be useful for end-to-end tests that simulate a full browser environment.

Eventually, we expect testing libraries will configure this for you automatically. For example, the [next version of React Testing Library has built-in support for React 18](https://github.com/testing-library/react-testing-library/issues/509#issuecomment-917989936) without any additional configuration.

[More background on the `act` testing API and related changes](https://github.com/reactwg/react-18/discussions/102) is available in the working group.

## [](#dropping-support-for-internet-explorer)Dropping Support for Internet Explorer

In this release, React is dropping support for Internet Explorer, which is [going out of support on June 15, 2022](https://blogs.windows.com/windowsexperience/2021/05/19/the-future-of-internet-explorer-on-windows-10-is-in-microsoft-edge). We’re making this change now because new features introduced in React 18 are built using modern browser features such as microtasks which cannot be adequately polyfilled in IE.

If you need to support Internet Explorer we recommend you stay with React 17.

## [](#deprecations)Deprecations

* `react-dom`: `ReactDOM.render` has been deprecated. Using it will warn and run your app in React 17 mode.
* `react-dom`: `ReactDOM.hydrate` has been deprecated. Using it will warn and run your app in React 17 mode.
* `react-dom`: `ReactDOM.unmountComponentAtNode` has been deprecated.
* `react-dom`: `ReactDOM.renderSubtreeIntoContainer` has been deprecated.
* `react-dom/server`: `ReactDOMServer.renderToNodeStream` has been deprecated.

## [](#other-breaking-changes)Other Breaking Changes

* **Consistent useEffect timing**: React now always synchronously flushes effect functions if the update was triggered during a discrete user input event such as a click or a keydown event. Previously, the behavior wasn’t always predictable or consistent.
* **Stricter hydration errors**: Hydration mismatches due to missing or extra text content are now treated like errors instead of warnings. React will no longer attempt to “patch up” individual nodes by inserting or deleting a node on the client in an attempt to match the server markup, and will revert to client rendering up to the closest `<Suspense>` boundary in the tree. This ensures the hydrated tree is consistent and avoids potential privacy and security holes that can be caused by hydration mismatches.
* **Suspense trees are always consistent:** If a component suspends before it’s fully added to the tree, React will not add it to the tree in an incomplete state or fire its effects. Instead, React will throw away the new tree completely, wait for the asynchronous operation to finish, and then retry rendering again from scratch. React will render the retry attempt concurrently, and without blocking the browser.
* **Layout Effects with Suspense**: When a tree re-suspends and reverts to a fallback, React will now clean up layout effects, and then re-create them when the content inside the boundary is shown again. This fixes an issue which prevented component libraries from correctly measuring layout when used with Suspense.
* **New JS Environment Requirements**: React now depends on modern browsers features including `Promise`, `Symbol`, and `Object.assign`. If you support older browsers and devices such as Internet Explorer which do not provide modern browser features natively or have non-compliant implementations, consider including a global polyfill in your bundled application.

## [](#other-notable-changes)Other Notable Changes

### [](#react)React

* **Components can now render `undefined`:** React no longer warns if you return `undefined` from a component. This makes the allowed component return values consistent with values that are allowed in the middle of a component tree. We suggest to use a linter to prevent mistakes like forgetting a `return` statement before JSX.
* **In tests, `act` warnings are now opt-in:** If you’re running end-to-end tests, the `act` warnings are unnecessary. We’ve introduced an [opt-in](https://github.com/reactwg/react-18/discussions/102) mechanism so you can enable them only for unit tests where they are useful and beneficial.
* **No warning about `setState` on unmounted components:** Previously, React warned about memory leaks when you call `setState` on an unmounted component. This warning was added for subscriptions, but people primarily run into it in scenarios where setting state is fine, and workarounds make the code worse. We’ve [removed](https://github.com/facebook/react/pull/22114) this warning.
* **No suppression of console logs:** When you use Strict Mode, React renders each component twice to help you find unexpected side effects. In React 17, we’ve suppressed console logs for one of the two renders to make the logs easier to read. In response to [community feedback](https://github.com/facebook/react/issues/21783) about this being confusing, we’ve removed the suppression. Instead, if you have React DevTools installed, the second log’s renders will be displayed in grey, and there will be an option (off by default) to suppress them completely.
* **Improved memory usage:** React now cleans up more internal fields on unmount, making the impact from unfixed memory leaks that may exist in your application code less severe.

### [](#react-dom-server)React DOM Server

* **`renderToString`:** Will no longer error when suspending on the server. Instead, it will emit the fallback HTML for the closest `<Suspense>` boundary and then retry rendering the same content on the client. It is still recommended that you switch to a streaming API like `renderToPipeableStream` or `renderToReadableStream` instead.
* **`renderToStaticMarkup`:** Will no longer error when suspending on the server. Instead, it will emit the fallback HTML for the closest `<Suspense>` boundary.

## [](#changelog)Changelog

You can view the [full changelog here](https://github.com/facebook/react/blob/main/CHANGELOG.md).

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2022-03-08-react-18-upgrade-guide.md)

----
url: https://legacy.reactjs.org/blog/2016/11/16/react-v15.4.0.html
----

November 16, 2016 by [Dan Abramov](https://twitter.com/dan_abramov)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

Today we are releasing React 15.4.0.

We didn’t announce the [previous](https://github.com/facebook/react/blob/main/CHANGELOG.md#1510-may-20-2016) [minor](https://github.com/facebook/react/blob/main/CHANGELOG.md#1520-july-1-2016) [releases](https://github.com/facebook/react/blob/main/CHANGELOG.md#1530-july-29-2016) on the blog because most of the changes were bug fixes. However, 15.4.0 is a special release, and we would like to highlight a few notable changes in it.

### [](#separating-react-and-react-dom)Separating React and React DOM

[More than a year ago](/blog/2015/09/10/react-v0.14-rc1.html#two-packages-react-and-react-dom), we started separating React and React DOM into separate packages. We deprecated `React.render()` in favor of `ReactDOM.render()` in React 0.14, and removed DOM-specific APIs from `React` completely in React 15. However, the React DOM implementation still [secretly lived inside the React package](https://www.reddit.com/r/javascript/comments/3m6wyu/found_this_line_in_the_react_codebase_made_me/cvcyo4a/).

In React 15.4.0, we are finally moving React DOM implementation to the React DOM package. The React package will now contain only the renderer-agnostic code such as `React.Component` and `React.createElement()`.

This solves a few long-standing issues, such as [errors](https://github.com/facebook/react/issues/7386) when you import React DOM in the same file as the [snapshot testing](https://facebook.github.io/jest/blog/2016/07/27/jest-14.html) renderer.

**If you only use the official and documented React APIs you won’t need to change anything in your application.**

However, there is a possibility that you imported private APIs from `react/lib/*`, or that a package you rely on might use them. We would like to remind you that this was never supported, and that your apps should not rely on internal APIs. The React internals will keep changing as we work to make React better.

Another thing to watch out for is that React DOM Server is now about the same size as React DOM since it contains its own copy of the React reconciler. We don’t recommend using React DOM Server on the client in most cases.

### [](#profiling-components-with-chrome-timeline)Profiling Components with Chrome Timeline

You can now visualize React components in the Chrome Timeline. This lets you see which components exactly get mounted, updated, and unmounted, how much time they take relative to each other.

[](/static/64d522b74fb585f1abada9801f85fa9d/1ac66/react-perf-chrome-timeline.png)

To use it:

1. Load your app with `?react_perf` in the query string (for example, `http://localhost:3000/?react_perf`).
2. Open the Chrome DevTools **Timeline** tab and press **Record**.
3. Perform the actions you want to profile. Don’t record more than 20 seconds or Chrome might hang.
4. Stop recording.
5. React events will be grouped under the **User Timing** label.

Note that the numbers are relative so components will render faster in production. Still, this should help you realize when unrelated UI gets updated by mistake, and how deep and how often your UI updates occur.

Currently Chrome, Edge, and IE are the only browsers supporting this feature, but we use the standard [User Timing API](https://developer.mozilla.org/en-US/docs/Web/API/User_Timing_API) so we expect more browsers to add support for it.

### [](#mocking-refs-for-snapshot-testing)Mocking Refs for Snapshot Testing

If you’re using Jest [snapshot testing](https://facebook.github.io/jest/blog/2016/07/27/jest-14.html), you might have had [issues](https://github.com/facebook/react/issues/7371) with components that rely on refs. With React 15.4.0, we introduce a way to provide mock refs to the test renderer. For example, consider this component using a ref in `componentDidMount`:

```
import React from 'react';

export default class MyInput extends React.Component {
  componentDidMount() {
    this.input.focus();  }

  render() {
    return (
      <input
        ref={node => this.input = node}      />
    );
  }
}
```

With snapshot renderer, `this.input` will be `null` because there is no DOM. React 15.4.0 lets us avoid such crashes by passing a custom `createNodeMock` function to the snapshot renderer in an `options` argument:

```
import React from 'react';
import MyInput from './MyInput';
import renderer from 'react-test-renderer';

function createNodeMock(element) {  if (element.type === 'input') {    return {      focus() {},    };  }  return null;}
it('renders correctly', () => {
  const options = {createNodeMock};
  const tree = renderer.create(<MyInput />, options);  expect(tree).toMatchSnapshot();
});
```

We would like to thank [Brandon Dail](https://github.com/Aweary) for implementing this feature.

You can learn more about snapshot testing in [this Jest blog post](https://facebook.github.io/jest/blog/2016/07/27/jest-14.html).

***

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

## [](#installation)Installation

We recommend using [Yarn](https://yarnpkg.com/) or [npm](https://www.npmjs.com/) for managing front-end dependencies. If you’re new to package managers, the [Yarn documentation](https://yarnpkg.com/en/docs/getting-started) is a good place to get started.

To install React with Yarn, run:

```
yarn add react@15.4.0 react-dom@15.4.0
```

To install React with npm, run:

```
npm install --save react@15.4.0 react-dom@15.4.0
```

We recommend using a bundler like [webpack](https://webpack.js.org/) or [Browserify](http://browserify.org/) so you can write modular code and bundle it together into small packages to optimize load time.

Remember that by default, React runs extra checks and provides helpful warnings in development mode. When deploying your app, make sure to [compile it in production mode](/docs/installation.html#development-and-production-versions).

In case you don’t use a bundler, we also provide pre-built bundles in the npm packages which you can [include as script tags](/docs/installation.html#using-a-cdn) on your page:

* **React**\
  Dev build with warnings: [react/dist/react.js](https://unpkg.com/react@15.4.0/dist/react.js)\
  Minified build for production: [react/dist/react.min.js](https://unpkg.com/react@15.4.0/dist/react.min.js)
* **React with Add-Ons**\
  Dev build with warnings: [react/dist/react-with-addons.js](https://unpkg.com/react@15.4.0/dist/react-with-addons.js)\
  Minified build for production: [react/dist/react-with-addons.min.js](https://unpkg.com/react@15.4.0/dist/react-with-addons.min.js)
* **React DOM** (include React in the page before React DOM)\
  Dev build with warnings: [react-dom/dist/react-dom.js](https://unpkg.com/react-dom@15.4.0/dist/react-dom.js)\
  Minified build for production: [react-dom/dist/react-dom.min.js](https://unpkg.com/react-dom@15.4.0/dist/react-dom.min.js)
* **React DOM Server** (include React in the page before React DOM Server)\
  Dev build with warnings: [react-dom/dist/react-dom-server.js](https://unpkg.com/react-dom@15.4.0/dist/react-dom-server.js)\
  Minified build for production: [react-dom/dist/react-dom-server.min.js](https://unpkg.com/react-dom@15.4.0/dist/react-dom-server.min.js)

We’ve also published version `15.4.0` of the `react`, `react-dom`, and addons packages on npm and the `react` package on bower.

***

## [](#changelog)Changelog

### [](#react)React

* React package and browser build no longer “secretly” includes React DOM.\
  ([@sebmarkbage](https://github.com/sebmarkbage) in [#7164](https://github.com/facebook/react/pull/7164) and [#7168](https://github.com/facebook/react/pull/7168))
* Required PropTypes now fail with specific messages for null and undefined.\
  ([@chenglou](https://github.com/chenglou) in [#7291](https://github.com/facebook/react/pull/7291))
* Improved development performance by freezing children instead of copying.\
  ([@keyanzhang](https://github.com/keyanzhang) in [#7455](https://github.com/facebook/react/pull/7455))

### [](#react-dom)React DOM

* Fixed occasional test failures when React DOM is used together with shallow renderer.\
  ([@goatslacker](https://github.com/goatslacker) in [#8097](https://github.com/facebook/react/pull/8097))
* Added a warning for invalid `aria-` attributes.\
  ([@jessebeach](https://github.com/jessebeach) in [#7744](https://github.com/facebook/react/pull/7744))
* Added a warning for using `autofocus` rather than `autoFocus`.\
  ([@hkal](https://github.com/hkal) in [#7694](https://github.com/facebook/react/pull/7694))
* Removed an unnecessary warning about polyfilling `String.prototype.split`.\
  ([@nhunzaker](https://github.com/nhunzaker) in [#7629](https://github.com/facebook/react/pull/7629))
* Clarified the warning about not calling PropTypes manually.\
  ([@jedwards1211](https://github.com/jedwards1211) in [#7777](https://github.com/facebook/react/pull/7777))
* The unstable `batchedUpdates` API now passes the wrapped function’s return value through.\
  ([@bgnorlov](https://github.com/bgnorlov) in [#7444](https://github.com/facebook/react/pull/7444))
* Fixed a bug with updating text in IE 8.\
  ([@mnpenner](https://github.com/mnpenner) in [#7832](https://github.com/facebook/react/pull/7832))

### [](#react-perf)React Perf

* When ReactPerf is started, you can now view the relative time spent in components as a chart in Chrome Timeline.\
  ([@gaearon](https://github.com/gaearon) in [#7549](https://github.com/facebook/react/pull/7549))

### [](#react-test-utils)React Test Utils

* If you call `Simulate.click()` on a `<input disabled onClick={foo} />` then `foo` will get called whereas it didn’t before.\
  ([@nhunzaker](https://github.com/nhunzaker) in [#7642](https://github.com/facebook/react/pull/7642))

### [](#react-test-renderer)React Test Renderer

* Due to packaging changes, it no longer crashes when imported together with React DOM in the same file.\
  ([@sebmarkbage](https://github.com/sebmarkbage) in [#7164](https://github.com/facebook/react/pull/7164) and [#7168](https://github.com/facebook/react/pull/7168))
* `ReactTestRenderer.create()` now accepts `{createNodeMock: element => mock}` as an optional argument so you can mock refs with snapshot testing.\
  ([@Aweary](https://github.com/Aweary) in [#7649](https://github.com/facebook/react/pull/7649) and [#8261](https://github.com/facebook/react/pull/8261))

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2016-11-16-react-v15.4.0.md)

----
url: https://legacy.reactjs.org/blog/2015/12/29/react-v0.14.4.html
----

December 29, 2015 by [Sophie Alpert](https://sophiebits.com/)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

Happy December! We have a minor point release today. It has just a few small bug fixes.

The release is now available for download:

* **React**\
  Dev build with warnings: <https://fb.me/react-0.14.4.js>\
  Minified build for production: <https://fb.me/react-0.14.4.min.js>
* **React with Add-Ons**\
  Dev build with warnings: <https://fb.me/react-with-addons-0.14.4.js>\
  Minified build for production: <https://fb.me/react-with-addons-0.14.4.min.js>
* **React DOM** (include React in the page before React DOM)\
  Dev build with warnings: <https://fb.me/react-dom-0.14.4.js>\
  Minified build for production: <https://fb.me/react-dom-0.14.4.min.js>
* **React DOM Server** (include React in the page before React DOM Server)\
  Dev build with warnings: <https://fb.me/react-dom-server-0.14.4.js>\
  Minified build for production: <https://fb.me/react-dom-server-0.14.4.min.js>

We’ve also published version `0.14.4` of the `react`, `react-dom`, and addons packages on npm and the `react` package on bower.

***

## [](#changelog)Changelog

### [](#react)React

* Minor internal changes for better compatibility with React Native

### [](#react-dom)React DOM

* The `autoCapitalize` and `autoCorrect` props are now set as attributes in the DOM instead of properties to improve cross-browser compatibility
* Fixed bug with controlled `<select>` elements not handling updates properly

### [](#react-perf-add-on)React Perf Add-on

* Some DOM operation names have been updated for clarity in the output of `.printDOM()`

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2015-12-29-react-v0.14.4.md)

----
url: https://legacy.reactjs.org/docs/hooks-effect.html
----

> These docs are old and won’t be updated. Go to [react.dev](https://react.dev/) for the new React docs.
>
> These new documentation pages teach modern React and include live examples:
>
> * [Synchronizing with Effects](https://react.dev/learn/synchronizing-with-effects)
> * [You Might Not Need an Effect](https://react.dev/learn/you-might-not-need-an-effect)
> * [`useEffect`](https://react.dev/reference/react/useEffect)

*Hooks* are a new addition in React 16.8. They let you use state and other React features without writing a class.

The *Effect Hook* lets you perform side effects in function components:

```
import React, { useState, useEffect } from 'react';
function Example() {
  const [count, setCount] = useState(0);

  // Similar to componentDidMount and componentDidUpdate:  useEffect(() => {    // Update the document title using the browser API    document.title = `You clicked ${count} times`;  });
  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}
```

This snippet is based on the [counter example from the previous page](/docs/hooks-state.html), but we added a new feature to it: we set the document title to a custom message including the number of clicks.

Data fetching, setting up a subscription, and manually changing the DOM in React components are all examples of side effects. Whether or not you’re used to calling these operations “side effects” (or just “effects”), you’ve likely performed them in your components before.

> Tip
>
> If you’re familiar with React class lifecycle methods, you can think of `useEffect` Hook as `componentDidMount`, `componentDidUpdate`, and `componentWillUnmount` combined.

There are two common kinds of side effects in React components: those that don’t require cleanup, and those that do. Let’s look at this distinction in more detail.

## [](#effects-without-cleanup)Effects Without Cleanup

Sometimes, we want to **run some additional code after React has updated the DOM.** Network requests, manual DOM mutations, and logging are common examples of effects that don’t require a cleanup. We say that because we can run them and immediately forget about them. Let’s compare how classes and Hooks let us express such side effects.

### [](#example-using-classes)Example Using Classes

In React class components, the `render` method itself shouldn’t cause side effects. It would be too early — we typically want to perform our effects *after* React has updated the DOM.

This is why in React classes, we put side effects into `componentDidMount` and `componentDidUpdate`. Coming back to our example, here is a React counter class component that updates the document title right after React makes changes to the DOM:

```
class Example extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0
    };
  }

  componentDidMount() {    document.title = `You clicked ${this.state.count} times`;  }  componentDidUpdate() {    document.title = `You clicked ${this.state.count} times`;  }
  render() {
    return (
      <div>
        <p>You clicked {this.state.count} times</p>
        <button onClick={() => this.setState({ count: this.state.count + 1 })}>
          Click me
        </button>
      </div>
    );
  }
}
```

Note how **we have to duplicate the code between these two lifecycle methods in class.**

This is because in many cases we want to perform the same side effect regardless of whether the component just mounted, or if it has been updated. Conceptually, we want it to happen after every render — but React class components don’t have a method like this. We could extract a separate method but we would still have to call it in two places.

Now let’s see how we can do the same with the `useEffect` Hook.

### [](#example-using-hooks)Example Using Hooks

We’ve already seen this example at the top of this page, but let’s take a closer look at it:

```
import React, { useState, useEffect } from 'react';
function Example() {
  const [count, setCount] = useState(0);

  useEffect(() => {    document.title = `You clicked ${count} times`;  });
  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}
```

**What does `useEffect` do?** By using this Hook, you tell React that your component needs to do something after render. React will remember the function you passed (we’ll refer to it as our “effect”), and call it later after performing the DOM updates. In this effect, we set the document title, but we could also perform data fetching or call some other imperative API.

**Why is `useEffect` called inside a component?** Placing `useEffect` inside the component lets us access the `count` state variable (or any props) right from the effect. We don’t need a special API to read it — it’s already in the function scope. Hooks embrace JavaScript closures and avoid introducing React-specific APIs where JavaScript already provides a solution.

**Does `useEffect` run after every render?** Yes! By default, it runs both after the first render *and* after every update. (We will later talk about [how to customize this](#tip-optimizing-performance-by-skipping-effects).) Instead of thinking in terms of “mounting” and “updating”, you might find it easier to think that effects happen “after render”. React guarantees the DOM has been updated by the time it runs the effects.

### [](#detailed-explanation)Detailed Explanation

Now that we know more about effects, these lines should make sense:

```
function Example() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    document.title = `You clicked ${count} times`;
  });
}
```

We declare the `count` state variable, and then we tell React we need to use an effect. We pass a function to the `useEffect` Hook. This function we pass *is* our effect. Inside our effect, we set the document title using the `document.title` browser API. We can read the latest `count` inside the effect because it’s in the scope of our function. When React renders our component, it will remember the effect we used, and then run our effect after updating the DOM. This happens for every render, including the first one.

Experienced JavaScript developers might notice that the function passed to `useEffect` is going to be different on every render. This is intentional. In fact, this is what lets us read the `count` value from inside the effect without worrying about it getting stale. Every time we re-render, we schedule a *different* effect, replacing the previous one. In a way, this makes the effects behave more like a part of the render result — each effect “belongs” to a particular render. We will see more clearly why this is useful [later on this page](#explanation-why-effects-run-on-each-update).

> Tip
>
> Unlike `componentDidMount` or `componentDidUpdate`, effects scheduled with `useEffect` don’t block the browser from updating the screen. This makes your app feel more responsive. The majority of effects don’t need to happen synchronously. In the uncommon cases where they do (such as measuring the layout), there is a separate [`useLayoutEffect`](/docs/hooks-reference.html#uselayouteffect) Hook with an API identical to `useEffect`.

## [](#effects-with-cleanup)Effects with Cleanup

Earlier, we looked at how to express side effects that don’t require any cleanup. However, some effects do. For example, **we might want to set up a subscription** to some external data source. In that case, it is important to clean up so that we don’t introduce a memory leak! Let’s compare how we can do it with classes and with Hooks.

### [](#example-using-classes-1)Example Using Classes

In a React class, you would typically set up a subscription in `componentDidMount`, and clean it up in `componentWillUnmount`. For example, let’s say we have a `ChatAPI` module that lets us subscribe to a friend’s online status. Here’s how we might subscribe and display that status using a class:

```
class FriendStatus extends React.Component {
  constructor(props) {
    super(props);
    this.state = { isOnline: null };
    this.handleStatusChange = this.handleStatusChange.bind(this);
  }

  componentDidMount() {    ChatAPI.subscribeToFriendStatus(      this.props.friend.id,      this.handleStatusChange    );  }  componentWillUnmount() {    ChatAPI.unsubscribeFromFriendStatus(      this.props.friend.id,      this.handleStatusChange    );  }  handleStatusChange(status) {    this.setState({      isOnline: status.isOnline    });  }
  render() {
    if (this.state.isOnline === null) {
      return 'Loading...';
    }
    return this.state.isOnline ? 'Online' : 'Offline';
  }
}
```

Notice how `componentDidMount` and `componentWillUnmount` need to mirror each other. Lifecycle methods force us to split this logic even though conceptually code in both of them is related to the same effect.

> Note
>
> Eagle-eyed readers may notice that this example also needs a `componentDidUpdate` method to be fully correct. We’ll ignore this for now but will come back to it in a [later section](#explanation-why-effects-run-on-each-update) of this page.

### [](#example-using-hooks-1)Example Using Hooks

Let’s see how we could write this component with Hooks.

You might be thinking that we’d need a separate effect to perform the cleanup. But code for adding and removing a subscription is so tightly related that `useEffect` is designed to keep it together. If your effect returns a function, React will run it when it is time to clean up:

```
import React, { useState, useEffect } from 'react';

function FriendStatus(props) {
  const [isOnline, setIsOnline] = useState(null);

  useEffect(() => {    function handleStatusChange(status) {      setIsOnline(status.isOnline);    }    ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);    // Specify how to clean up after this effect:    return function cleanup() {      ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);    };  });
  if (isOnline === null) {
    return 'Loading...';
  }
  return isOnline ? 'Online' : 'Offline';
}
```

**Why did we return a function from our effect?** This is the optional cleanup mechanism for effects. Every effect may return a function that cleans up after it. This lets us keep the logic for adding and removing subscriptions close to each other. They’re part of the same effect!

**When exactly does React clean up an effect?** React performs the cleanup when the component unmounts. However, as we learned earlier, effects run for every render and not just once. This is why React *also* cleans up effects from the previous render before running the effects next time. We’ll discuss [why this helps avoid bugs](#explanation-why-effects-run-on-each-update) and [how to opt out of this behavior in case it creates performance issues](#tip-optimizing-performance-by-skipping-effects) later below.

> Note
>
> We don’t have to return a named function from the effect. We called it `cleanup` here to clarify its purpose, but you could return an arrow function or call it something different.

## [](#recap)Recap

We’ve learned that `useEffect` lets us express different kinds of side effects after a component renders. Some effects might require cleanup so they return a function:

```
  useEffect(() => {
    function handleStatusChange(status) {
      setIsOnline(status.isOnline);
    }

    ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
    return () => {
      ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
    };
  });
```

Other effects might not have a cleanup phase, and don’t return anything.

```
  useEffect(() => {
    document.title = `You clicked ${count} times`;
  });
```

The Effect Hook unifies both use cases with a single API.

***

**If you feel like you have a decent grasp on how the Effect Hook works, or if you feel overwhelmed, you can jump to the [next page about Rules of Hooks](/docs/hooks-rules.html) now.**

***

## [](#tips-for-using-effects)Tips for Using Effects

We’ll continue this page with an in-depth look at some aspects of `useEffect` that experienced React users will likely be curious about. Don’t feel obligated to dig into them now. You can always come back to this page to learn more details about the Effect Hook.

### [](#tip-use-multiple-effects-to-separate-concerns)Tip: Use Multiple Effects to Separate Concerns

One of the problems we outlined in the [Motivation](/docs/hooks-intro.html#complex-components-become-hard-to-understand) for Hooks is that class lifecycle methods often contain unrelated logic, but related logic gets broken up into several methods. Here is a component that combines the counter and the friend status indicator logic from the previous examples:

```
class FriendStatusWithCounter extends React.Component {
  constructor(props) {
    super(props);
    this.state = { count: 0, isOnline: null };
    this.handleStatusChange = this.handleStatusChange.bind(this);
  }

  componentDidMount() {
    document.title = `You clicked ${this.state.count} times`;
    ChatAPI.subscribeToFriendStatus(
      this.props.friend.id,
      this.handleStatusChange
    );
  }

  componentDidUpdate() {
    document.title = `You clicked ${this.state.count} times`;
  }

  componentWillUnmount() {
    ChatAPI.unsubscribeFromFriendStatus(
      this.props.friend.id,
      this.handleStatusChange
    );
  }

  handleStatusChange(status) {
    this.setState({
      isOnline: status.isOnline
    });
  }
  // ...
```

Note how the logic that sets `document.title` is split between `componentDidMount` and `componentDidUpdate`. The subscription logic is also spread between `componentDidMount` and `componentWillUnmount`. And `componentDidMount` contains code for both tasks.

So, how can Hooks solve this problem? Just like [you can use the *State* Hook more than once](/docs/hooks-state.html#tip-using-multiple-state-variables), you can also use several effects. This lets us separate unrelated logic into different effects:

```
function FriendStatusWithCounter(props) {
  const [count, setCount] = useState(0);
  useEffect(() => {    document.title = `You clicked ${count} times`;
  });

  const [isOnline, setIsOnline] = useState(null);
  useEffect(() => {    function handleStatusChange(status) {
      setIsOnline(status.isOnline);
    }

    ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
    return () => {
      ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
    };
  });
  // ...
}
```

**Hooks let us split the code based on what it is doing** rather than a lifecycle method name. React will apply *every* effect used by the component, in the order they were specified.

### [](#explanation-why-effects-run-on-each-update)Explanation: Why Effects Run on Each Update

If you’re used to classes, you might be wondering why the effect cleanup phase happens after every re-render, and not just once during unmounting. Let’s look at a practical example to see why this design helps us create components with fewer bugs.

[Earlier on this page](#example-using-classes-1), we introduced an example `FriendStatus` component that displays whether a friend is online or not. Our class reads `friend.id` from `this.props`, subscribes to the friend status after the component mounts, and unsubscribes during unmounting:

```
  componentDidMount() {
    ChatAPI.subscribeToFriendStatus(
      this.props.friend.id,
      this.handleStatusChange
    );
  }

  componentWillUnmount() {
    ChatAPI.unsubscribeFromFriendStatus(
      this.props.friend.id,
      this.handleStatusChange
    );
  }
```

**But what happens if the `friend` prop changes** while the component is on the screen? Our component would continue displaying the online status of a different friend. This is a bug. We would also cause a memory leak or crash when unmounting since the unsubscribe call would use the wrong friend ID.

In a class component, we would need to add `componentDidUpdate` to handle this case:

```
  componentDidMount() {
    ChatAPI.subscribeToFriendStatus(
      this.props.friend.id,
      this.handleStatusChange
    );
  }

  componentDidUpdate(prevProps) {    // Unsubscribe from the previous friend.id    ChatAPI.unsubscribeFromFriendStatus(      prevProps.friend.id,      this.handleStatusChange    );    // Subscribe to the next friend.id    ChatAPI.subscribeToFriendStatus(      this.props.friend.id,      this.handleStatusChange    );  }
  componentWillUnmount() {
    ChatAPI.unsubscribeFromFriendStatus(
      this.props.friend.id,
      this.handleStatusChange
    );
  }
```

Forgetting to handle `componentDidUpdate` properly is a common source of bugs in React applications.

Now consider the version of this component that uses Hooks:

```
function FriendStatus(props) {
  // ...
  useEffect(() => {
    // ...
    ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
    return () => {
      ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
    };
  });
```

It doesn’t suffer from this bug. (But we also didn’t make any changes to it.)

There is no special code for handling updates because `useEffect` handles them *by default*. It cleans up the previous effects before applying the next effects. To illustrate this, here is a sequence of subscribe and unsubscribe calls that this component could produce over time:

```
// Mount with { friend: { id: 100 } } props
ChatAPI.subscribeToFriendStatus(100, handleStatusChange);     // Run first effect

// Update with { friend: { id: 200 } } props
ChatAPI.unsubscribeFromFriendStatus(100, handleStatusChange); // Clean up previous effect
ChatAPI.subscribeToFriendStatus(200, handleStatusChange);     // Run next effect

// Update with { friend: { id: 300 } } props
ChatAPI.unsubscribeFromFriendStatus(200, handleStatusChange); // Clean up previous effect
ChatAPI.subscribeToFriendStatus(300, handleStatusChange);     // Run next effect

// Unmount
ChatAPI.unsubscribeFromFriendStatus(300, handleStatusChange); // Clean up last effect
```

This behavior ensures consistency by default and prevents bugs that are common in class components due to missing update logic.

### [](#tip-optimizing-performance-by-skipping-effects)Tip: Optimizing Performance by Skipping Effects

In some cases, cleaning up or applying the effect after every render might create a performance problem. In class components, we can solve this by writing an extra comparison with `prevProps` or `prevState` inside `componentDidUpdate`:

```
componentDidUpdate(prevProps, prevState) {
  if (prevState.count !== this.state.count) {
    document.title = `You clicked ${this.state.count} times`;
  }
}
```

This requirement is common enough that it is built into the `useEffect` Hook API. You can tell React to *skip* applying an effect if certain values haven’t changed between re-renders. To do so, pass an array as an optional second argument to `useEffect`:

```
useEffect(() => {
  document.title = `You clicked ${count} times`;
}, [count]); // Only re-run the effect if count changes
```

In the example above, we pass `[count]` as the second argument. What does this mean? If the `count` is `5`, and then our component re-renders with `count` still equal to `5`, React will compare `[5]` from the previous render and `[5]` from the next render. Because all items in the array are the same (`5 === 5`), React would skip the effect. That’s our optimization.

When we render with `count` updated to `6`, React will compare the items in the `[5]` array from the previous render to items in the `[6]` array from the next render. This time, React will re-apply the effect because `5 !== 6`. If there are multiple items in the array, React will re-run the effect even if just one of them is different.

This also works for effects that have a cleanup phase:

```
useEffect(() => {
  function handleStatusChange(status) {
    setIsOnline(status.isOnline);
  }

  ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
  return () => {
    ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
  };
}, [props.friend.id]); // Only re-subscribe if props.friend.id changes
```

In the future, the second argument might get added automatically by a build-time transformation.

> 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 changes 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.

## [](#next-steps)Next Steps

Congratulations! This was a long page, but hopefully by the end most of your questions about effects were answered. You’ve learned both the State Hook and the Effect Hook, and there is a *lot* you can do with both of them combined. They cover most of the use cases for classes — and where they don’t, you might find the [additional Hooks](/docs/hooks-reference.html) helpful.

We’re also starting to see how Hooks solve problems outlined in [Motivation](/docs/hooks-intro.html#motivation). We’ve seen how effect cleanup avoids duplication in `componentDidUpdate` and `componentWillUnmount`, brings related code closer together, and helps us avoid bugs. We’ve also seen how we can separate effects by their purpose, which is something we couldn’t do in classes at all.

At this point you might be questioning how Hooks work. How can React know which `useState` call corresponds to which state variable between re-renders? How does React “match up” previous and next effects on every update? **On the next page we will learn about the [Rules of Hooks](/docs/hooks-rules.html) — they’re essential to making Hooks work.**

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/hooks-effect.md)

* Previous article

  [Using the State Hook](/docs/hooks-state.html)

* Next article

  [Rules of Hooks](/docs/hooks-rules.html)

----
url: https://react.dev/learn/lifecycle-of-reactive-effects
----

```
const serverUrl = 'https://localhost:1234';



function ChatRoom({ roomId }) {

  useEffect(() => {

    const connection = createConnection(serverUrl, roomId);

    connection.connect();

    return () => {

      connection.disconnect();

    };

  }, [roomId]);

  // ...

}
```

Your Effect’s body specifies how to **start synchronizing:**

```
    // ...

    const connection = createConnection(serverUrl, roomId);

    connection.connect();

    return () => {

      connection.disconnect();

    };

    // ...
```

The cleanup function returned by your Effect specifies how to **stop synchronizing:**

```
    // ...

    const connection = createConnection(serverUrl, roomId);

    connection.connect();

    return () => {

      connection.disconnect();

    };

    // ...
```

Intuitively, you might think that React would **start synchronizing** when your component mounts and **stop synchronizing** when your component unmounts. However, this is not the end of the story! Sometimes, it may also be necessary to **start and stop synchronizing multiple times** while the component remains mounted.

Let’s look at *why* this is necessary, *when* it happens, and *how* you can control this behavior.

### Note

Some Effects don’t return a cleanup function at all. [More often than not,](/learn/synchronizing-with-effects#how-to-handle-the-effect-firing-twice-in-development) you’ll want to return one—but if you don’t, React will behave as if you returned an empty cleanup function.

### Why synchronization may need to happen more than once[](#why-synchronization-may-need-to-happen-more-than-once "Link for Why synchronization may need to happen more than once ")

Imagine this `ChatRoom` component receives a `roomId` prop that the user picks in a dropdown. Let’s say that initially the user picks the `"general"` room as the `roomId`. Your app displays the `"general"` chat room:

```
const serverUrl = 'https://localhost:1234';



function ChatRoom({ roomId /* "general" */ }) {

  // ...

  return <h1>Welcome to the {roomId} room!</h1>;

}
```

After the UI is displayed, React will run your Effect to **start synchronizing.** It connects to the `"general"` room:

```
function ChatRoom({ roomId /* "general" */ }) {

  useEffect(() => {

    const connection = createConnection(serverUrl, roomId); // Connects to the "general" room

    connection.connect();

    return () => {

      connection.disconnect(); // Disconnects from the "general" room

    };

  }, [roomId]);

  // ...
```

So far, so good.

Later, the user picks a different room in the dropdown (for example, `"travel"`). First, React will update the UI:

```
function ChatRoom({ roomId /* "travel" */ }) {

  // ...

  return <h1>Welcome to the {roomId} room!</h1>;

}
```

```
function ChatRoom({ roomId /* "general" */ }) {

  useEffect(() => {

    const connection = createConnection(serverUrl, roomId); // Connects to the "general" room

    connection.connect();

    return () => {

      connection.disconnect(); // Disconnects from the "general" room

    };

    // ...
```

Then React will run the Effect that you’ve provided during this render. This time, `roomId` is `"travel"` so it will **start synchronizing** to the `"travel"` chat room (until its cleanup function is eventually called too):

```
function ChatRoom({ roomId /* "travel" */ }) {

  useEffect(() => {

    const connection = createConnection(serverUrl, roomId); // Connects to the "travel" room

    connection.connect();

    // ...
```

```
  useEffect(() => {

    // Your Effect connected to the room specified with roomId...

    const connection = createConnection(serverUrl, roomId);

    connection.connect();

    return () => {

      // ...until it disconnected

      connection.disconnect();

    };

  }, [roomId]);
```

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useEffect } from 'react';
import { createConnection } from './chat.js';

const serverUrl = 'https://localhost:1234';

function ChatRoom({ roomId }) {
  useEffect(() => {
    const connection = createConnection(serverUrl, roomId);
    connection.connect();
    return () => connection.disconnect();
  }, [roomId]);
  return <h1>Welcome to the {roomId} room!</h1>;
}

export default function App() {
  const [roomId, setRoomId] = useState('general');
  const [show, setShow] = useState(false);
  return (
    <>
      <label>
        Choose the chat room:{' '}
        <select
          value={roomId}
          onChange={e => setRoomId(e.target.value)}
        >
          <option value="general">general</option>
          <option value="travel">travel</option>
          <option value="music">music</option>
        </select>
      </label>
      <button onClick={() => setShow(!show)}>
        {show ? 'Close chat' : 'Open chat'}
      </button>
      {show && <hr />}
      {show && <ChatRoom roomId={roomId} />}
    </>
  );
}
```

```
function ChatRoom({ roomId }) { // The roomId prop may change over time

  useEffect(() => {

    const connection = createConnection(serverUrl, roomId); // This Effect reads roomId

    connection.connect();

    return () => {

      connection.disconnect();

    };

  }, [roomId]); // So you tell React that this Effect "depends on" roomId

  // ...
```

```
function ChatRoom({ roomId }) {

  useEffect(() => {

    logVisit(roomId);

    const connection = createConnection(serverUrl, roomId);

    connection.connect();

    return () => {

      connection.disconnect();

    };

  }, [roomId]);

  // ...

}
```

But imagine you later add another dependency to this Effect that needs to re-establish the connection. If this Effect re-synchronizes, it will also call `logVisit(roomId)` for the same room, which you did not intend. Logging the visit **is a separate process** from connecting. Write them as two separate Effects:

```
function ChatRoom({ roomId }) {

  useEffect(() => {

    logVisit(roomId);

  }, [roomId]);



  useEffect(() => {

    const connection = createConnection(serverUrl, roomId);

    // ...

  }, [roomId]);

  // ...

}
```

**Each Effect in your code should represent a separate and independent synchronization process.**

In the above example, deleting one Effect wouldn’t break the other Effect’s logic. This is a good indication that they synchronize different things, and so it made sense to split them up. On the other hand, if you split up a cohesive piece of logic into separate Effects, the code may look “cleaner” but will be [more difficult to maintain.](/learn/you-might-not-need-an-effect#chains-of-computations) This is why you should think whether the processes are same or separate, not whether the code looks cleaner.

## Effects “react” to reactive values[](#effects-react-to-reactive-values "Link for Effects “react” to reactive values ")

Your Effect reads two variables (`serverUrl` and `roomId`), but you only specified `roomId` as a dependency:

```
const serverUrl = 'https://localhost:1234';



function ChatRoom({ roomId }) {

  useEffect(() => {

    const connection = createConnection(serverUrl, roomId);

    connection.connect();

    return () => {

      connection.disconnect();

    };

  }, [roomId]);

  // ...

}
```

Why doesn’t `serverUrl` need to be a dependency?

This is because the `serverUrl` never changes due to a re-render. It’s always the same no matter how many times the component re-renders and why. Since `serverUrl` never changes, it wouldn’t make sense to specify it as a dependency. After all, dependencies only do something when they change over time!

On the other hand, `roomId` may be different on a re-render. **Props, state, and other values declared inside the component are *reactive* because they’re calculated during rendering and participate in the React data flow.**

If `serverUrl` was a state variable, it would be reactive. Reactive values must be included in dependencies:

```
function ChatRoom({ roomId }) { // Props change over time

  const [serverUrl, setServerUrl] = useState('https://localhost:1234'); // State may change over time



  useEffect(() => {

    const connection = createConnection(serverUrl, roomId); // Your Effect reads props and state

    connection.connect();

    return () => {

      connection.disconnect();

    };

  }, [roomId, serverUrl]); // So you tell React that this Effect "depends on" on props and state

  // ...

}
```

By including `serverUrl` as a dependency, you ensure that the Effect re-synchronizes after it changes.

Try changing the selected chat room or edit the server URL in this sandbox:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
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();
  }, [roomId, serverUrl]);

  return (
    <>
      <label>
        Server URL:{' '}
        <input
          value={serverUrl}
          onChange={e => setServerUrl(e.target.value)}
        />
      </label>
      <h1>Welcome to the {roomId} room!</h1>
    </>
  );
}

export default function App() {
  const [roomId, setRoomId] = useState('general');
  return (
    <>
      <label>
        Choose the chat room:{' '}
        <select
          value={roomId}
          onChange={e => setRoomId(e.target.value)}
        >
          <option value="general">general</option>
          <option value="travel">travel</option>
          <option value="music">music</option>
        </select>
      </label>
      <hr />
      <ChatRoom roomId={roomId} />
    </>
  );
}
```

Whenever you change a reactive value like `roomId` or `serverUrl`, the Effect re-connects to the chat server.

### What an Effect with empty dependencies means[](#what-an-effect-with-empty-dependencies-means "Link for What an Effect with empty dependencies means ")

What happens if you move both `serverUrl` and `roomId` outside the component?

```
const serverUrl = 'https://localhost:1234';

const roomId = 'general';



function ChatRoom() {

  useEffect(() => {

    const connection = createConnection(serverUrl, roomId);

    connection.connect();

    return () => {

      connection.disconnect();

    };

  }, []); // ✅ All dependencies declared

  // ...

}
```

Now your Effect’s code does not use *any* reactive values, so its dependencies can be empty (`[]`).

Thinking from the component’s perspective, the empty `[]` dependency array means this Effect connects to the chat room only when the component mounts, and disconnects only when the component unmounts. (Keep in mind that React would still [re-synchronize it an extra time](#how-react-verifies-that-your-effect-can-re-synchronize) in development to stress-test your logic.)

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useEffect } from 'react';
import { createConnection } from './chat.js';

const serverUrl = 'https://localhost:1234';
const roomId = 'general';

function ChatRoom() {
  useEffect(() => {
    const connection = createConnection(serverUrl, roomId);
    connection.connect();
    return () => connection.disconnect();
  }, []);
  return <h1>Welcome to the {roomId} room!</h1>;
}

export default function App() {
  const [show, setShow] = useState(false);
  return (
    <>
      <button onClick={() => setShow(!show)}>
        {show ? 'Close chat' : 'Open chat'}
      </button>
      {show && <hr />}
      {show && <ChatRoom />}
    </>
  );
}
```

However, if you [think from the Effect’s perspective,](#thinking-from-the-effects-perspective) you don’t need to think about mounting and unmounting at all. What’s important is you’ve specified what your Effect does to start and stop synchronizing. Today, it has no reactive dependencies. But if you ever want the user to change `roomId` or `serverUrl` over time (and they would become reactive), your Effect’s code won’t change. You will only need to add them to the dependencies.

### All variables declared in the component body are reactive[](#all-variables-declared-in-the-component-body-are-reactive "Link for All variables declared in the component body are reactive ")

Props and state aren’t the only reactive values. Values that you calculate from them are also reactive. If the props or state change, your component will re-render, and the values calculated from them will also change. This is why all variables from the component body used by the Effect should be in the Effect dependency list.

Let’s say that the user can pick a chat server in the dropdown, but they can also configure a default server in settings. Suppose you’ve already put the settings state in a [context](/learn/scaling-up-with-reducer-and-context) so you read the `settings` from that context. Now you calculate the `serverUrl` based on the selected server from props and the default server:

```
function ChatRoom({ roomId, selectedServerUrl }) { // roomId is reactive

  const settings = useContext(SettingsContext); // settings is reactive

  const serverUrl = selectedServerUrl ?? settings.defaultServerUrl; // serverUrl is reactive

  useEffect(() => {

    const connection = createConnection(serverUrl, roomId); // Your Effect reads roomId and serverUrl

    connection.connect();

    return () => {

      connection.disconnect();

    };

  }, [roomId, serverUrl]); // So it needs to re-synchronize when either of them changes!

  // ...

}
```

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useEffect } from 'react';
import { createConnection } from './chat.js';

function ChatRoom({ roomId }) { // roomId is reactive
  const [serverUrl, setServerUrl] = useState('https://localhost:1234'); // serverUrl is reactive

  useEffect(() => {
    const connection = createConnection(serverUrl, roomId);
    connection.connect();
    return () => connection.disconnect();
  }, []); // <-- Something's wrong here!

  return (
    <>
      <label>
        Server URL:{' '}
        <input
          value={serverUrl}
          onChange={e => setServerUrl(e.target.value)}
        />
      </label>
      <h1>Welcome to the {roomId} room!</h1>
    </>
  );
}

export default function App() {
  const [roomId, setRoomId] = useState('general');
  return (
    <>
      <label>
        Choose the chat room:{' '}
        <select
          value={roomId}
          onChange={e => setRoomId(e.target.value)}
        >
          <option value="general">general</option>
          <option value="travel">travel</option>
          <option value="music">music</option>
        </select>
      </label>
      <hr />
      <ChatRoom roomId={roomId} />
    </>
  );
}
```

This may look like a React error, but really React is pointing out a bug in your code. Both `roomId` and `serverUrl` may change over time, but you’re forgetting to re-synchronize your Effect when they change. You will remain connected to the initial `roomId` and `serverUrl` even after the user picks different values in the UI.

To fix the bug, follow the linter’s suggestion to specify `roomId` and `serverUrl` as dependencies of your Effect:

```
function ChatRoom({ roomId }) { // roomId is reactive

  const [serverUrl, setServerUrl] = useState('https://localhost:1234'); // serverUrl is reactive

  useEffect(() => {

    const connection = createConnection(serverUrl, roomId);

    connection.connect();

    return () => {

      connection.disconnect();

    };

  }, [serverUrl, roomId]); // ✅ All dependencies declared

  // ...

}
```

Try this fix in the sandbox above. Verify that the linter error is gone, and the chat re-connects when needed.

### Note

In some cases, React *knows* that a value never changes even though it’s declared inside the component. For example, the [`set` function](/reference/react/useState#setstate) returned from `useState` and the ref object returned by [`useRef`](/reference/react/useRef) are *stable*—they are guaranteed to not change on a re-render. Stable values aren’t reactive, so you may omit them from the list. Including them is allowed: they won’t change, so it doesn’t matter.

### What to do when you don’t want to re-synchronize[](#what-to-do-when-you-dont-want-to-re-synchronize "Link for What to do when you don’t want to re-synchronize ")

In the previous example, you’ve fixed the lint error by listing `roomId` and `serverUrl` as dependencies.

**However, you could instead “prove” to the linter that these values aren’t reactive values,** i.e. that they *can’t* change as a result of a re-render. For example, if `serverUrl` and `roomId` don’t depend on rendering and always have the same values, you can move them outside the component. Now they don’t need to be dependencies:

```
const serverUrl = 'https://localhost:1234'; // serverUrl is not reactive

const roomId = 'general'; // roomId is not reactive



function ChatRoom() {

  useEffect(() => {

    const connection = createConnection(serverUrl, roomId);

    connection.connect();

    return () => {

      connection.disconnect();

    };

  }, []); // ✅ All dependencies declared

  // ...

}
```

You can also move them *inside the Effect.* They aren’t calculated during rendering, so they’re not reactive:

```
function ChatRoom() {

  useEffect(() => {

    const serverUrl = 'https://localhost:1234'; // serverUrl is not reactive

    const roomId = 'general'; // roomId is not reactive

    const connection = createConnection(serverUrl, roomId);

    connection.connect();

    return () => {

      connection.disconnect();

    };

  }, []); // ✅ All dependencies declared

  // ...

}
```

```
useEffect(() => {

  // ...

  // 🔴 Avoid suppressing the linter like this:

  // eslint-ignore-next-line react-hooks/exhaustive-deps

}, []);
```

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useEffect } from 'react';
import { createConnection } from './chat.js';

const serverUrl = 'https://localhost:1234';

function ChatRoom({ roomId }) {
  const [message, setMessage] = useState('');

  useEffect(() => {
    const connection = createConnection(serverUrl, roomId);
    connection.connect();
    return () => connection.disconnect();
  });

  return (
    <>
      <h1>Welcome to the {roomId} room!</h1>
      <input
        value={message}
        onChange={e => setMessage(e.target.value)}
      />
    </>
  );
}

export default function App() {
  const [roomId, setRoomId] = useState('general');
  return (
    <>
      <label>
        Choose the chat room:{' '}
        <select
          value={roomId}
          onChange={e => setRoomId(e.target.value)}
        >
          <option value="general">general</option>
          <option value="travel">travel</option>
          <option value="music">music</option>
        </select>
      </label>
      <hr />
      <ChatRoom roomId={roomId} />
    </>
  );
}
```

[PreviousYou Might Not Need an Effect](/learn/you-might-not-need-an-effect)

[NextSeparating Events from Effects](/learn/separating-events-from-effects)

***

----
url: https://legacy.reactjs.org/blog/2020/08/10/react-v17-rc.html
----

August 10, 2020 by [Dan Abramov](https://twitter.com/dan_abramov) and [Rachel Nabors](https://twitter.com/rachelnabors)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

Today, we are publishing the first Release Candidate for React 17. It has been two and a half years since [the previous major release of React](/blog/2017/09/26/react-v16.0.html), which is a long time even by our standards! In this blog post, we will describe the role of this major release, what changes you can expect in it, and how you can try this release.

## [](#no-new-features)No New Features

The React 17 release is unusual because it doesn’t add any new developer-facing features. Instead, this release is primarily focused on **making it easier to upgrade React itself**.

We’re actively working on the new React features, but they’re not a part of this release. The React 17 release is a key part of our strategy to roll them out without leaving anyone behind.

In particular, **React 17 is a “stepping stone” release** that makes it safer to embed a tree managed by one version of React inside a tree managed by a different version of React.

## [](#gradual-upgrades)Gradual Upgrades

For the past seven years, React upgrades have been “all-or-nothing”. Either you stay on an old version, or you upgrade your whole app to a new version. There was no in-between.

This has worked out so far, but we are running into the limits of the “all-or-nothing” upgrade strategy. Some API changes, for example, deprecating the [legacy context API](/docs/legacy-context.html), are impossible to do in an automated way. Even though most apps written today don’t ever use them, we still support them in React. We have to choose between supporting them in React indefinitely or leaving some apps behind on an old version of React. Both of these options aren’t great.

So we wanted to provide another option.

**React 17 enables gradual React upgrades.** When you upgrade from React 15 to 16 (or, soon, from React 16 to 17), you would usually upgrade your whole app at once. This works well for many apps. But it can get increasingly challenging if the codebase was written more than a few years ago and isn’t actively maintained. And while it’s possible to use two versions of React on the page, until React 17 this has been fragile and caused problems with events.

We’re fixing many of those problems with React 17. This means that **when React 18 and the next future versions come out, you will now have more options**. The first option will be to upgrade your whole app at once, like you might have done before. But you will also have an option to upgrade your app piece by piece. For example, you might decide to migrate most of your app to React 18, but keep some lazy-loaded dialog or a subroute on React 17.

This doesn’t mean you *have to* do gradual upgrades. For most apps, upgrading all at once is still the best solution. Loading two versions of React — even if one of them is loaded lazily on demand — is still not ideal. However, for larger apps that aren’t actively maintained, this option may make sense to consider, and React 17 enables those apps to not get left behind.

To enable gradual updates, we’ve needed to make some changes to the React event system. React 17 is a major release because these changes are potentially breaking. In practice, we’ve only had to change fewer than twenty components out of 100,000+ so **we expect that most apps can upgrade to React 17 without too much trouble**. [Tell us](https://github.com/facebook/react/issues) if you run into problems.

### [](#demo-of-gradual-upgrades)Demo of Gradual Upgrades

We’ve prepared an [example repository](https://github.com/reactjs/react-gradual-upgrade-demo/) demonstrating how to lazy-load an older version of React if necessary. This demo uses Create React App, but it should be possible to follow a similar approach with any other tool. We welcome demos using other tooling as pull requests.

> Note
>
> We’ve **postponed other changes** until after React 17. The goal of this release is to enable gradual upgrades. If upgrading to React 17 were too difficult, it would defeat its purpose.

## [](#changes-to-event-delegation)Changes to Event Delegation

Technically, it has always been possible to nest apps developed with different versions of React. However, it was rather fragile because of how the React event system worked.

In React components, you usually write event handlers inline:

```
<button onClick={handleClick}>
```

The vanilla DOM equivalent to this code is something like:

```
myButton.addEventListener('click', handleClick);
```

However, for most events, React doesn’t actually attach them to the DOM nodes on which you declare them. Instead, React attaches one handler per event type directly at the `document` node. This is called [event delegation](https://davidwalsh.name/event-delegate). In addition to its performance benefits on large application trees, it also makes it easier to add new features like [replaying events](https://twitter.com/dan_abramov/status/1200118229697486849).

React has been doing event delegation automatically since its first release. When a DOM event fires on the document, React figures out which component to call, and then the React event “bubbles” upwards through your components. But behind the scenes, the native event has already bubbled up to the `document` level, where React installs its event handlers.

However, this is a problem for gradual upgrades.

If you have multiple React versions on the page, they all register event handlers at the top. This breaks `e.stopPropagation()`: if a nested tree has stopped propagation of an event, the outer tree would still receive it. This made it difficult to nest different versions of React. This concern is not hypothetical — for example, the Atom editor [ran into this](https://github.com/facebook/react/pull/8117) four years ago.

This is why we’re changing how React attaches events to the DOM under the hood.

**In React 17, React will no longer attach event handlers at the `document` level. Instead, it will attach them to the root DOM container into which your React tree is rendered:**

```
const rootNode = document.getElementById('root');
ReactDOM.render(<App />, rootNode);
```

In React 16 and earlier, React would do `document.addEventListener()` for most events. React 17 will call `rootNode.addEventListener()` under the hood instead.

[](/static/bb4b10114882a50090b8ff61b3c4d0fd/31868/react_17_delegation.png)

Thanks to this change, **it is now safer to embed a React tree managed by one version inside a tree managed by a different React version**. Note that for this to work, both of the versions would need to be 17 or higher, which is why upgrading to React 17 is important. In a way, React 17 is a “stepping stone” release that makes next gradual upgrades feasible.

This change also **makes it easier to embed React into apps built with other technologies**. For example, if the outer “shell” of your app is written in jQuery, but the newer code inside of it is written with React, `e.stopPropagation()` inside the React code would now prevent it from reaching the jQuery code — as you would expect. This also works in the other direction. If you no longer like React and want to rewrite your app — for example, in jQuery — you can start converting the outer shell from React to jQuery without breaking the event propagation.

We’ve confirmed that [numerous](https://github.com/facebook/react/issues/7094) [problems](https://github.com/facebook/react/issues/8693) [reported](https://github.com/facebook/react/issues/12518) [over](https://github.com/facebook/react/issues/13451) [the](https://github.com/facebook/react/issues/4335) [years](https://github.com/facebook/react/issues/1691) [on](https://github.com/facebook/react/issues/285#issuecomment-253502585) [our](https://github.com/facebook/react/pull/8117) [issue](https://github.com/facebook/react/issues/11530) [tracker](https://github.com/facebook/react/issues/7128) related to integrating React with non-React code have been fixed by the new behavior.

> Note
>
> You might be wondering whether this breaks [Portals](/docs/portals.html) outside of the root container. The answer is that React *also* listens to events on portal containers, so this is not an issue.

#### [](#fixing-potential-issues)Fixing Potential Issues

As with any breaking change, it is likely some code would need to be adjusted. At Facebook, we had to adjust about 10 modules in total (out of many thousands) to work with this change.

For example, if you add manual DOM listeners with `document.addEventListener(...)`, you might expect them to catch all React events. In React 16 and earlier, even if you call `e.stopPropagation()` in a React event handler, your custom `document` listeners would still receive them because the native event is *already* at the document level. With React 17, the propagation *would* stop (as requested!), so your `document` handlers would not fire:

```
document.addEventListener('click', function() {
  // This custom handler will no longer receive clicks
  // from React components that called e.stopPropagation()
});
```

You can fix code like this by converting your listener to use the [capture phase](https://javascript.info/bubbling-and-capturing#capturing). To do this, you can pass `{ capture: true }` as the third argument to `document.addEventListener`:

```
document.addEventListener('click', function() {
  // Now this event handler uses the capture phase,
  // so it receives *all* click events below!
}, { capture: true });
```

Note how this strategy is more resilient overall — for example, it will probably fix existing bugs in your code that happen when `e.stopPropagation()` is called outside of a React event handler. In other words, **event propagation in React 17 works closer to the regular DOM**.

## [](#other-breaking-changes)Other Breaking Changes

We’ve kept the breaking changes in React 17 to the minimum. For example, it doesn’t remove any of the methods that have been deprecated in the previous releases. However, it does include a few other breaking changes that have been relatively safe in our experience. In total, we’ve had to adjust fewer than 20 out of 100,000+ our components because of them.

### [](#aligning-with-browsers)Aligning with Browsers

We’ve made a couple of smaller changes related to the event system:

* The `onScroll` event **no longer bubbles** to prevent [common confusion](https://github.com/facebook/react/issues/15723).
* React `onFocus` and `onBlur` events have switched to using the native `focusin` and `focusout` events under the hood, which more closely match React’s existing behavior and sometimes provide extra information.
* Capture phase events (e.g. `onClickCapture`) now use real browser capture phase listeners.

These changes align React closer with the browser behavior and improve interoperability.

> Note
>
> Although React 17 switched from `focus` to `focusin` *under the hood* for the `onFocus` event, note that this has **not** affected the bubbling behavior. In React, `onFocus` event has always bubbled, and it continues to do so in React 17 because generally it is a more useful default. See [this sandbox](https://codesandbox.io/s/strange-albattani-7tqr7?file=/src/App.js) for the different checks you can add for different particular use cases.

### [](#no-event-pooling)No Event Pooling

React 17 removes the “event pooling” optimization from React. It doesn’t improve performance in modern browsers and confuses even experienced React users:

```
function handleChange(e) {
  setData(data => ({
    ...data,
    // This crashes in React 16 and earlier:
    text: e.target.value
  }));
}
```

This is because React reused the event objects between different events for performance in old browsers, and set all event fields to `null` in between them. With React 16 and earlier, you have to call `e.persist()` to properly use the event, or read the property you need earlier.

**In React 17, this code works as you would expect. The old event pooling optimization has been fully removed, so you can read the event fields whenever you need them.**

This is a behavior change, which is why we’re marking it as breaking, but in practice we haven’t seen it break anything at Facebook. (Maybe it even fixed a few bugs!) Note that `e.persist()` is still available on the React event object, but now it doesn’t do anything.

### [](#effect-cleanup-timing)Effect Cleanup Timing

We are making the timing of the `useEffect` cleanup function more consistent.

```
useEffect(() => {
  // This is the effect itself.
  return () => {    // This is its cleanup.  };});
```

Most effects don’t need to delay screen updates, so React runs them asynchronously soon after the update has been reflected on the screen. (For the rare cases where you need an effect to block paint, e.g. to measure and position a tooltip, prefer `useLayoutEffect`.)

However, when a component is unmounting, effect *cleanup* functions used to run synchronously (similar to `componentWillUnmount` being synchronous in classes). We’ve found that this is not ideal for larger apps because it slows down large screen transitions (e.g. switching tabs).

**In React 17, the effect cleanup function always runs asynchronously — for example, if the component is unmounting, the cleanup runs *after* the screen has been updated.**

This mirrors how the effects themselves run more closely. In the rare cases where you might want to rely on the synchronous execution, you can switch to `useLayoutEffect` instead.

> Note
>
> You might be wondering whether this means that you’ll now be unable to fix warnings about `setState` on unmounted components. Don’t worry — React specifically checks for this case, and does *not* fire `setState` warnings in the short gap between unmounting and the cleanup. **So code cancelling requests or intervals can almost always stay the same.**

Additionally, React 17 will always execute all effect cleanup functions (for all components) before it runs any new effects. React 16 only guaranteed this ordering for effects within a component.

#### [](#potential-issues)Potential Issues

We’ve only seen a couple of components break with this change, although reusable libraries may need to test it more thoroughly. One example of problematic code may look like this:

```
useEffect(() => {
  someRef.current.someSetupMethod();
  return () => {
    someRef.current.someCleanupMethod();
  };
});
```

The problem is that `someRef.current` is mutable, so by the time the cleanup function runs, it may have been set to `null`. The solution is to capture any mutable values *inside* the effect:

```
useEffect(() => {
  const instance = someRef.current;
  instance.someSetupMethod();
  return () => {
    instance.someCleanupMethod();
  };
});
```

We don’t expect this to be a common problem because [our `eslint-plugin-react-hooks/exhaustive-deps` lint rule](https://github.com/facebook/react/tree/main/packages/eslint-plugin-react-hooks) (make sure you use it!) has always warned about this.

### [](#consistent-errors-for-returning-undefined)Consistent Errors for Returning Undefined

In React 16 and earlier, returning `undefined` has always been an error:

```
function Button() {
  return; // Error: Nothing was returned from render
}
```

This is in part because it’s easy to return `undefined` unintentionally:

```
function Button() {
  // We forgot to write return, so this component returns undefined.
  // React surfaces this as an error instead of ignoring it.
  <button />;
}
```

Previously, React only did this for class and function components, but did not check the return values of `forwardRef` and `memo` components. This was due to a coding mistake.

**In React 17, the behavior for `forwardRef` and `memo` components is consistent with regular function and class components. Returning `undefined` from them is an error.**

```
let Button = forwardRef(() => {
  // We forgot to write return, so this component returns undefined.
  // React 17 surfaces this as an error instead of ignoring it.
  <button />;
});

let Button = memo(() => {
  // We forgot to write return, so this component returns undefined.
  // React 17 surfaces this as an error instead of ignoring it.
  <button />;
});
```

For the cases where you want to render nothing intentionally, return `null` instead.

### [](#native-component-stacks)Native Component Stacks

When you throw an error in the browser, the browser gives you a stack trace with JavaScript function names and their locations. However, JavaScript stacks are often not enough to diagnose a problem because the React tree hierarchy can be just as important. You want to know not just that a `Button` threw an error, but *where in the React tree* that `Button` is.

To solve this, React 16 started printing “component stacks” when you have an error. Still, they used to be inferior to the native JavaScript stacks. In particular, they were not clickable in the console because React didn’t know where the function was declared in the source code. Additionally, they were [mostly useless in production](https://github.com/facebook/react/issues/12757). Unlike regular minified JavaScript stacks which can be automatically restored to the original function names with a sourcemap, with React component stacks you had to choose between production stacks and bundle size.

**In React 17, the component stacks are generated using a different mechanism that stitches them together from the regular native JavaScript stacks. This lets you get the fully symbolicated React component stack traces in a production environment.**

The way React implements this is somewhat unorthodox. Currently, the browsers don’t provide a way to get a function’s stack frame (source file and location). So when React catches an error, it will now *reconstruct* its component stack by throwing (and catching) a temporary error from inside each of the components above, when it is possible. This adds a small performance penalty for crashes, but it only happens once per component type.

If you’re curious, you can read more details in [this pull request](https://github.com/facebook/react/pull/18561), but for the most part this exact mechanism shouldn’t affect your code. From your perspective, the new feature is that component stacks are now clickable (because they rely on the native browser stack frames), and that you can decode them in production like you would with regular JavaScript errors.

The part that constitutes a breaking change is that for this to work, React re-executes parts of some of the React functions and React class constructors above in the stack after an error is captured. Since render functions and class constructors shouldn’t have side effects (which is also important for server rendering), this should not pose any practical problems.

### [](#removing-private-exports)Removing Private Exports

Finally, the last notable breaking change is that we’ve removed some React internals that were previously exposed to other projects. In particular, [React Native for Web](https://github.com/necolas/react-native-web) used to depend on some internals of the event system, but that dependency was fragile and used to break.

**In React 17, these private exports have been removed. As far as we’re aware, React Native for Web was the only project using them, and they have already completed a migration to a different approach that doesn’t depend on those private exports.**

This means that the older versions of React Native for Web won’t be compatible with React 17, but the newer versions will work with it. In practice, this doesn’t change much because React Native for Web had to release new versions to adapt to internal React changes anyway.

Additionally, we’ve removed the `ReactTestUtils.SimulateNative` helper methods. They have never been documented, didn’t do quite what their names implied, and didn’t work with the changes we’ve made to the event system. If you want a convenient way to fire native browser events in tests, check out the [React Testing Library](https://testing-library.com/docs/dom-testing-library/api-events) instead.

## [](#installation)Installation

We encourage you to try React 17.0 Release Candidate soon and [raise any issues](https://github.com/facebook/react/issues) for the problems you might encounter in the migration. **Keep in mind that a release candidate is more likely to contain bugs than a stable release, so don’t deploy it to production yet.**

To install React 17 RC with npm, run:

```
npm install react@17.0.0-rc.3 react-dom@17.0.0-rc.3
```

To install React 17 RC with Yarn, run:

```
yarn add react@17.0.0-rc.3 react-dom@17.0.0-rc.3
```

We also provide UMD builds of React via a CDN:

```
<script crossorigin src="https://unpkg.com/react@17.0.0-rc.3/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17.0.0-rc.3/umd/react-dom.production.min.js"></script>
```

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2020-08-10-react-v17-rc.md)

----
url: https://legacy.reactjs.org/blog/2019/11/06/building-great-user-experiences-with-concurrent-mode-and-suspense.html
----

November 06, 2019 by [Joseph Savona](https://twitter.com/en_JS)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

At React Conf 2019 we announced an [experimental release](/docs/concurrent-mode-adoption.html#installation) of React that supports Concurrent Mode and Suspense. In this post we’ll introduce best practices for using them that we’ve identified through the process of building [the new facebook.com](https://twitter.com/facebook/status/1123322299418124289).

> This post will be most relevant to people working on *data fetching libraries* for React.
>
> It shows how to best integrate them with Concurrent Mode and Suspense. The patterns introduced here are based on [Relay](https://relay.dev/docs/en/experimental/step-by-step) — our library for building data-driven UIs with GraphQL. However, the ideas in this post **apply to other GraphQL clients as well as libraries using REST** or other approaches.

This post is **aimed at library authors**. If you’re primarily an application developer, you might still find some interesting ideas here, but don’t feel like you have to read it in its entirety.

## [](#talk-videos)Talk Videos

If you prefer to watch videos, some of the ideas from this blog post have been referenced in several React Conf 2019 presentations:

* [Data Fetching with Suspense in Relay](https://www.youtube.com/watch?v=Tl0S7QkxFE4\&list=PLPxbbTqCLbGHPxZpw4xj_Wwg8-fdNxJRh\&index=15\&t=0s) by [Joe Savona](https://twitter.com/en_JS)
* [Building the New Facebook with React and Relay](https://www.youtube.com/watch?v=KT3XKDBZW7M\&list=PLPxbbTqCLbGHPxZpw4xj_Wwg8-fdNxJRh\&index=4) by [Ashley Watkins](https://twitter.com/catchingash)
* [React Conf Keynote](https://www.youtube.com/watch?v=uXEEL9mrkAQ\&list=PLPxbbTqCLbGHPxZpw4xj_Wwg8-fdNxJRh\&index=2) by [Yuzhi Zheng](https://twitter.com/yuzhiz)

This post presents a deeper dive on implementing a data fetching library with Suspense.

## [](#putting-user-experience-first)Putting User Experience First

The React team and community has long placed a deserved emphasis on developer experience: ensuring that React has good error messages, focusing on components as a way to reason locally about app behavior, crafting APIs that are predictable and encourage correct usage by design, etc. But we haven’t provided enough guidance on the best ways to achieve a great *user* experience in large apps.

For example, the React team has focused on *framework* performance and providing tools for developers to debug and tune application performance (e.g. `React.memo`). But we haven’t been as opinionated about the *high-level patterns* that make the difference between fast, fluid apps and slow, janky ones. We always want to ensure that React remains approachable to new users and supports a variety of use-cases — not every app has to be “blazing” fast. But as a community we can and should aim high. **We should make it as easy as possible to build apps that start fast and stay fast,** even as they grow in complexity, for users on varying devices and networks around the world.

[Concurrent Mode](/docs/concurrent-mode-intro.html) and [Suspense](/docs/concurrent-mode-suspense.html) are experimental features that can help developers achieve this goal. We first introduced them at [JSConf Iceland in 2018](/blog/2018/03/01/sneak-peek-beyond-react-16.html), intentionally sharing details very early to give the community time to digest the new concepts and to set the stage for subsequent changes. Since then we’ve completed related work, such as the new Context API and the introduction of Hooks, which are designed in part to help developers naturally write code that is more compatible with Concurrent Mode. But we didn’t want to implement these features and release them without validating that they work. So over the past year, the React, Relay, web infrastructure, and product teams at Facebook have all collaborated closely to build a new version of facebook.com that deeply integrates Concurrent Mode and Suspense to create an experience with a more fluid and app-like feel.

Thanks to this project, we’re more confident than ever that Concurrent Mode and Suspense can make it easier to deliver great, *fast* user experiences. But doing so requires rethinking how we approach loading code and data for our apps. Effectively all of the data-fetching on the new facebook.com is powered by [Relay Hooks](https://relay.dev/docs/en/experimental/step-by-step) — new Hooks-based Relay APIs that integrate with Concurrent Mode and Suspense out of the box.

Relay Hooks — and GraphQL — won’t be for everyone, and that’s ok! Through our work on these APIs we’ve identified a set of more general patterns for using Suspense. **Even if Relay isn’t the right fit for you, we think the key patterns we’ve introduced with Relay Hooks can be adapted to other frameworks.**

## [](#best-practices-for-suspense)Best Practices for Suspense

It’s tempting to focus only on the total startup time for an app — but it turns out that users’ perception of performance is determined by more than the absolute loading time. For example, when comparing two apps with the same absolute startup time, our research shows that users will generally perceive the one with fewer intermediate loading states and fewer layout changes as having loaded faster. Suspense is a powerful tool for carefully orchestrating an elegant loading sequence with a few, well-defined states that progressively reveal content. But improving perceived performance only goes so far — our apps still shouldn’t take forever to fetch all of their code, data, images, and other assets.

The traditional approach to loading data in React apps involves what we refer to as [“fetch-on-render”](/docs/concurrent-mode-suspense.html#approach-1-fetch-on-render-not-using-suspense). First we render a component with a spinner, then fetch data on mount (`componentDidMount` or `useEffect`), and finally update to render the resulting data. It’s certainly *possible* to use this pattern with Suspense: instead of initially rendering a placeholder itself, a component can “suspend” — indicate to React that it isn’t ready yet. This will tell React to find the nearest ancestor `<Suspense fallback={<Placeholder/>}>`, and render its fallback instead. If you watched earlier Suspense demos this example may feel familiar — it’s how we originally imagined using Suspense for data-fetching.

It turns out that this approach has some limitations. Consider a page that shows a social media post by a user, along with comments on that post. That might be structured as a `<Post>` component that renders both the post body and a `<CommentList>` to show the comments. Using the fetch-on-render approach described above to implement this could cause sequential round trips (sometimes referred to as a “waterfall”). First the data for the `<Post>` component would be fetched and then the data for `<CommentList>` would be fetched, increasing the time it takes to show the full page.

There’s also another often-overlooked downside to this approach. If `<Post>` eagerly requires (or imports) the `<CommentList>` component, our app will have to wait to show the post *body* while the code for the *comments* is downloading. We could lazily load `<CommentList>`, but then that would delay fetching comments data and increase the time to show the full page. How do we resolve this problem without compromising on the user experience?

## [](#render-as-you-fetch)Render As You Fetch

The fetch-on-render approach is widely used by React apps today and can certainly be used to create great apps. But can we do even better? Let’s step back and consider our goal.

In the above `<Post>` example, we’d ideally show the more important content — the post body — as early as possible, *without* negatively impacting the time to show the full page (including comments). Let’s consider the key constraints on any solution and look at how we can achieve them:

* Showing the more important content (the post body) as early as possible means that we need to load the code and data for the view incrementally. We *don’t want to block showing the post body* on the code for `<CommentList>` being downloaded, for example.
* At the same time we don’t want to increase the time to show the full page including comments. So we need to *start loading the code and data for the comments* as soon as possible, ideally *in parallel* with loading the post body.

This might sound difficult to achieve — but these constraints are actually incredibly helpful. They rule out a large number of approaches and spell out a solution for us. This brings us to the key patterns we’ve implemented in Relay Hooks, and that can be adapted to other data-fetching libraries. We’ll look at each one in turn and then see how they add up to achieve our goal of fast, delightful loading experiences:

1. Parallel data and view trees
2. Fetch in event handlers
3. Load data incrementally
4. Treat code like data

### [](#parallel-data-and-view-trees)Parallel Data and View Trees

One of the most appealing things about the fetch-on-render pattern is that it colocates *what* data a component needs with *how* to render that data. This colocation is great — an example of how it makes sense to group code by concerns and not by technologies. All the issues we saw above were due to *when* we fetch data in this approach: upon rendering. We need to be able to fetch data *before* we’ve rendered the component. The only way to achieve that is by extracting the data dependencies into parallel data and view trees.

Here’s how that works in Relay Hooks. Continuing our example of a social media post with body and comments, here’s how we might define it with Relay Hooks:

```
// Post.js
function Post(props) {
  // Given a reference to some post - `props.post` - *what* data
  // do we need about that post?
  const postData = useFragment(graphql`
    fragment PostData on Post @refetchable(queryName: "PostQuery") {
      author
      title
      # ...  more fields ...
    }
  `, props.post);

  // Now that we have the data, how do we render it?
  return (
    <div>
      <h1>{postData.title}</h1>
      <h2>by {postData.author}</h2>
      {/* more fields  */}
    </div>
  );
}
```

Although the GraphQL is written within the component, Relay has a build step (Relay Compiler) that extracts these data-dependencies into separate files and aggregates the GraphQL for each view into a single query. So we get the benefit of colocating concerns, while at runtime having parallel data and view trees. Other frameworks could achieve a similar effect by allowing developers to define data-fetching logic in a sibling file (maybe `Post.data.js`), or perhaps integrate with a bundler to allow defining data dependencies with UI code and automatically extracting it, similar to Relay Compiler.

The key is that regardless of the technology we’re using to load our data — GraphQL, REST, etc — we can separate *what* data to load from how and when to actually load it. But once we do that, how and when *do* we fetch our data?

### [](#fetch-in-event-handlers)Fetch in Event Handlers

Imagine that we’re about to navigate from a list of a user’s posts to the page for a specific post. We’ll need to download the code for that page — `Post.js` — and also fetch its data.

Waiting until we render the component has problems as we saw above. The key is to start fetching code and data for a new view *in the same event handler that triggers showing that view*. We can either fetch the data within our router — if our router supports preloading data for routes — or in the click event on the link that triggered the navigation. It turns out that the React Router folks are already hard at work on building APIs to support preloading data for routes. But other routing frameworks can implement this idea too.

Conceptually, we want every route definition to include two things: what component to render and what data to preload, as a function of the route/url params. Here’s what such a route definition *might* look like. This example is loosely inspired by React Router’s route definitions and is *primarily intended to demonstrate the concept, not a specific API*:

```
// PostRoute.js (GraphQL version)

// Relay generated query for loading Post data
import PostQuery from './__generated__/PostQuery.graphql';

const PostRoute = {
  // a matching expression for which paths to handle
  path: '/post/:id',

  // what component to render for this route
  component: React.lazy(() => import('./Post')),

  // data to load for this route, as function of the route
  // parameters
  prepare: routeParams => {
    // Relay extracts queries from components, allowing us to reference
    // the data dependencies -- data tree -- from outside.
    const postData = preloadQuery(PostQuery, {
      postId: routeParams.id,
    });

    return { postData };
  },
};

export default PostRoute;
```

Given such a definition, a router can:

* Match a URL to a route definition.
* Call the `prepare()` function to start loading that route’s data. Note that `prepare()` is synchronous — *we don’t wait for the data to be ready*, since we want to start rendering more important parts of the view (like the post body) as quickly as possible.
* Pass the preloaded data to the component. If the component is ready — the `React.lazy` dynamic import has completed — the component will render and try to access its data. If not, `React.lazy` will suspend until the code is ready.

This approach can be generalized to other data-fetching solutions. An app that uses REST might define a route like this:

```
// PostRoute.js (REST version)

// Manually written logic for loading the data for the component
import PostData from './Post.data';

const PostRoute = {
  // a matching expression for which paths to handle
  path: '/post/:id',

  // what component to render for this route
  component: React.lazy(() => import('./Post')),

  // data to load for this route, as function of the route
  // parameters
  prepare: routeParams => {
    const postData = preloadRestEndpoint(
      PostData.endpointUrl, 
      {
        postId: routeParams.id,
      },
    );
    return { postData };
  },
};

export default PostRoute;
```

This same approach can be employed not just for routing, but in other places where we show content lazily or based on user interaction. For example, a tab component could eagerly load the first tab’s code and data, and then use the same pattern as above to load the code and data for other tabs in the tab-change event handler. A component that displays a modal could preload the code and data for the modal in the click handler that triggers opening the modal, and so on.

Once we’ve implemented the ability to start loading code and data for a view independently, we have the option to go one step further. Consider a `<Link to={path} />` component that links to a route. If the user hovers over that link, there’s a reasonable chance they’ll click it. And if they press the mouse down, there’s an even better chance that they’ll complete the click. If we can load code and data for a view *after* the user clicks, we can also start that work *before* they click, getting a head start on preparing the view.

Best of all, we can centralize that logic in a few key places — a router or core UI components — and get any performance benefits automatically throughout our app. Of course preloading isn’t always beneficial. It’s something an application would tune based on the user’s device or network speed to avoid eating up user’s data plans. But the pattern here makes it easier to centralize the implementation of preloading and the decision of whether to enable it or not.

### [](#load-data-incrementally)Load Data Incrementally

The above patterns — parallel data/view trees and fetching in event handlers — let us start loading all the data for a view earlier. But we still want to be able to show more important parts of the view without waiting for *all* of our data. At Facebook we’ve implemented support for this in GraphQL and Relay in the form of some new GraphQL directives (annotations that affect how/when data is delivered, but not what data). These new directives, called `@defer` and `@stream`, allow us to retrieve data incrementally. For example, consider our `<Post>` component from above. We want to show the body without waiting for the comments to be ready. We can achieve this with `@defer` and `<Suspense>`:

```
// Post.js
function Post(props) {
  const postData = useFragment(graphql`
    fragment PostData on Post {
      author
      title

      # fetch data for the comments, but don't block on it being ready
      ...CommentList @defer
    }
  `, props.post);

  return (
    <div>
      <h1>{postData.title}</h1>
      <h2>by {postData.author}</h2>
      {/* @defer pairs naturally with <Suspense> to make the UI non-blocking too */}
      <Suspense fallback={<Spinner/>}>
        <CommentList post={postData} />
      </Suspense>
    </div>
  );
}
```

Here, our GraphQL server will stream back the results, first returning the `author` and `title` fields and then returning the comment data when it’s ready. We wrap `<CommentList>` in a `<Suspense>` boundary so that we can render the post body before `<CommentList>` and its data are ready. This same pattern can be applied to other frameworks as well. For example, apps that call a REST API might make parallel requests to fetch the body and comments data for a post to avoid blocking on all the data being ready.

### [](#treat-code-like-data)Treat Code Like Data

But there’s one thing that’s still missing. We’ve shown how to preload *data* for a route — but what about code? The example above cheated a bit and used `React.lazy`. However, `React.lazy` is, as the name implies, *lazy*. It won’t start downloading code until the lazy component is actually rendered — it’s “fetch-on-render” for code!

To solve this, the React team is considering APIs that would allow bundle splitting and eager preloading for code as well. That would allow a user to pass some form of lazy component to a router, and for the router to trigger loading the code alongside its data as early as possible.

## [](#putting-it-all-together)Putting It All Together

To recap, achieving a great loading experience means that we need to **start loading code and data as early as possible, but without waiting for all of it to be ready**. Parallel data and view trees allow us to load the data for a view in parallel with loading the view (code) itself. Fetching in an event handler means we can start loading data as early as possible, and even optimistically preload a view when we have enough confidence that a user will navigate to it. Loading data incrementally allows us to load important data earlier without delaying the fetching of less important data. And treating code as data — and preloading it with similar APIs — allows us to load it earlier too.

## [](#using-these-patterns)Using These Patterns

These patterns aren’t just ideas — we’ve implemented them in Relay Hooks and are using them in production throughout the new facebook.com (which is currently in beta testing). If you’re interested in using or learning more about these patterns, here are some resources:

* The [React Concurrent docs](/docs/concurrent-mode-intro.html) explore how to use Concurrent Mode and Suspense and go into more detail about many of these patterns. It’s a great resource to learn more about the APIs and use-cases they support.

* The [experimental release of Relay Hooks](https://relay.dev/docs/en/experimental/step-by-step) implements the patterns described here.

* We’ve implemented two similar example apps that demonstrate these concepts:

  * The [Relay Hooks example app](https://github.com/relayjs/relay-examples/tree/master/issue-tracker) uses GitHub’s public GraphQL API to implement a simple issue tracker app. It includes nested route support with code and data preloading. The code is fully commented — we encourage cloning the repo, running the app locally, and exploring how it works.
  * We also have a [non-GraphQL version of the app](https://github.com/gaearon/suspense-experimental-github-demo) that demonstrates how these concepts can be applied to other data-fetching libraries.

While the APIs around Concurrent Mode and Suspense are [still experimental](/docs/concurrent-mode-adoption.html#who-is-this-experimental-release-for), we’re confident that the ideas in this post are proven by practice. However, we understand that Relay and GraphQL aren’t the right fit for everyone. That’s ok! **We’re actively exploring how to generalize these patterns to approaches such as REST,** and are exploring ideas for a more generic (ie non-GraphQL) API for composing a tree of data dependencies. In the meantime, we’re excited to see what new libraries will emerge that implement the patterns described in this post to make it easier to build great, *fast* user experiences.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2019-11-06-building-great-user-experiences-with-concurrent-mode-and-suspense.md)

----
url: https://legacy.reactjs.org/blog/2013/07/11/react-v0-4-prop-validation-and-default-values.html
----

July 11, 2013 by [Paul O’Shannessy](https://twitter.com/zpao)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

Many of the questions we got following the public launch of React revolved around `props`, specifically that people wanted to do validation and to make sure their components had sensible defaults.

## [](#validation)Validation

Oftentimes you want to validate your `props` before you use them. Perhaps you want to ensure they are a specific type. Or maybe you want to restrict your prop to specific values. Or maybe you want to make a specific prop required. This was always possible — you could have written validations in your `render` or `componentWillReceiveProps` functions, but that gets clunky fast.

React v0.4 will provide a nice easy way for you to use built-in validators, or to even write your own.

```
React.createClass({
  propTypes: {
    // An optional string prop named "description".
    description: React.PropTypes.string,

    // A required enum prop named "category".
    category: React.PropTypes.oneOf(['News','Photos']).isRequired,

    // A prop named "dialog" that requires an instance of Dialog.
    dialog: React.PropTypes.instanceOf(Dialog).isRequired
  },
  ...
});
```

## [](#default-values)Default Values

One common pattern we’ve seen with our React code is to do something like this:

```
React.createClass({
  render: function() {
    var value = this.props.value || 'default value';
    return <div>{value}</div>;
  }
});
```

Do this for a few `props` across a few components and now you have a lot of redundant code. Starting with React v0.4, you can provide default values in a declarative way:

```
React.createClass({
  getDefaultProps: function() {
    return {
      value: 'default value'
    };
  }
  ...
});
```

We will use the cached result of this function before each `render`. We also perform all validations before each `render` to ensure that you have all of the data you need in the right form before you try to use it.

***

Both of these features are entirely optional. We’ve found them to be increasingly valuable at Facebook as our applications grow and evolve, and we hope others find them useful as well.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2013-07-11-react-v0-4-prop-validation-and-default-values.md)

----
url: https://react.dev/learn/extracting-state-logic-into-a-reducer
----

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';
import AddTask from './AddTask.js';
import TaskList from './TaskList.js';

export default function TaskApp() {
  const [tasks, setTasks] = useState(initialTasks);

  function handleAddTask(text) {
    setTasks([
      ...tasks,
      {
        id: nextId++,
        text: text,
        done: false,
      },
    ]);
  }

  function handleChangeTask(task) {
    setTasks(
      tasks.map((t) => {
        if (t.id === task.id) {
          return task;
        } else {
          return t;
        }
      })
    );
  }

  function handleDeleteTask(taskId) {
    setTasks(tasks.filter((t) => t.id !== taskId));
  }

  return (
    <>
      <h1>Prague itinerary</h1>
      <AddTask onAddTask={handleAddTask} />
      <TaskList
        tasks={tasks}
        onChangeTask={handleChangeTask}
        onDeleteTask={handleDeleteTask}
      />
    </>
  );
}

let nextId = 3;
const initialTasks = [
  {id: 0, text: 'Visit Kafka Museum', done: true},
  {id: 1, text: 'Watch a puppet show', done: false},
  {id: 2, text: 'Lennon Wall pic', done: false},
];
```

```
function handleAddTask(text) {

  setTasks([

    ...tasks,

    {

      id: nextId++,

      text: text,

      done: false,

    },

  ]);

}



function handleChangeTask(task) {

  setTasks(

    tasks.map((t) => {

      if (t.id === task.id) {

        return task;

      } else {

        return t;

      }

    })

  );

}



function handleDeleteTask(taskId) {

  setTasks(tasks.filter((t) => t.id !== taskId));

}
```

Remove all the state setting logic. What you are left with are three event handlers:

* `handleAddTask(text)` is called when the user presses “Add”.
* `handleChangeTask(task)` is called when the user toggles a task or presses “Save”.
* `handleDeleteTask(taskId)` is called when the user presses “Delete”.

Managing state with reducers is slightly different from directly setting state. Instead of telling React “what to do” by setting state, you specify “what the user just did” by dispatching “actions” from your event handlers. (The state update logic will live elsewhere!) So instead of “setting `tasks`” via an event handler, you’re dispatching an “added/changed/deleted a task” action. This is more descriptive of the user’s intent.

```
function handleAddTask(text) {

  dispatch({

    type: 'added',

    id: nextId++,

    text: text,

  });

}



function handleChangeTask(task) {

  dispatch({

    type: 'changed',

    task: task,

  });

}



function handleDeleteTask(taskId) {

  dispatch({

    type: 'deleted',

    id: taskId,

  });

}
```

The object you pass to `dispatch` is called an “action”:

```
function handleDeleteTask(taskId) {

  dispatch(

    // "action" object:

    {

      type: 'deleted',

      id: taskId,

    }

  );

}
```

It is a regular JavaScript object. You decide what to put in it, but generally it should contain the minimal information about *what happened*. (You will add the `dispatch` function itself in a later step.)

### Note

An action object can have any shape.

By convention, it is common to give it a string `type` that describes what happened, and pass any additional information in other fields. The `type` is specific to a component, so in this example either `'added'` or `'added_task'` would be fine. Choose a name that says what happened!

```
dispatch({

  // specific to component

  type: 'what_happened',

  // other fields go here

});
```

### Step 2: Write a reducer function[](#step-2-write-a-reducer-function "Link for Step 2: Write a reducer function ")

A reducer function is where you will put your state logic. It takes two arguments, the current state and the action object, and it returns the next state:

```
function yourReducer(state, action) {

  // return next state for React to set

}
```

React will set the state to what you return from the reducer.

To move your state setting logic from your event handlers to a reducer function in this example, you will:

1. Declare the current state (`tasks`) as the first argument.
2. Declare the `action` object as the second argument.
3. Return the *next* state from the reducer (which React will set the state to).

Here is all the state setting logic migrated to a reducer function:

```
function tasksReducer(tasks, action) {

  if (action.type === 'added') {

    return [

      ...tasks,

      {

        id: action.id,

        text: action.text,

        done: false,

      },

    ];

  } else if (action.type === 'changed') {

    return tasks.map((t) => {

      if (t.id === action.task.id) {

        return action.task;

      } else {

        return t;

      }

    });

  } else if (action.type === 'deleted') {

    return tasks.filter((t) => t.id !== action.id);

  } else {

    throw Error('Unknown action: ' + action.type);

  }

}
```

Because the reducer function takes state (`tasks`) as an argument, you can **declare it outside of your component.** This decreases the indentation level and can make your code easier to read.

### Note

The code above uses if/else statements, but it’s a convention to use [switch statements](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/switch) inside reducers. The result is the same, but it can be easier to read switch statements at a glance.

We’ll be using them throughout the rest of this documentation like so:

```
function tasksReducer(tasks, action) {

  switch (action.type) {

    case 'added': {

      return [

        ...tasks,

        {

          id: action.id,

          text: action.text,

          done: false,

        },

      ];

    }

    case 'changed': {

      return tasks.map((t) => {

        if (t.id === action.task.id) {

          return action.task;

        } else {

          return t;

        }

      });

    }

    case 'deleted': {

      return tasks.filter((t) => t.id !== action.id);

    }

    default: {

      throw Error('Unknown action: ' + action.type);

    }

  }

}
```

We recommend wrapping each `case` block into the `{` and `}` curly braces so that variables declared inside of different `case`s don’t clash with each other. Also, a `case` should usually end with a `return`. If you forget to `return`, the code will “fall through” to the next `case`, which can lead to mistakes!

If you’re not yet comfortable with switch statements, using if/else is completely fine.

##### Deep Dive#### Why are reducers called this way?[](#why-are-reducers-called-this-way "Link for Why are reducers called this way? ")

Although reducers can “reduce” the amount of code inside your component, they are actually named after the [`reduce()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce) operation that you can perform on arrays.

The `reduce()` operation lets you take an array and “accumulate” a single value out of many:

```
const arr = [1, 2, 3, 4, 5];

const sum = arr.reduce(

  (result, number) => result + number

); // 1 + 2 + 3 + 4 + 5
```

The function you pass to `reduce` is known as a “reducer”. It takes the *result so far* and the *current item,* then it returns the *next result.* React reducers are an example of the same idea: they take the *state so far* and the *action*, and return the *next state.* In this way, they accumulate actions over time into state.

You could even use the `reduce()` method with an `initialState` and an array of `actions` to calculate the final state by passing your reducer function to it:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import tasksReducer from './tasksReducer.js';

let initialState = [];
let actions = [
  {type: 'added', id: 1, text: 'Visit Kafka Museum'},
  {type: 'added', id: 2, text: 'Watch a puppet show'},
  {type: 'deleted', id: 1},
  {type: 'added', id: 3, text: 'Lennon Wall pic'},
];

let finalState = actions.reduce(tasksReducer, initialState);

const output = document.getElementById('output');
output.textContent = JSON.stringify(finalState, null, 2);
```

You probably won’t need to do this yourself, but this is similar to what React does!

### Step 3: Use the reducer from your component[](#step-3-use-the-reducer-from-your-component "Link for Step 3: Use the reducer from your component ")

Finally, you need to hook up the `tasksReducer` to your component. Import the `useReducer` Hook from React:

```
import { useReducer } from 'react';
```

Then you can replace `useState`:

```
const [tasks, setTasks] = useState(initialTasks);
```

with `useReducer` like so:

```
const [tasks, dispatch] = useReducer(tasksReducer, initialTasks);
```

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useReducer } from 'react';
import AddTask from './AddTask.js';
import TaskList from './TaskList.js';

export default function TaskApp() {
  const [tasks, dispatch] = useReducer(tasksReducer, initialTasks);

  function handleAddTask(text) {
    dispatch({
      type: 'added',
      id: nextId++,
      text: text,
    });
  }

  function handleChangeTask(task) {
    dispatch({
      type: 'changed',
      task: task,
    });
  }

  function handleDeleteTask(taskId) {
    dispatch({
      type: 'deleted',
      id: taskId,
    });
  }

  return (
    <>
      <h1>Prague itinerary</h1>
      <AddTask onAddTask={handleAddTask} />
      <TaskList
        tasks={tasks}
        onChangeTask={handleChangeTask}
        onDeleteTask={handleDeleteTask}
      />
    </>
  );
}

function tasksReducer(tasks, action) {
  switch (action.type) {
    case 'added': {
      return [
        ...tasks,
        {
          id: action.id,
          text: action.text,
          done: false,
        },
      ];
    }
    case 'changed': {
      return tasks.map((t) => {
        if (t.id === action.task.id) {
          return action.task;
        } else {
          return t;
        }
      });
    }
    case 'deleted': {
      return tasks.filter((t) => t.id !== action.id);
    }
    default: {
      throw Error('Unknown action: ' + action.type);
    }
  }
}

let nextId = 3;
const initialTasks = [
  {id: 0, text: 'Visit Kafka Museum', done: true},
  {id: 1, text: 'Watch a puppet show', done: false},
  {id: 2, text: 'Lennon Wall pic', done: false},
];
```

If you want, you can even move the reducer to a different file:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useReducer } from 'react';
import AddTask from './AddTask.js';
import TaskList from './TaskList.js';
import tasksReducer from './tasksReducer.js';

export default function TaskApp() {
  const [tasks, dispatch] = useReducer(tasksReducer, initialTasks);

  function handleAddTask(text) {
    dispatch({
      type: 'added',
      id: nextId++,
      text: text,
    });
  }

  function handleChangeTask(task) {
    dispatch({
      type: 'changed',
      task: task,
    });
  }

  function handleDeleteTask(taskId) {
    dispatch({
      type: 'deleted',
      id: taskId,
    });
  }

  return (
    <>
      <h1>Prague itinerary</h1>
      <AddTask onAddTask={handleAddTask} />
      <TaskList
        tasks={tasks}
        onChangeTask={handleChangeTask}
        onDeleteTask={handleDeleteTask}
      />
    </>
  );
}

let nextId = 3;
const initialTasks = [
  {id: 0, text: 'Visit Kafka Museum', done: true},
  {id: 1, text: 'Watch a puppet show', done: false},
  {id: 2, text: 'Lennon Wall pic', done: false},
];
```

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
{
  "dependencies": {
    "immer": "1.7.3",
    "react": "latest",
    "react-dom": "latest",
    "react-scripts": "latest",
    "use-immer": "0.5.1"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject"
  },
  "devDependencies": {}
}
```

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useReducer } from 'react';
import Chat from './Chat.js';
import ContactList from './ContactList.js';
import { initialState, messengerReducer } from './messengerReducer';

export default function Messenger() {
  const [state, dispatch] = useReducer(messengerReducer, initialState);
  const message = state.message;
  const contact = contacts.find((c) => c.id === state.selectedId);
  return (
    <div>
      <ContactList
        contacts={contacts}
        selectedId={state.selectedId}
        dispatch={dispatch}
      />
      <Chat
        key={contact.id}
        message={message}
        contact={contact}
        dispatch={dispatch}
      />
    </div>
  );
}

const contacts = [
  {id: 0, name: 'Taylor', email: 'taylor@mail.com'},
  {id: 1, name: 'Alice', email: 'alice@mail.com'},
  {id: 2, name: 'Bob', email: 'bob@mail.com'},
];
```

[PreviousPreserving and Resetting State](/learn/preserving-and-resetting-state)

[NextPassing Data Deeply with Context](/learn/passing-data-deeply-with-context)

***

----
url: https://legacy.reactjs.org/blog/2019/08/15/new-react-devtools.html
----

August 15, 2019 by [Brian Vaughn](https://github.com/bvaughn)

We are excited to announce a new release of the React Developer Tools, available today in Chrome, Firefox, and (Chromium) Edge!

## [](#whats-changed)What’s changed?

A lot has changed in version 4! At a high level, this new version should offer significant performance gains and an improved navigation experience. It also offers full support for React Hooks, including inspecting nested objects.

[](/static/9552e88d7605ef4e547af89096a9225d/cd138/devtools-v4-screenshot.png)

[Visit the interactive tutorial](https://react-devtools-tutorial.now.sh/) to try out the new version or [see the changelog](https://github.com/facebook/react/blob/main/packages/react-devtools/CHANGELOG.md#400-august-15-2019) for demo videos and more details.

## [](#which-versions-of-react-are-supported)Which versions of React are supported?

**`react-dom`**

* `0`-`14.x`: Not supported
* `15.x`: Supported (except for the new component filters feature)
* `16.x`: Supported

**`react-native`**

* `0`-`0.61.x`: Not supported
* `0.62`: Supported

## [](#how-do-i-get-the-new-devtools)How do I get the new DevTools?

React DevTools is available as an extension for [Chrome](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?hl=en) and [Firefox](https://addons.mozilla.org/en-US/firefox/addon/react-devtools/). If you have already installed the extension, it should update automatically within the next couple of hours.

If you use the standalone shell (e.g. in React Native or Safari), you can install the new version [from NPM](https://www.npmjs.com/package/react-devtools):

```
npm install -g react-devtools@^4
```

## [](#where-did-all-of-the-dom-elements-go)Where did all of the DOM elements go?

The new DevTools provides a way to filter components from the tree to make it easier to navigate deeply nested hierarchies. Host nodes (e.g. HTML `<div>`, React Native `<View>`) are *hidden by default*, but this filter can be disabled:

## [](#how-do-i-get-the-old-version-back)How do I get the old version back?

If you are working with React Native version 60 (or older) you can install the previous release of DevTools from NPM:

```
npm install --dev react-devtools@^3
```

For older versions of React DOM (v0.14 or earlier) you will need to build the extension from source:

```
# Checkout the extension source
git clone https://github.com/facebook/react-devtools

cd react-devtools

# Checkout the previous release branch
git checkout v3

# Install dependencies and build the unpacked extension
yarn install
yarn build:extension

# Follow the on-screen instructions to complete installation
```

## [](#thank-you)Thank you!

We’d like to thank everyone who tested the early release of DevTools version 4. Your feedback helped improve this initial release significantly.

We still have many exciting features planned and feedback is always welcome! Please feel free to open a [GitHub issue](https://github.com/facebook/react/issues/new?labels=Component:%20Developer%20Tools) or tag [@reactjs on Twitter](https://twitter.com/reactjs).

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2019-08-15-new-react-devtools.md)

----
url: https://legacy.reactjs.org/blog/2015/12/18/react-components-elements-and-instances.html
----

December 18, 2015 by [Dan Abramov](https://twitter.com/dan_abramov)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

The difference between **components, their instances, and elements** confuses many React beginners. Why are there three different terms to refer to something that is painted on screen?

## [](#managing-the-instances)Managing the Instances

If you’re new to React, you probably only worked with component classes and instances before. For example, you may declare a `Button` *component* by creating a class. When the app is running, you may have several *instances* of this component on screen, each with its own properties and local state. This is the traditional object-oriented UI programming. Why introduce *elements*?

In this traditional UI model, it is up to you to take care of creating and destroying child component instances. If a `Form` component wants to render a `Button` component, it needs to create its instance, and manually keep it up to date with any new information.

```
class Form extends TraditionalObjectOrientedView {
  render() {
    // Read some data passed to the view
    const { isSubmitted, buttonText } = this.attrs;

    if (!isSubmitted && !this.button) {
      // Form is not yet submitted. Create the button!
      this.button = new Button({
        children: buttonText,
        color: 'blue'
      });
      this.el.appendChild(this.button.el);
    }

    if (this.button) {
      // The button is visible. Update its text!
      this.button.attrs.children = buttonText;
      this.button.render();
    }

    if (isSubmitted && this.button) {
      // Form was submitted. Destroy the button!
      this.el.removeChild(this.button.el);
      this.button.destroy();
    }

    if (isSubmitted && !this.message) {
      // Form was submitted. Show the success message!
      this.message = new Message({ text: 'Success!' });
      this.el.appendChild(this.message.el);
    }
  }
}
```

This is pseudocode, but it is more or less what you end up with when you write composite UI code that behaves consistently in an object-oriented way using a library like Backbone.

Each component instance has to keep references to its DOM node and to the instances of the children components, and create, update, and destroy them when the time is right. The lines of code grow as the square of the number of possible states of the component, and the parents have direct access to their children component instances, making it hard to decouple them in the future.

So how is React different?

## [](#elements-describe-the-tree)Elements Describe the Tree

In React, this is where the *elements* come to rescue. **An element is a plain object *describing* a component instance or DOM node and its desired properties.** It contains only information about the component type (for example, a `Button`), its properties (for example, its `color`), and any child elements inside it.

An element is not an actual instance. Rather, it is a way to tell React what you *want* to see on the screen. You can’t call any methods on the element. It’s just an immutable description object with two fields: `type: (string | ReactClass)` and `props: Object`[1](#fn-1).

### [](#dom-elements)DOM Elements

When an element’s `type` is a string, it represents a DOM node with that tag name, and `props` correspond to its attributes. This is what React will render. For example:

```
{
  type: 'button',
  props: {
    className: 'button button-blue',
    children: {
      type: 'b',
      props: {
        children: 'OK!'
      }
    }
  }
}
```

This element is just a way to represent the following HTML as a plain object:

```
<button class='button button-blue'>
  <b>
    OK!
  </b>
</button>
```

Note how elements can be nested. By convention, when we want to create an element tree, we specify one or more child elements as the `children` prop of their containing element.

What’s important is that both child and parent elements are *just descriptions and not the actual instances*. They don’t refer to anything on the screen when you create them. You can create them and throw them away, and it won’t matter much.

React elements are easy to traverse, don’t need to be parsed, and of course they are much lighter than the actual DOM elements—they’re just objects!

### [](#component-elements)Component Elements

However, the `type` of an element can also be a function or a class corresponding to a React component:

```
{
  type: Button,
  props: {
    color: 'blue',
    children: 'OK!'
  }
}
```

This is the core idea of React.

**An element describing a component is also an element, just like an element describing the DOM node. They can be nested and mixed with each other.**

This feature lets you define a `DangerButton` component as a `Button` with a specific `color` property value without worrying about whether `Button` renders to a DOM `<button>`, a `<div>`, or something else entirely:

```
const DangerButton = ({ children }) => ({
  type: Button,
  props: {
    color: 'red',
    children: children
  }
});
```

You can mix and match DOM and component elements in a single element tree:

```
const DeleteAccount = () => ({
  type: 'div',
  props: {
    children: [{
      type: 'p',
      props: {
        children: 'Are you sure?'
      }
    }, {
      type: DangerButton,
      props: {
        children: 'Yep'
      }
    }, {
      type: Button,
      props: {
        color: 'blue',
        children: 'Cancel'
      }
   }]
});
```

Or, if you prefer JSX:

```
const DeleteAccount = () => (
  <div>
    <p>Are you sure?</p>
    <DangerButton>Yep</DangerButton>
    <Button color='blue'>Cancel</Button>
  </div>
);
```

This mix and matching helps keep components decoupled from each other, as they can express both *is-a* and *has-a* relationships exclusively through composition:

* `Button` is a DOM `<button>` with specific properties.
* `DangerButton` is a `Button` with specific properties.
* `DeleteAccount` contains a `Button` and a `DangerButton` inside a `<div>`.

### [](#components-encapsulate-element-trees)Components Encapsulate Element Trees

When React sees an element with a function or class `type`, it knows to ask *that* component what element it renders to, given the corresponding `props`.

When it sees this element:

```
{
  type: Button,
  props: {
    color: 'blue',
    children: 'OK!'
  }
}
```

React will ask `Button` what it renders to. The `Button` will return this element:

```
{
  type: 'button',
  props: {
    className: 'button button-blue',
    children: {
      type: 'b',
      props: {
        children: 'OK!'
      }
    }
  }
}
```

React will repeat this process until it knows the underlying DOM tag elements for every component on the page.

React is like a child asking “what is Y” for every “X is Y” you explain to them until they figure out every little thing in the world.

Remember the `Form` example above? It can be written in React as follows[1](#fn-1):

```
const Form = ({ isSubmitted, buttonText }) => {
  if (isSubmitted) {
    // Form submitted! Return a message element.
    return {
      type: Message,
      props: {
        text: 'Success!'
      }
    };
  }

  // Form is still visible! Return a button element.
  return {
    type: Button,
    props: {
      children: buttonText,
      color: 'blue'
    }
  };
};
```

That’s it! For a React component, props are the input, and an element tree is the output.

**The returned element tree can contain both elements describing DOM nodes, and elements describing other components. This lets you compose independent parts of UI without relying on their internal DOM structure.**

We let React create, update, and destroy instances. We *describe* them with elements we return from the components, and React takes care of managing the instances.

### [](#components-can-be-classes-or-functions)Components Can Be Classes or Functions

In the code above, `Form`, `Message`, and `Button` are React components. They can either be written as functions, like above, or as classes descending from `React.Component`. These three ways to declare a component are mostly equivalent:

```
// 1) As a function of props
const Button = ({ children, color }) => ({
  type: 'button',
  props: {
    className: 'button button-' + color,
    children: {
      type: 'b',
      props: {
        children: children
      }
    }
  }
});

// 2) Using the React.createClass() factory
const Button = React.createClass({
  render() {
    const { children, color } = this.props;
    return {
      type: 'button',
      props: {
        className: 'button button-' + color,
        children: {
          type: 'b',
          props: {
            children: children
          }
        }
      }
    };
  }
});

// 3) As an ES6 class descending from React.Component
class Button extends React.Component {
  render() {
    const { children, color } = this.props;
    return {
      type: 'button',
      props: {
        className: 'button button-' + color,
        children: {
          type: 'b',
          props: {
            children: children
          }
        }
      }
    };
  }
}
```

When a component is defined as a class, it is a little bit more powerful than a function component. It can store some local state and perform custom logic when the corresponding DOM node is created or destroyed.

A function component is less powerful but is simpler, and acts like a class component with just a single `render()` method. Unless you need features available only in a class, we encourage you to use function components instead.

**However, whether functions or classes, fundamentally they are all components to React. They take the props as their input, and return the elements as their output.**

### [](#top-down-reconciliation)Top-Down Reconciliation

When you call:

```
ReactDOM.render({
  type: Form,
  props: {
    isSubmitted: false,
    buttonText: 'OK!'
  }
}, document.getElementById('root'));
```

React will ask the `Form` component what element tree it returns, given those `props`. It will gradually “refine” its understanding of your component tree in terms of simpler primitives:

```
// React: You told me this...
{
  type: Form,
  props: {
    isSubmitted: false,
    buttonText: 'OK!'
  }
}

// React: ...And Form told me this...
{
  type: Button,
  props: {
    children: 'OK!',
    color: 'blue'
  }
}

// React: ...and Button told me this! I guess I'm done.
{
  type: 'button',
  props: {
    className: 'button button-blue',
    children: {
      type: 'b',
      props: {
        children: 'OK!'
      }
    }
  }
}
```

This is a part of the process that React calls [reconciliation](/docs/reconciliation.html) which starts when you call [`ReactDOM.render()`](/docs/top-level-api.html#reactdom.render) or [`setState()`](/docs/component-api.html#setstate). By the end of the reconciliation, React knows the resulting DOM tree, and a renderer like `react-dom` or `react-native` applies the minimal set of changes necessary to update the DOM nodes (or the platform-specific views in case of React Native).

This gradual refining process is also the reason React apps are easy to optimize. If some parts of your component tree become too large for React to visit efficiently, you can tell it to [skip this “refining” and diffing certain parts of the tree if the relevant props have not changed](/docs/advanced-performance.html). It is very fast to calculate whether the props have changed if they are immutable, so React and immutability work great together, and can provide great optimizations with the minimal effort.

You might have noticed that this blog entry talks a lot about components and elements, and not so much about the instances. The truth is, instances have much less importance in React than in most object-oriented UI frameworks.

Only components declared as classes have instances, and you never create them directly: React does that for you. While [mechanisms for a parent component instance to access a child component instance](/docs/more-about-refs.html) exist, they are only used for imperative actions (such as setting focus on a field), and should generally be avoided.

React takes care of creating an instance for every class component, so you can write components in an object-oriented way with methods and local state, but other than that, instances are not very important in the React’s programming model and are managed by React itself.

## [](#summary)Summary

An *element* is a plain object describing what you want to appear on the screen in terms of the DOM nodes or other components. Elements can contain other elements in their props. Creating a React element is cheap. Once an element is created, it is never mutated.

A *component* can be declared in several different ways. It can be a class with a `render()` method. Alternatively, in simple cases, it can be defined as a function. In either case, it takes props as an input, and returns an element tree as the output.

When a component receives some props as an input, it is because a particular parent component returned an element with its `type` and these props. This is why people say that the props flows one way in React: from parents to children.

An *instance* is what you refer to as `this` in the component class you write. It is useful for [storing local state and reacting to the lifecycle events](/docs/component-api.html).

Function components don’t have instances at all. Class components have instances, but you never need to create a component instance directly—React takes care of this.

Finally, to create elements, use [`React.createElement()`](/docs/top-level-api.html#react.createelement), [JSX](/docs/jsx-in-depth.html), or an [element factory helper](/docs/top-level-api.html#react.createfactory). Don’t write elements as plain objects in the real code—just know that they are plain objects under the hood.

## [](#further-reading)Further Reading

* [Introducing React Elements](/blog/2014/10/14/introducing-react-elements.html)
* [Streamlining React Elements](/blog/2015/02/24/streamlining-react-elements.html)
* [React (Virtual) DOM Terminology](/docs/glossary.html)

***

1. All React elements require an additional `$$typeof: Symbol.for('react.element')` field declared on the object for [security reasons](https://github.com/facebook/react/pull/4832). It is omitted in the examples above. This blog entry uses inline objects for elements to give you an idea of what’s happening underneath but the code won’t run as is unless you either add `$$typeof` to the elements, or change the code to use `React.createElement()` or JSX.

   [↩](#fnref-1)

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2015-12-18-react-components-elements-and-instances.md)

----
url: https://legacy.reactjs.org/docs/animation.html
----

> Note:
>
> `ReactTransitionGroup` and `ReactCSSTransitionGroup` have been moved to the [`react-transition-group`](https://github.com/reactjs/react-transition-group/tree/v1-stable) package that is maintained by the community. Its 1.x branch is completely API-compatible with the existing addons. Please file bugs and feature requests in the [new repository](https://github.com/reactjs/react-transition-group/tree/v1-stable).

The [`ReactTransitionGroup`](#low-level-api-reacttransitiongroup) add-on component is a low-level API for animation, and [`ReactCSSTransitionGroup`](#high-level-api-reactcsstransitiongroup) is an add-on component for easily implementing basic CSS animations and transitions.

## [](#high-level-api-reactcsstransitiongroup)High-level API: ReactCSSTransitionGroup

`ReactCSSTransitionGroup` is a high-level API based on [`ReactTransitionGroup`](#low-level-api-reacttransitiongroup) and is an easy way to perform CSS transitions and animations when a React component enters or leaves the DOM. It’s inspired by the excellent [ng-animate](https://docs.angularjs.org/api/ngAnimate) library.

**Importing**

```
import ReactCSSTransitionGroup from 'react-transition-group'; // ES6
var ReactCSSTransitionGroup = require('react-transition-group'); // ES5 with npm
```

```
class TodoList extends React.Component {
  constructor(props) {
    super(props);
    this.state = {items: ['hello', 'world', 'click', 'me']};
    this.handleAdd = this.handleAdd.bind(this);
  }

  handleAdd() {
    const newItems = this.state.items.concat([
      prompt('Enter some text')
    ]);
    this.setState({items: newItems});
  }

  handleRemove(i) {
    let newItems = this.state.items.slice();
    newItems.splice(i, 1);
    this.setState({items: newItems});
  }

  render() {
    const items = this.state.items.map((item, i) => (
      <div key={i} onClick={() => this.handleRemove(i)}>
        {item}
      </div>
    ));

    return (
      <div>
        <button onClick={this.handleAdd}>Add Item</button>
        <ReactCSSTransitionGroup          transitionName="example"          transitionEnterTimeout={500}          transitionLeaveTimeout={300}>          {items}        </ReactCSSTransitionGroup>      </div>
    );
  }
}
```

> Note:
>
> You must provide [the `key` attribute](/docs/lists-and-keys.html#keys) for all children of `ReactCSSTransitionGroup`, even when only rendering a single item. This is how React will determine which children have entered, left, or stayed.

In this component, when a new item is added to `ReactCSSTransitionGroup` it will get the `example-enter` CSS class and the `example-enter-active` CSS class added in the next tick. This is a convention based on the `transitionName` prop.

You can use these classes to trigger a CSS animation or transition. For example, try adding this CSS and adding a new list item:

```
.example-enter {
  opacity: 0.01;
}

.example-enter.example-enter-active {
  opacity: 1;
  transition: opacity 500ms ease-in;
}

.example-leave {
  opacity: 1;
}

.example-leave.example-leave-active {
  opacity: 0.01;
  transition: opacity 300ms ease-in;
}
```

You’ll notice that animation durations need to be specified in both the CSS and the render method; this tells React when to remove the animation classes from the element and — if it’s leaving — when to remove the element from the DOM.

### [](#animate-initial-mounting)Animate Initial Mounting

`ReactCSSTransitionGroup` provides the optional prop `transitionAppear`, to add an extra transition phase at the initial mount of the component. There is generally no transition phase at the initial mount as the default value of `transitionAppear` is `false`. The following is an example which passes the prop `transitionAppear` with the value `true`.

```
render() {
  return (
    <ReactCSSTransitionGroup
      transitionName="example"
      transitionAppear={true}      transitionAppearTimeout={500}      transitionEnter={false}
      transitionLeave={false}>
      <h1>Fading at Initial Mount</h1>
    </ReactCSSTransitionGroup>
  );
}
```

During the initial mount `ReactCSSTransitionGroup` will get the `example-appear` CSS class and the `example-appear-active` CSS class added in the next tick.

```
.example-appear {
  opacity: 0.01;
}

.example-appear.example-appear-active {
  opacity: 1;
  transition: opacity .5s ease-in;
}
```

At the initial mount, all children of the `ReactCSSTransitionGroup` will `appear` but not `enter`. However, all children later added to an existing `ReactCSSTransitionGroup` will `enter` but not `appear`.

> Note:
>
> The prop `transitionAppear` was added to `ReactCSSTransitionGroup` in version `0.13`. To maintain backwards compatibility, the default value is set to `false`.
>
> However, the default values of `transitionEnter` and `transitionLeave` are `true` so you must specify `transitionEnterTimeout` and `transitionLeaveTimeout` by default. If you don’t need either enter or leave animations, pass `transitionEnter={false}` or `transitionLeave={false}`.

### [](#custom-classes)Custom Classes

It is also possible to use custom class names for each of the steps in your transitions. Instead of passing a string into transitionName you can pass an object containing either the `enter` and `leave` class names, or an object containing the `enter`, `enter-active`, `leave-active`, and `leave` class names. If only the enter and leave classes are provided, the enter-active and leave-active classes will be determined by appending ‘-active’ to the end of the class name. Here are two examples using custom classes:

```
// ...
<ReactCSSTransitionGroup
  transitionName={ {
    enter: 'enter',
    enterActive: 'enterActive',
    leave: 'leave',
    leaveActive: 'leaveActive',
    appear: 'appear',
    appearActive: 'appearActive'
  } }>
  {item}
</ReactCSSTransitionGroup>

<ReactCSSTransitionGroup
  transitionName={ {
    enter: 'enter',
    leave: 'leave',
    appear: 'appear'
  } }>
  {item2}
</ReactCSSTransitionGroup>
// ...
```

### [](#animation-group-must-be-mounted-to-work)Animation Group Must Be Mounted To Work

In order for it to apply transitions to its children, the `ReactCSSTransitionGroup` must already be mounted in the DOM or the prop `transitionAppear` must be set to `true`.

The example below would **not** work, because the `ReactCSSTransitionGroup` is being mounted along with the new item, instead of the new item being mounted within it. Compare this to the [Getting Started](#getting-started) section above to see the difference.

```
render() {
  const items = this.state.items.map((item, i) => (
    <div key={item} onClick={() => this.handleRemove(i)}>
      <ReactCSSTransitionGroup transitionName="example">        {item}
      </ReactCSSTransitionGroup>    </div>
  ));

  return (
    <div>
      <button onClick={this.handleAdd}>Add Item</button>
      {items}    </div>
  );
}
```

### [](#animating-one-or-zero-items)Animating One or Zero Items

In the example above, we rendered a list of items into `ReactCSSTransitionGroup`. However, the children of `ReactCSSTransitionGroup` can also be one or zero items. This makes it possible to animate a single element entering or leaving. Similarly, you can animate a new element replacing the current element. For example, we can implement a simple image carousel like this:

```
import ReactCSSTransitionGroup from 'react-transition-group';

function ImageCarousel(props) {
  return (
    <div>
      <ReactCSSTransitionGroup
        transitionName="carousel"
        transitionEnterTimeout={300}
        transitionLeaveTimeout={300}>
        <img src={props.imageSrc} key={props.imageSrc} />      </ReactCSSTransitionGroup>
    </div>
  );
}
```

### [](#disabling-animations)Disabling Animations

You can disable animating `enter` or `leave` animations if you want. For example, sometimes you may want an `enter` animation and no `leave` animation, but `ReactCSSTransitionGroup` waits for an animation to complete before removing your DOM node. You can add `transitionEnter={false}` or `transitionLeave={false}` props to `ReactCSSTransitionGroup` to disable these animations.

> Note:
>
> When using `ReactCSSTransitionGroup`, there’s no way for your components to be notified when a transition has ended or to perform any more complex logic around animation. If you want more fine-grained control, you can use the lower-level `ReactTransitionGroup` API which provides the hooks you need to do custom transitions.

***

## [](#low-level-api-reacttransitiongroup)Low-level API: ReactTransitionGroup

**Importing**

```
import ReactTransitionGroup from 'react-addons-transition-group' // ES6
var ReactTransitionGroup = require('react-addons-transition-group') // ES5 with npm
```

`ReactTransitionGroup` is the basis for animations. When children are declaratively added or removed from it (as in the [example above](#getting-started)), special lifecycle methods are called on them.

* [`componentWillAppear()`](#componentwillappear)
* [`componentDidAppear()`](#componentdidappear)
* [`componentWillEnter()`](#componentwillenter)
* [`componentDidEnter()`](#componentdidenter)
* [`componentWillLeave()`](#componentwillleave)
* [`componentDidLeave()`](#componentdidleave)

#### [](#rendering-a-different-component)Rendering a Different Component

`ReactTransitionGroup` renders as a `span` by default. You can change this behavior by providing a `component` prop. For example, here’s how you would render a `<ul>`:

```
<ReactTransitionGroup component="ul">  {/* ... */}
</ReactTransitionGroup>
```

Any additional, user-defined, properties will become properties of the rendered component. For example, here’s how you would render a `<ul>` with CSS class:

```
<ReactTransitionGroup component="ul" className="animated-list">  {/* ... */}
</ReactTransitionGroup>
```

Every DOM component that React can render is available for use. However, `component` does not need to be a DOM component. It can be any React component you want; even ones you’ve written yourself! Just write `component={List}` and your component will receive `this.props.children`.

#### [](#rendering-a-single-child)Rendering a Single Child

People often use `ReactTransitionGroup` to animate mounting and unmounting of a single child such as a collapsible panel. Normally `ReactTransitionGroup` wraps all its children in a `span` (or a custom `component` as described above). This is because any React component has to return a single root element, and `ReactTransitionGroup` is no exception to this rule.

However if you only need to render a single child inside `ReactTransitionGroup`, you can completely avoid wrapping it in a `<span>` or any other DOM component. To do this, create a custom component that renders the first child passed to it directly:

```
function FirstChild(props) {
  const childrenArray = React.Children.toArray(props.children);
  return childrenArray[0] || null;
}
```

Now you can specify `FirstChild` as the `component` prop in `<ReactTransitionGroup>` props and avoid any wrappers in the result DOM:

```
<ReactTransitionGroup component={FirstChild}>
  {someCondition ? <MyComponent /> : null}
</ReactTransitionGroup>
```

This only works when you are animating a single child in and out, such as a collapsible panel. This approach wouldn’t work when animating multiple children or replacing the single child with another child, such as an image carousel. For an image carousel, while the current image is animating out, another image will animate in, so `<ReactTransitionGroup>` needs to give them a common DOM parent. You can’t avoid the wrapper for multiple children, but you can customize the wrapper with the `component` prop as described above.

***

## [](#reference)Reference

### [](#componentwillappear)`componentWillAppear()`

```
componentWillAppear(callback)
```

This is called at the same time as `componentDidMount()` for components that are initially mounted in a `TransitionGroup`. It will block other animations from occurring until `callback` is called. It is only called on the initial render of a `TransitionGroup`.

***

### [](#componentdidappear)`componentDidAppear()`

```
componentDidAppear()
```

This is called after the `callback` function that was passed to `componentWillAppear` is called.

***

### [](#componentwillenter)`componentWillEnter()`

```
componentWillEnter(callback)
```

This is called at the same time as `componentDidMount()` for components added to an existing `TransitionGroup`. It will block other animations from occurring until `callback` is called. It will not be called on the initial render of a `TransitionGroup`.

***

### [](#componentdidenter)`componentDidEnter()`

```
componentDidEnter()
```

This is called after the `callback` function that was passed to [`componentWillEnter()`](#componentwillenter) is called.

***

### [](#componentwillleave)`componentWillLeave()`

```
componentWillLeave(callback)
```

This is called when the child has been removed from the `ReactTransitionGroup`. Though the child has been removed, `ReactTransitionGroup` will keep it in the DOM until `callback` is called.

***

### [](#componentdidleave)`componentDidLeave()`

```
componentDidLeave()
```

This is called when the `willLeave` `callback` is called (at the same time as `componentWillUnmount()`).

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/addons-animation.md)

----
url: https://react.dev/reference/react/useRef
----

[API Reference](/reference/react)

[Hooks](/reference/react/hooks)

# useRef[](#undefined "Link for this heading")

`useRef` is a React Hook that lets you reference a value that’s not needed for rendering.

```
const ref = useRef(initialValue)
```

***

## Reference[](#reference "Link for Reference ")

### `useRef(initialValue)`[](#useref "Link for this heading")

Call `useRef` at the top level of your component to declare a [ref.](/learn/referencing-values-with-refs)

```
import { useRef } from 'react';



function MyComponent() {

  const intervalRef = useRef(0);

  const inputRef = useRef(null);

  // ...
```

***

## Usage[](#usage "Link for Usage ")

### Referencing a value with a ref[](#referencing-a-value-with-a-ref "Link for Referencing a value with a ref ")

Call `useRef` at the top level of your component to declare one or more [refs.](/learn/referencing-values-with-refs)

```
import { useRef } from 'react';



function Stopwatch() {

  const intervalRef = useRef(0);

  // ...
```

`useRef` returns a ref object with a single `current` property initially set to the initial value you provided.

On the next renders, `useRef` will return the same object. You can change its `current` property to store information and read it later. This might remind you of [state](/reference/react/useState), but there is an important difference.

**Changing a ref does not trigger a re-render.** This means refs are perfect for storing information that doesn’t affect the visual output of your component. For example, if you need to store an [interval ID](https://developer.mozilla.org/en-US/docs/Web/API/setInterval) and retrieve it later, you can put it in a ref. To update the value inside the ref, you need to manually change its `current` property:

```
function handleStartClick() {

  const intervalId = setInterval(() => {

    // ...

  }, 1000);

  intervalRef.current = intervalId;

}
```

Later, you can read that interval ID from the ref so that you can call [clear that interval](https://developer.mozilla.org/en-US/docs/Web/API/clearInterval):

```
function handleStopClick() {

  const intervalId = intervalRef.current;

  clearInterval(intervalId);

}
```

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useRef } from 'react';

export default function Counter() {
  let ref = useRef(0);

  function handleClick() {
    ref.current = ref.current + 1;
    alert('You clicked ' + ref.current + ' times!');
  }

  return (
    <button onClick={handleClick}>
      Click me!
    </button>
  );
}
```

```
function MyComponent() {

  // ...

  // 🚩 Don't write a ref during rendering

  myRef.current = 123;

  // ...

  // 🚩 Don't read a ref during rendering

  return <h1>{myOtherRef.current}</h1>;

}
```

You can read or write refs **from event handlers or effects instead**.

```
function MyComponent() {

  // ...

  useEffect(() => {

    // ✅ You can read or write refs in effects

    myRef.current = 123;

  });

  // ...

  function handleClick() {

    // ✅ You can read or write refs in event handlers

    doSomething(myOtherRef.current);

  }

  // ...

}
```

If you *have to* read [or write](/reference/react/useState#storing-information-from-previous-renders) something during rendering, [use state](/reference/react/useState) instead.

When you break these rules, your component might still work, but most of the newer features we’re adding to React will rely on these expectations. Read more about [keeping your components pure.](/learn/keeping-components-pure#where-you-_can_-cause-side-effects)

***

### Manipulating the DOM with a ref[](#manipulating-the-dom-with-a-ref "Link for Manipulating the DOM with a ref ")

It’s particularly common to use a ref to manipulate the [DOM.](https://developer.mozilla.org/en-US/docs/Web/API/HTML_DOM_API) React has built-in support for this.

First, declare a ref object with an initial value of `null`:

```
import { useRef } from 'react';



function MyComponent() {

  const inputRef = useRef(null);

  // ...
```

Then pass your ref object as the `ref` attribute to the JSX of the DOM node you want to manipulate:

```
  // ...

  return <input ref={inputRef} />;
```

After React creates the DOM node and puts it on the screen, React will set the `current` property of your ref object to that DOM node. Now you can access the `<input>`’s DOM node and call methods like [`focus()`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus):

```
  function handleClick() {

    inputRef.current.focus();

  }
```

React will set the `current` property back to `null` when the node is removed from the screen.

Read more about [manipulating the DOM with refs.](/learn/manipulating-the-dom-with-refs)

#### Examples of manipulating the DOM with useRef[](#examples-dom "Link for Examples of manipulating the DOM with useRef")

#### Example 1 of 4:Focusing a text input[](#focusing-a-text-input "Link for this heading")

In this example, clicking the button will focus the input:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useRef } from 'react';

export default function Form() {
  const inputRef = useRef(null);

  function handleClick() {
    inputRef.current.focus();
  }

  return (
    <>
      <input ref={inputRef} />
      <button onClick={handleClick}>
        Focus the input
      </button>
    </>
  );
}
```

***

### Avoiding recreating the ref contents[](#avoiding-recreating-the-ref-contents "Link for Avoiding recreating the ref contents ")

React saves the initial ref value once and ignores it on the next renders.

```
function Video() {

  const playerRef = useRef(new VideoPlayer());

  // ...
```

Although the result of `new VideoPlayer()` is only used for the initial render, you’re still calling this function on every render. This can be wasteful if it’s creating expensive objects.

To solve it, you may initialize the ref like this instead:

```
function Video() {

  const playerRef = useRef(null);

  if (playerRef.current === null) {

    playerRef.current = new VideoPlayer();

  }

  // ...
```

Normally, writing or reading `ref.current` during render is not allowed. However, it’s fine in this case because the result is always the same, and the condition only executes during initialization so it’s fully predictable.

##### Deep Dive#### How to avoid null checks when initializing useRef later[](#how-to-avoid-null-checks-when-initializing-use-ref-later "Link for How to avoid null checks when initializing useRef later ")

If you use a type checker and don’t want to always check for `null`, you can try a pattern like this instead:

```
function Video() {

  const playerRef = useRef(null);



  function getPlayer() {

    if (playerRef.current !== null) {

      return playerRef.current;

    }

    const player = new VideoPlayer();

    playerRef.current = player;

    return player;

  }



  // ...
```

Here, the `playerRef` itself is nullable. However, you should be able to convince your type checker that there is no case in which `getPlayer()` returns `null`. Then use `getPlayer()` in your event handlers.

***

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### I can’t get a ref to a custom component[](#i-cant-get-a-ref-to-a-custom-component "Link for I can’t get a ref to a custom component ")

If you try to pass a `ref` to your own component like this:

```
const inputRef = useRef(null);



return <MyInput ref={inputRef} />;
```

You might get an error in the console:

Console

TypeError: Cannot read properties of null

By default, your own components don’t expose refs to the DOM nodes inside them.

To fix this, find the component that you want to get a ref to:

```
export default function MyInput({ value, onChange }) {

  return (

    <input

      value={value}

      onChange={onChange}

    />

  );

}
```

And then add `ref` to the list of props your component accepts and pass `ref` as a prop to the relevant child [built-in component](/reference/react-dom/components/common) like this:

```
function MyInput({ value, onChange, ref }) {

  return (

    <input

      value={value}

      onChange={onChange}

      ref={ref}

    />

  );

};



export default MyInput;
```

Then the parent component can get a ref to it.

Read more about [accessing another component’s DOM nodes.](/learn/manipulating-the-dom-with-refs#accessing-another-components-dom-nodes)

[PrevioususeReducer](/reference/react/useReducer)

[NextuseState](/reference/react/useState)

***

----
url: https://react.dev/reference/react-dom/components/form
----

[API Reference](/reference/react)

[Components](/reference/react-dom/components)

# \<form>[](#undefined "Link for this heading")

The [built-in browser `<form>` component](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form) lets you create interactive controls for submitting information.

```
<form action={search}>

    <input name="query" />

    <button type="submit">Search</button>

</form>
```

* [Reference](#reference)
  * [`<form>`](#form)

* [Usage](#usage)

  * [Handle form submission with an event handler](#handle-form-submission-with-an-event-handler)
  * [Handle form submission with an action prop](#handle-form-submission-with-an-action-prop)
  * [Handle form submission with a Server Function](#handle-form-submission-with-a-server-function)
  * [Display a pending state during form submission](#display-a-pending-state-during-form-submission)
  * [Optimistically updating form data](#optimistically-updating-form-data)
  * [Handling form submission errors](#handling-form-submission-errors)
  * [Display a form submission error without JavaScript](#display-a-form-submission-error-without-javascript)
  * [Handling multiple submission types](#handling-multiple-submission-types)

***

## Reference[](#reference "Link for Reference ")

### `<form>`[](#form "Link for this heading")

To create interactive controls for submitting information, render the [built-in browser `<form>` component](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form).

```
<form action={search}>

    <input name="query" />

    <button type="submit">Search</button>

</form>
```

[See more examples below.](#usage)

#### Props[](#props "Link for Props ")

`<form>` supports all [common element props.](/reference/react-dom/components/common#common-props)

[`action`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form#action): a URL or function. When a URL is passed to `action` the form will behave like the HTML form component. When a function is passed to `action` the function will handle the form submission in a Transition following [the Action prop pattern](/reference/react/useTransition#exposing-action-props-from-components). The function passed to `action` may be async and will be called with a single argument containing the [form data](https://developer.mozilla.org/en-US/docs/Web/API/FormData) of the submitted form. The `action` prop can be overridden by a `formAction` attribute on a `<button>`, `<input type="submit">`, or `<input type="image">` component.

#### Caveats[](#caveats "Link for Caveats ")

* When a function is passed to `action` or `formAction` the HTTP method will be POST regardless of value of the `method` prop.

***

## Usage[](#usage "Link for Usage ")

### Handle form submission with an event handler[](#handle-form-submission-with-an-event-handler "Link for Handle form submission with an event handler ")

Pass a function to the `onSubmit` event handler to run code when the form is submitted. By default, the browser sends the form data to the current URL and refreshes the page, so call [`e.preventDefault()`](https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault) to override that behavior.

This example reads the submitted values with [`new FormData(e.target)`](https://developer.mozilla.org/en-US/docs/Web/API/FormData), which collects every field by its `name`. This keeps the inputs [uncontrolled](/reference/react-dom/components/input#reading-the-input-values-when-submitting-a-form). If you instead [control an input with state](/reference/react-dom/components/input#controlling-an-input-with-a-state-variable), read from that state on submit rather than from `FormData`.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
export default function Search() {
  function handleSubmit(e) {
    // Prevent the browser from reloading the page
    e.preventDefault();

    // Read the form data
    const form = e.target;
    const formData = new FormData(form);
    const query = formData.get("query");
    alert(`You searched for '${query}'`);
  }

  return (
    <form onSubmit={handleSubmit}>
      <input name="query" />
      <button type="submit">Search</button>
    </form>
  );
}
```

### Note

Reading form data with `onSubmit` works in every version of React and gives you direct access to the [submit event](https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/submit_event), so you can call `e.preventDefault()` and read the data yourself. Passing the function to the `action` prop instead runs the submission in a [Transition](/reference/react/useTransition). React then tracks the pending state, sends thrown errors to the nearest error boundary, and lets the form work with [`useActionState`](/reference/react/useActionState) and [`useOptimistic`](/reference/react/useOptimistic). An `action` can also be a [Server Function](/reference/rsc/server-functions), which `onSubmit` does not support.

### Handle form submission with an action prop[](#handle-form-submission-with-an-action-prop "Link for Handle form submission with an action prop ")

Pass a function to the `action` prop of form to run the function when the form is submitted. [`formData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData) will be passed to the function as an argument so you can access the data submitted by the form. This differs from the conventional [HTML action](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form#action), which only accepts URLs. Unlike `onSubmit`, an `action` runs in a [Transition](/reference/react/useTransition) and calling `e.preventDefault()` isn’t needed. After the `action` function succeeds, all uncontrolled field elements in the form are reset.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
export default function Search() {
  function search(formData) {
    const query = formData.get("query");
    alert(`You searched for '${query}'`);
  }
  return (
    <form action={search}>
      <input name="query" />
      <button type="submit">Search</button>
    </form>
  );
}
```

### Handle form submission with a Server Function[](#handle-form-submission-with-a-server-function "Link for Handle form submission with a Server Function ")

Render a `<form>` with an input and submit button. Pass a Server Function (a function marked with [`'use server'`](/reference/rsc/use-server)) to the `action` prop of form to run the function when the form is submitted.

Passing a Server Function to `<form action>` allow users to submit forms without JavaScript enabled or before the code has loaded. This is beneficial to users who have a slow connection, device, or have JavaScript disabled and is similar to the way forms work when a URL is passed to the `action` prop.

You can use hidden form fields to provide data to the `<form>`’s action. The Server Function will be called with the hidden form field data as an instance of [`FormData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData).

```
import { updateCart } from './lib.js';



function AddToCart({productId}) {

  async function addToCart(formData) {

    'use server'

    const productId = formData.get('productId')

    await updateCart(productId)

  }

  return (

    <form action={addToCart}>

        <input type="hidden" name="productId" value={productId} />

        <button type="submit">Add to Cart</button>

    </form>



  );

}
```

In lieu of using hidden form fields to provide data to the `<form>`’s action, you can call the `bind` method to supply it with extra arguments. This will bind a new argument (`productId`) to the function in addition to the `formData` that is passed as an argument to the function.

```
import { updateCart } from './lib.js';



function AddToCart({productId}) {

  async function addToCart(productId, formData) {

    "use server";

    await updateCart(productId)

  }

  const addProductToCart = addToCart.bind(null, productId);

  return (

    <form action={addProductToCart}>

      <button type="submit">Add to Cart</button>

    </form>

  );

}
```

When `<form>` is rendered by a [Server Component](/reference/rsc/use-client), and a [Server Function](/reference/rsc/server-functions) is passed to the `<form>`’s `action` prop, the form is [progressively enhanced](https://developer.mozilla.org/en-US/docs/Glossary/Progressive_Enhancement).

### Display a pending state during form submission[](#display-a-pending-state-during-form-submission "Link for Display a pending state during form submission ")

To display a pending state when a form is being submitted, you can call the `useFormStatus` Hook in a component rendered in a `<form>` and read the `pending` property returned.

Here, we use the `pending` property to indicate the form is submitting.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useFormStatus } from "react-dom";
import { submitForm } from "./actions.js";

function Submit() {
  const { pending } = useFormStatus();
  return (
    <button type="submit" disabled={pending}>
      {pending ? "Submitting..." : "Submit"}
    </button>
  );
}

function Form({ action }) {
  return (
    <form action={action}>
      <Submit />
    </form>
  );
}

export default function App() {
  return <Form action={submitForm} />;
}
```

To learn more about the `useFormStatus` Hook see the [reference documentation](/reference/react-dom/hooks/useFormStatus).

### Optimistically updating form data[](#optimistically-updating-form-data "Link for Optimistically updating form data ")

The `useOptimistic` Hook provides a way to optimistically update the user interface before a background operation, like a network request, completes. In the context of forms, this technique helps to make apps feel more responsive. When a user submits a form, instead of waiting for the server’s response to reflect the changes, the interface is immediately updated with the expected outcome.

For example, when a user types a message into the form and hits the “Send” button, the `useOptimistic` Hook allows the message to immediately appear in the list with a “Sending…” label, even before the message is actually sent to a server. This “optimistic” approach gives the impression of speed and responsiveness. The form then attempts to truly send the message in the background. Once the server confirms the message has been received, the “Sending…” label is removed.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useOptimistic, useState, useRef } from "react";
import { deliverMessage } from "./actions.js";

function Thread({ messages, sendMessage }) {
  const formRef = useRef();
  async function formAction(formData) {
    addOptimisticMessage(formData.get("message"));
    formRef.current.reset();
    await sendMessage(formData);
  }
  const [optimisticMessages, addOptimisticMessage] = useOptimistic(
    messages,
    (state, newMessage) => [
      ...state,
      {
        text: newMessage,
        sending: true
      }
    ]
  );

  return (
    <>
      {optimisticMessages.map((message, index) => (
        <div key={index}>
          {message.text}
          {!!message.sending && <small> (Sending...)</small>}
        </div>
      ))}
      <form action={formAction} ref={formRef}>
        <input type="text" name="message" placeholder="Hello!" />
        <button type="submit">Send</button>
      </form>
    </>
  );
}

export default function App() {
  const [messages, setMessages] = useState([
    { text: "Hello there!", sending: false, key: 1 }
  ]);
  async function sendMessage(formData) {
    const sentMessage = await deliverMessage(formData.get("message"));
    setMessages((messages) => [...messages, { text: sentMessage }]);
  }
  return <Thread messages={messages} sendMessage={sendMessage} />;
}
```

### Handling form submission errors[](#handling-form-submission-errors "Link for Handling form submission errors ")

In some cases the function called by a `<form>`’s `action` prop throws an error. You can handle these errors by wrapping `<form>` in an Error Boundary. If the function called by a `<form>`’s `action` prop throws an error, the fallback for the error boundary will be displayed.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { ErrorBoundary } from "react-error-boundary";

export default function Search() {
  function search() {
    throw new Error("search error");
  }
  return (
    <ErrorBoundary
      fallback={<p>There was an error while submitting the form</p>}
    >
      <form action={search}>
        <input name="query" />
        <button type="submit">Search</button>
      </form>
    </ErrorBoundary>
  );
}
```

### Display a form submission error without JavaScript[](#display-a-form-submission-error-without-javascript "Link for Display a form submission error without JavaScript ")

Displaying a form submission error message before the JavaScript bundle loads for progressive enhancement requires that:

1. `<form>` be rendered by a [Client Component](/reference/rsc/use-client)
2. the function passed to the `<form>`’s `action` prop be a [Server Function](/reference/rsc/server-functions)
3. the `useActionState` Hook be used to display the error message

`useActionState` takes two parameters: a [Server Function](/reference/rsc/server-functions) and an initial state. `useActionState` returns two values, a state variable and an action. The action returned by `useActionState` should be passed to the `action` prop of the form. The state variable returned by `useActionState` can be used to display an error message. The value returned by the Server Function passed to `useActionState` will be used to update the state variable.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useActionState } from "react";
import { signUpNewUser } from "./api";

export default function Page() {
  async function signup(prevState, formData) {
    "use server";
    const email = formData.get("email");
    try {
      await signUpNewUser(email);
      alert(`Added "${email}"`);
    } catch (err) {
      return err.toString();
    }
  }
  const [message, signupAction] = useActionState(signup, null);
  return (
    <>
      <h1>Signup for my newsletter</h1>
      <p>Signup with the same email twice to see an error</p>
      <form action={signupAction} id="signup-form">
        <label htmlFor="email">Email: </label>
        <input name="email" id="email" placeholder="react@example.com" />
        <button>Sign up</button>
        {!!message && <p>{message}</p>}
      </form>
    </>
  );
}
```

Learn more about updating state from a form action with the [`useActionState`](/reference/react/useActionState) docs

### Handling multiple submission types[](#handling-multiple-submission-types "Link for Handling multiple submission types ")

Forms can be designed to handle multiple submission actions based on the button pressed by the user. Each button inside a form can be associated with a distinct action or behavior by setting the `formAction` prop.

When a user taps a specific button, the form is submitted, and a corresponding action, defined by that button’s attributes and action, is executed. For instance, a form might submit an article for review by default but have a separate button with `formAction` set to save the article as a draft.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
export default function Search() {
  function publish(formData) {
    const content = formData.get("content");
    const button = formData.get("button");
    alert(`'${content}' was published with the '${button}' button`);
  }

  function save(formData) {
    const content = formData.get("content");
    alert(`Your draft of '${content}' has been saved!`);
  }

  return (
    <form action={publish}>
      <textarea name="content" rows={4} cols={40} />
      <br />
      <button type="submit" name="button" value="submit">Publish</button>
      <button formAction={save}>Save draft</button>
    </form>
  );
}
```

[PreviousCommon (e.g. \<div>)](/reference/react-dom/components/common)

[Next\<input>](/reference/react-dom/components/input)

***

----
url: https://legacy.reactjs.org/docs/higher-order-components.html
----

> These docs are old and won’t be updated. Go to [react.dev](https://react.dev/) for the new React docs.
>
> Higher-order components are not commonly used in modern React code.

A higher-order component (HOC) is an advanced technique in React for reusing component logic. HOCs are not part of the React API, per se. They are a pattern that emerges from React’s compositional nature.

Concretely, **a higher-order component is a function that takes a component and returns a new component.**

```
const EnhancedComponent = higherOrderComponent(WrappedComponent);
```

Whereas a component transforms props into UI, a higher-order component transforms a component into another component.

HOCs are common in third-party React libraries, such as Redux’s [`connect`](https://react-redux.js.org/api/connect) and Relay’s [`createFragmentContainer`](https://relay.dev/docs/v10.1.3/fragment-container/#createfragmentcontainer).

In this document, we’ll discuss why higher-order components are useful, and how to write your own.

## [](#use-hocs-for-cross-cutting-concerns)Use HOCs For Cross-Cutting Concerns

> **Note**
>
> We previously recommended mixins as a way to handle cross-cutting concerns. We’ve since realized that mixins create more trouble than they are worth. [Read more](/blog/2016/07/13/mixins-considered-harmful.html) about why we’ve moved away from mixins and how you can transition your existing components.

Components are the primary unit of code reuse in React. However, you’ll find that some patterns aren’t a straightforward fit for traditional components.

For example, say you have a `CommentList` component that subscribes to an external data source to render a list of comments:

```
class CommentList extends React.Component {
  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
    this.state = {
      // "DataSource" is some global data source
      comments: DataSource.getComments()
    };
  }

  componentDidMount() {
    // Subscribe to changes
    DataSource.addChangeListener(this.handleChange);
  }

  componentWillUnmount() {
    // Clean up listener
    DataSource.removeChangeListener(this.handleChange);
  }

  handleChange() {
    // Update component state whenever the data source changes
    this.setState({
      comments: DataSource.getComments()
    });
  }

  render() {
    return (
      <div>
        {this.state.comments.map((comment) => (
          <Comment comment={comment} key={comment.id} />
        ))}
      </div>
    );
  }
}
```

Later, you write a component for subscribing to a single blog post, which follows a similar pattern:

```
class BlogPost extends React.Component {
  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
    this.state = {
      blogPost: DataSource.getBlogPost(props.id)
    };
  }

  componentDidMount() {
    DataSource.addChangeListener(this.handleChange);
  }

  componentWillUnmount() {
    DataSource.removeChangeListener(this.handleChange);
  }

  handleChange() {
    this.setState({
      blogPost: DataSource.getBlogPost(this.props.id)
    });
  }

  render() {
    return <TextBlock text={this.state.blogPost} />;
  }
}
```

`CommentList` and `BlogPost` aren’t identical — they call different methods on `DataSource`, and they render different output. But much of their implementation is the same:

* On mount, add a change listener to `DataSource`.
* Inside the listener, call `setState` whenever the data source changes.
* On unmount, remove the change listener.

You can imagine that in a large app, this same pattern of subscribing to `DataSource` and calling `setState` will occur over and over again. We want an abstraction that allows us to define this logic in a single place and share it across many components. This is where higher-order components excel.

We can write a function that creates components, like `CommentList` and `BlogPost`, that subscribe to `DataSource`. The function will accept as one of its arguments a child component that receives the subscribed data as a prop. Let’s call the function `withSubscription`:

```
const CommentListWithSubscription = withSubscription(
  CommentList,
  (DataSource) => DataSource.getComments()
);

const BlogPostWithSubscription = withSubscription(
  BlogPost,
  (DataSource, props) => DataSource.getBlogPost(props.id)
);
```

The first parameter is the wrapped component. The second parameter retrieves the data we’re interested in, given a `DataSource` and the current props.

When `CommentListWithSubscription` and `BlogPostWithSubscription` are rendered, `CommentList` and `BlogPost` will be passed a `data` prop with the most current data retrieved from `DataSource`:

```
// This function takes a component...
function withSubscription(WrappedComponent, selectData) {
  // ...and returns another component...
  return class extends React.Component {
    constructor(props) {
      super(props);
      this.handleChange = this.handleChange.bind(this);
      this.state = {
        data: selectData(DataSource, props)
      };
    }

    componentDidMount() {
      // ... that takes care of the subscription...
      DataSource.addChangeListener(this.handleChange);
    }

    componentWillUnmount() {
      DataSource.removeChangeListener(this.handleChange);
    }

    handleChange() {
      this.setState({
        data: selectData(DataSource, this.props)
      });
    }

    render() {
      // ... and renders the wrapped component with the fresh data!
      // Notice that we pass through any additional props
      return <WrappedComponent data={this.state.data} {...this.props} />;
    }
  };
}
```

Note that a HOC doesn’t modify the input component, nor does it use inheritance to copy its behavior. Rather, a HOC *composes* the original component by *wrapping* it in a container component. A HOC is a pure function with zero side-effects.

And that’s it! The wrapped component receives all the props of the container, along with a new prop, `data`, which it uses to render its output. The HOC isn’t concerned with how or why the data is used, and the wrapped component isn’t concerned with where the data came from.

Because `withSubscription` is a normal function, you can add as many or as few arguments as you like. For example, you may want to make the name of the `data` prop configurable, to further isolate the HOC from the wrapped component. Or you could accept an argument that configures `shouldComponentUpdate`, or one that configures the data source. These are all possible because the HOC has full control over how the component is defined.

Like components, the contract between `withSubscription` and the wrapped component is entirely props-based. This makes it easy to swap one HOC for a different one, as long as they provide the same props to the wrapped component. This may be useful if you change data-fetching libraries, for example.

## [](#dont-mutate-the-original-component-use-composition)Don’t Mutate the Original Component. Use Composition.

Resist the temptation to modify a component’s prototype (or otherwise mutate it) inside a HOC.

```
function logProps(InputComponent) {
  InputComponent.prototype.componentDidUpdate = function(prevProps) {
    console.log('Current props: ', this.props);
    console.log('Previous props: ', prevProps);
  };
  // The fact that we're returning the original input is a hint that it has
  // been mutated.
  return InputComponent;
}

// EnhancedComponent will log whenever props are received
const EnhancedComponent = logProps(InputComponent);
```

There are a few problems with this. One is that the input component cannot be reused separately from the enhanced component. More crucially, if you apply another HOC to `EnhancedComponent` that *also* mutates `componentDidUpdate`, the first HOC’s functionality will be overridden! This HOC also won’t work with function components, which do not have lifecycle methods.

Mutating HOCs are a leaky abstraction—the consumer must know how they are implemented in order to avoid conflicts with other HOCs.

Instead of mutation, HOCs should use composition, by wrapping the input component in a container component:

```
function logProps(WrappedComponent) {
  return class extends React.Component {
    componentDidUpdate(prevProps) {
      console.log('Current props: ', this.props);
      console.log('Previous props: ', prevProps);
    }
    render() {
      // Wraps the input component in a container, without mutating it. Good!
      return <WrappedComponent {...this.props} />;
    }
  }
}
```

This HOC has the same functionality as the mutating version while avoiding the potential for clashes. It works equally well with class and function components. And because it’s a pure function, it’s composable with other HOCs, or even with itself.

You may have noticed similarities between HOCs and a pattern called **container components**. Container components are part of a strategy of separating responsibility between high-level and low-level concerns. Containers manage things like subscriptions and state, and pass props to components that handle things like rendering UI. HOCs use containers as part of their implementation. You can think of HOCs as parameterized container component definitions.

## [](#convention-pass-unrelated-props-through-to-the-wrapped-component)Convention: Pass Unrelated Props Through to the Wrapped Component

HOCs add features to a component. They shouldn’t drastically alter its contract. It’s expected that the component returned from a HOC has a similar interface to the wrapped component.

HOCs should pass through props that are unrelated to its specific concern. Most HOCs contain a render method that looks something like this:

```
render() {
  // Filter out extra props that are specific to this HOC and shouldn't be
  // passed through
  const { extraProp, ...passThroughProps } = this.props;

  // Inject props into the wrapped component. These are usually state values or
  // instance methods.
  const injectedProp = someStateOrInstanceMethod;

  // Pass props to wrapped component
  return (
    <WrappedComponent
      injectedProp={injectedProp}
      {...passThroughProps}
    />
  );
}
```

This convention helps ensure that HOCs are as flexible and reusable as possible.

## [](#convention-maximizing-composability)Convention: Maximizing Composability

Not all HOCs look the same. Sometimes they accept only a single argument, the wrapped component:

```
const NavbarWithRouter = withRouter(Navbar);
```

Usually, HOCs accept additional arguments. In this example from Relay, a config object is used to specify a component’s data dependencies:

```
const CommentWithRelay = Relay.createContainer(Comment, config);
```

The most common signature for HOCs looks like this:

```
// React Redux's `connect`
const ConnectedComment = connect(commentSelector, commentActions)(CommentList);
```

*What?!* If you break it apart, it’s easier to see what’s going on.

```
// connect is a function that returns another function
const enhance = connect(commentListSelector, commentListActions);
// The returned function is a HOC, which returns a component that is connected
// to the Redux store
const ConnectedComment = enhance(CommentList);
```

In other words, `connect` is a higher-order function that returns a higher-order component!

This form may seem confusing or unnecessary, but it has a useful property. Single-argument HOCs like the one returned by the `connect` function have the signature `Component => Component`. Functions whose output type is the same as its input type are really easy to compose together.

```
// Instead of doing this...
const EnhancedComponent = withRouter(connect(commentSelector)(WrappedComponent))

// ... you can use a function composition utility
// compose(f, g, h) is the same as (...args) => f(g(h(...args)))
const enhance = compose(
  // These are both single-argument HOCs
  withRouter,
  connect(commentSelector)
)
const EnhancedComponent = enhance(WrappedComponent)
```

(This same property also allows `connect` and other enhancer-style HOCs to be used as decorators, an experimental JavaScript proposal.)

The `compose` utility function is provided by many third-party libraries including lodash (as [`lodash.flowRight`](https://lodash.com/docs/#flowRight)), [Redux](https://redux.js.org/api/compose), and [Ramda](https://ramdajs.com/docs/#compose).

## [](#convention-wrap-the-display-name-for-easy-debugging)Convention: Wrap the Display Name for Easy Debugging

The container components created by HOCs show up in the [React Developer Tools](https://github.com/facebook/react/tree/main/packages/react-devtools) like any other component. To ease debugging, choose a display name that communicates that it’s the result of a HOC.

The most common technique is to wrap the display name of the wrapped component. So if your higher-order component is named `withSubscription`, and the wrapped component’s display name is `CommentList`, use the display name `WithSubscription(CommentList)`:

```
function withSubscription(WrappedComponent) {
  class WithSubscription extends React.Component {/* ... */}
  WithSubscription.displayName = `WithSubscription(${getDisplayName(WrappedComponent)})`;
  return WithSubscription;
}

function getDisplayName(WrappedComponent) {
  return WrappedComponent.displayName || WrappedComponent.name || 'Component';
}
```

## [](#caveats)Caveats

Higher-order components come with a few caveats that aren’t immediately obvious if you’re new to React.

### [](#dont-use-hocs-inside-the-render-method)Don’t Use HOCs Inside the render Method

React’s diffing algorithm (called [Reconciliation](/docs/reconciliation.html)) uses component identity to determine whether it should update the existing subtree or throw it away and mount a new one. If the component returned from `render` is identical (`===`) to the component from the previous render, React recursively updates the subtree by diffing it with the new one. If they’re not equal, the previous subtree is unmounted completely.

Normally, you shouldn’t need to think about this. But it matters for HOCs because it means you can’t apply a HOC to a component within the render method of a component:

```
render() {
  // A new version of EnhancedComponent is created on every render
  // EnhancedComponent1 !== EnhancedComponent2
  const EnhancedComponent = enhance(MyComponent);
  // That causes the entire subtree to unmount/remount each time!
  return <EnhancedComponent />;
}
```

The problem here isn’t just about performance — remounting a component causes the state of that component and all of its children to be lost.

Instead, apply HOCs outside the component definition so that the resulting component is created only once. Then, its identity will be consistent across renders. This is usually what you want, anyway.

In those rare cases where you need to apply a HOC dynamically, you can also do it inside a component’s lifecycle methods or its constructor.

### [](#static-methods-must-be-copied-over)Static Methods Must Be Copied Over

Sometimes it’s useful to define a static method on a React component. For example, Relay containers expose a static method `getFragment` to facilitate the composition of GraphQL fragments.

When you apply a HOC to a component, though, the original component is wrapped with a container component. That means the new component does not have any of the static methods of the original component.

```
// Define a static method
WrappedComponent.staticMethod = function() {/*...*/}
// Now apply a HOC
const EnhancedComponent = enhance(WrappedComponent);

// The enhanced component has no static method
typeof EnhancedComponent.staticMethod === 'undefined' // true
```

To solve this, you could copy the methods onto the container before returning it:

```
function enhance(WrappedComponent) {
  class Enhance extends React.Component {/*...*/}
  // Must know exactly which method(s) to copy :(
  Enhance.staticMethod = WrappedComponent.staticMethod;
  return Enhance;
}
```

However, this requires you to know exactly which methods need to be copied. You can use [hoist-non-react-statics](https://github.com/mridgway/hoist-non-react-statics) to automatically copy all non-React static methods:

```
import hoistNonReactStatic from 'hoist-non-react-statics';
function enhance(WrappedComponent) {
  class Enhance extends React.Component {/*...*/}
  hoistNonReactStatic(Enhance, WrappedComponent);
  return Enhance;
}
```

Another possible solution is to export the static method separately from the component itself.

```
// Instead of...
MyComponent.someFunction = someFunction;
export default MyComponent;

// ...export the method separately...
export { someFunction };

// ...and in the consuming module, import both
import MyComponent, { someFunction } from './MyComponent.js';
```

### [](#refs-arent-passed-through)Refs Aren’t Passed Through

While the convention for higher-order components is to pass through all props to the wrapped component, this does not work for refs. That’s because `ref` is not really a prop — like `key`, it’s handled specially by React. If you add a ref to an element whose component is the result of a HOC, the ref refers to an instance of the outermost container component, not the wrapped component.

The solution for this problem is to use the `React.forwardRef` API (introduced with React 16.3). [Learn more about it in the forwarding refs section](/docs/forwarding-refs.html).

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/higher-order-components.md)

----
url: https://legacy.reactjs.org/blog/2014/01/06/community-roundup-14.html
----

January 06, 2014 by [Vjeux](https://twitter.com/vjeux)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

The theme of this first round-up of 2014 is integration. I’ve tried to assemble a list of articles and projects that use React in various environments.

## [](#react-baseline)React Baseline

React is only one-piece of your web application stack. [Mark Lussier](https://github.com/intabulas) shared his baseline stack that uses React along with Grunt, Browserify, Bower, Zepto, Director and Sass. This should help you get started using React for a new project.

> As I do more projects with ReactJS I started to extract a baseline to use when starting new projects. This is very opinionated and I change my opinion from time to time. This is by no ways perfect and in your opinion most likely wrong :).. which is why I love github
>
> I encourage you to fork, and make it right and submit a pull request!
>
> My current opinion is using tools like Grunt, Browserify, Bower and multiple grunt plugins to get the job done. I also opted for Zepto over jQuery and the Flatiron Project’s Director when I need a router. Oh and for the last little bit of tech that makes you mad, I am in the SASS camp when it comes to stylesheets
>
> [Check it out on GitHub…](https://github.com/intabulas/reactjs-baseline)

## [](#animal-sounds)Animal Sounds

[Josh Duck](http://joshduck.com/) used React in order to build a Windows 8 tablet app. This is a good example of a touch app written in React.[](http://apps.microsoft.com/windows/en-us/app/baby-play-animal-sounds/9280825c-2ed9-41c0-ba38-aa9a5b890bb9)

[Download the app…](http://apps.microsoft.com/windows/en-us/app/baby-play-animal-sounds/9280825c-2ed9-41c0-ba38-aa9a5b890bb9)

## [](#react-rails-tutorial)React Rails Tutorial

[Selem Delul](http://selem.im) bundled the [React Tutorial](/tutorial/tutorial.html) into a rails app. This is a good example on how to get started with a rails project.

> ```
> git clone https://github.com/necrodome/react-rails-tutorial
> cd react-rails-tutorial
> bundle install
> rake db:migrate
> rails s
> ```
>
> Then visit <http://localhost:3000/app> to see the React application that is explained in the React Tutorial. Try opening multiple tabs!
>
> [View on GitHub…](https://github.com/necrodome/react-rails-tutorial)

## [](#mixing-with-backbone)Mixing with Backbone

[Eldar Djafarov](http://eldar.djafarov.com/) implemented a mixin to link Backbone models to React state and a small abstraction to write two-way binding on-top.

[View code on JSFiddle](http://jsfiddle.net/djkojb/qZf48/13/)

[Check out the blog post…](http://eldar.djafarov.com/2013/11/reactjs-mixing-with-backbone/)

## [](#react-infinite-scroll)React Infinite Scroll

[Guillaume Rivals](https://twitter.com/guillaumervls) implemented an InfiniteScroll component. This is a good example of a React component that has a simple yet powerful API.

```
<InfiniteScroll
  pageStart={0}
  loadMore={loadFunc}
  hasMore={true || false}
  loader={<div className="loader">Loading ...</div>}>
  {items} // <-- This is the "stuff" you want to load
</InfiniteScroll>
```

[Try it out on GitHub!](https://github.com/guillaumervls/react-infinite-scroll)

## [](#web-components-style)Web Components Style

[Thomas Aylott](http://subtlegradient.com/) implemented an API that looks like Web Components but using React underneath.

[View the source on JSFiddle…](http://jsfiddle.net/SubtleGradient/ue2Aa)

## [](#react-vs-angular)React vs Angular

React is often compared with Angular. [Pete Hunt](http://skulbuny.com/2013/10/31/react-vs-angular/) wrote an opinionated post on the subject.

> First of all I think it’s important to evaluate technologies on objective rather than subjective features. “It feels nicer” or “it’s cleaner” aren’t valid reasons: performance, modularity, community size and ease of testing / integration with other tools are.
>
> I’ve done a lot of work benchmarking, building apps, and reading the code of Angular to try to come up with a reasonable comparison between their ways of doing things.
>
> [Read the full post…](http://skulbuny.com/2013/10/31/react-vs-angular/)

## [](#random-tweet)Random Tweet

> Really intrigued by React.js. I've looked at all JS frameworks, and excepting [@serenadejs](https://twitter.com/serenadejs) this is the first one which makes sense to me.
>
> — Jonas Nicklas (@jonicklas) [December 16, 2013](https://twitter.com/jonicklas/statuses/412640708755869696)

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2014-01-06-community-roundup-14.md)

----
url: https://legacy.reactjs.org/blog/2015/03/19/building-the-facebook-news-feed-with-relay.html
----

March 19, 2015 by [Joseph Savona](https://twitter.com/en_JS)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

At React.js Conf in January we gave a preview of Relay, a new framework for building data-driven applications in React. In this post, we’ll describe the process of creating a Relay application. This post assumes some familiarity with the concepts of Relay and GraphQL, so if you haven’t already we recommend reading [our introductory blog post](/blog/2015/02/20/introducing-relay-and-graphql.html) or watching [the conference talk](https://www.youtube-nocookie.com/v/9sc8Pyc51uU).

We’re working hard to prepare GraphQL and Relay for public release. In the meantime, we’ll continue to provide information about what you can expect.



## [](#the-relay-architecture)The Relay Architecture

The diagram below shows the main parts of the Relay architecture on the client and the server:

[](/static/1c7e934642028c84d5af545a945394ef/97a96/relay-architecture.png)

The main pieces are as follows:

* Relay Components: React components annotated with declarative data descriptions.
* Actions: Descriptions of how data should change in response to user actions.
* Relay Store: A client-side data store that is fully managed by the framework.
* Server: An HTTP server with GraphQL endpoints (one for reads, one for writes) that respond to GraphQL queries.

This post will focus on **Relay components** that describe encapsulated units of UI and their data dependencies. These components form the majority of a Relay application.



## [](#a-relay-application)A Relay Application

To see how components work and can be composed, let’s implement a basic version of the Facebook News Feed in Relay. Our application will have two components: a `<NewsFeed>` that renders a list of `<Story>` items. We’ll introduce the plain React version of each component first and then convert it to a Relay component. The goal is something like the following:

[](/static/75bc0f3653210df5df2c21a706cab9eb/37523/sample-newsfeed.png)

## [](#the-story-begins)The `<Story>` Begins

The first step is a React `<Story>` component that accepts a `story` prop with the story’s text and author information. Note that all examples uses ES6 syntax and elide presentation details to focus on the pattern of data access.

```
// Story.react.js
export default class Story extends React.Component {
  render() {
    var story = this.props.story;
    return (
      <View>
        <Image uri={story.author.profilePicture.uri} />
        <Text>{story.author.name}</Text>
        <Text>{story.text}</Text>
      </View>
    );
  }
}
```



## [](#whats-the-story)What’s the `<Story>`?

Relay automates the process of fetching data for components by wrapping existing React components in Relay containers (themselves React components):

```
// Story.react.js
class Story extends React.Component { ... }

export default Relay.createContainer(Story, {
  fragments: {
    story: /* TODO */
  }
});
```

Before adding the GraphQL fragment, let’s look at the component hierarchy this creates:

[](/static/4e4a71a85b278968b8719601692bc18c/65c7b/relay-containers.png)

Most props will be passed through from the container to the original component. However, Relay will return the query results for a prop whenever a fragment is defined. In this case we’ll add a GraphQL fragment for `story`:

```
// Story.react.js
class Story extends React.Component { ... }

export default Relay.createContainer(Story, {
  fragments: {
    story: () => Relay.QL`
      fragment on Story {
        author {
          name
          profilePicture {
            uri
          }
        }
        text
      }
    `,
  },
});
```

Queries use ES6 template literals tagged with the `Relay.QL` function. Similar to how JSX transpiles to plain JavaScript objects and function calls, these template literals transpile to plain objects that describe fragments. Note that the fragment’s structure closely matches the object structure that we expected in `<Story>`’s render function.



## [](#storys-on-demand)`<Story>`s on Demand

We can render a Relay component by providing Relay with the component (`<Story>`) and the ID of the data (a story ID). Given this information, Relay will first fetch the results of the query and then `render()` the component. The value of `props.story` will be a plain JavaScript object such as the following:

```
{
  author: {
    name: "Greg",
    profilePicture: {
      uri: "https://…"
    }
  },
  text: "The first Relay blog post is up…"
}
```

Relay guarantees that all data required to render a component will be available before it is rendered. This means that `<Story>` does not need to handle a loading state; the `story` is *guaranteed* to be available before `render()` is called. We have found that this invariant simplifies our application code *and* improves the user experience. Of course, Relay also has options to delay the fetching of some parts of our queries.

The diagram below shows how Relay containers make data available to our React components:

[](/static/46e660a80043eb9e7a4ea27b3562d4a7/99375/relay-containers-data-flow.png)

## [](#newsfeed-worthy)`<NewsFeed>` Worthy

Now that the `<Story>` is over we can continue with the `<NewsFeed>` component. Again, we’ll start with a React version:

```
// NewsFeed.react.js
class NewsFeed extends React.Component {
  render() {
    var stories = this.props.viewer.stories; // `viewer` is the active user
    return (
      <View>
        {stories.map(story => <Story story={story} />)}
        <Button onClick={() => this.loadMore()}>Load More</Button>
      </View>
    );
  }

  loadMore() {
    // TODO: fetch more stories
  }
}

module.exports = NewsFeed;
```



## [](#all-the-news-fit-to-be-relayed)All the News Fit to be Relayed

`<NewsFeed>` has two new requirements: it composes `<Story>` and requests more data at runtime.

Just as React views can be nested, Relay components can compose query fragments from child components. Composition in GraphQL uses ES6 template literal substitution: `${Component.getFragment('prop')}`. Pagination can be accomplished with a variable, specified with `$variable` (as in `stories(first: $count)`):

```
// NewsFeed.react.js
class NewsFeed extends React.Component { ... }

export default Relay.createContainer(NewsFeed, {
  initialVariables: {
    count: 3                                /* default to 3 stories */
  },
  fragments: {
    viewer: () => Relay.QL`
      fragment on Viewer {
        stories(first: $count) {            /* fetch viewer's stories */
          edges {                           /* traverse the graph */
            node {
              ${Story.getFragment('story')} /* compose child fragment */
            }
          }
        }
      }
    `,
  },
});
```

Whenever `<NewsFeed>` is rendered, Relay will recursively expand all the composed fragments and fetch the queries in a single trip to the server. In this case, the `text` and `author` data will be fetched for each of the 3 story nodes.

Query variables are available to components as `props.relay.variables` and can be modified with `props.relay.setVariables(nextVariables)`. We can use these to implement pagination:

```
// NewsFeed.react.js
class NewsFeed extends React.Component {
  render() { ... }

  loadMore() {
    // read current params
    var count = this.props.relay.variables.count;
    // update params
    this.props.relay.setVariables({
      count: count + 5,
    });
  }
}
```

Now when `loadMore()` is called, Relay will send a GraphQL request for the additional five stories. When these stories are fetched, the component will re-render with the new stories available in `props.viewer.stories` and the updated count reflected in `props.relay.variables.count`.



## [](#in-conclusion)In Conclusion

These two components form a solid core for our application. With the use of Relay containers and GraphQL queries, we’ve enabled the following benefits:

* Automatic and efficient pre-fetching of data for an entire view hierarchy in a single network request.
* Trivial pagination with automatic optimizations to fetch only the additional items.
* View composition and reusability, so that `<Story>` can be used on its own or within `<NewsFeed>`, without any changes to either component.
* Automatic subscriptions, so that components will re-render if their data changes. Unaffected components will not re-render unnecessarily.
* Exactly *zero* lines of imperative data fetching logic. Relay takes full advantage of React’s declarative component model.

But Relay has many more tricks up its sleeve. For example, it’s built from the start to handle reads and writes, allowing for features like optimistic client updates with transactional rollback. Relay can also defer fetching select parts of queries, and it uses a local data store to avoid fetching the same data twice. These are all powerful features that we hope to explore in future posts.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2015-03-19-building-the-facebook-news-feed-with-relay.md)

----
url: https://legacy.reactjs.org/blog/2014/03/14/community-roundup-18.html
----

March 14, 2014 by [Jonas Gebhardt](https://twitter.com/jonasgebhardt)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

In this Round-up, we are taking a few closer looks at React’s interplay with different frameworks and architectures.

## [](#little-framework-big-splash)“Little framework BIG splash”

Let’s start with yet another refreshing introduction to React: Craig Savolainen ([@maedhr](https://twitter.com/maedhr)) walks through some first steps, demonstrating [how to build a Google Maps component](http://infinitemonkeys.influitive.com/little-framework-big-splash) using React.

## [](#architecting-your-app-with-react)Architecting your app with react

Brandon Konkle ([@bkonkle](https://twitter.com/bkonkle)) [Architecting your app with react](http://lincolnloop.com/blog/architecting-your-app-react-part-1/) We’re looking forward to part 2!

> React is not a full MVC framework, and this is actually one of its strengths. Many who adopt React choose to do so alongside their favorite MVC framework, like Backbone. React has no opinions about routing or syncing data, so you can easily use your favorite tools to handle those aspects of your frontend application. You’ll often see React used to manage specific parts of an application’s UI and not others. React really shines, however, when you fully embrace its strategies and make it the core of your application’s interface.
>
> [Read the full article…](http://lincolnloop.com/blog/architecting-your-app-react-part-1/)

## [](#react-vs-async-dom-manipulation)React vs. async DOM manipulation

Eliseu Monar ([@eliseumds](https://twitter.com/eliseumds))‘s post ”[ReactJS vs async concurrent rendering](http://eliseumds.tumblr.com/post/77843550010/vitalbox-pchr-reactjs-vs-async-concurrent-rendering)” is a great example of how React quite literally renders a whole array of common web development work(arounds) obsolete.

## [](#react-scala-and-the-play-framework)React, Scala and the Play Framework

[Matthias Nehlsen](http://matthiasnehlsen.com/) wrote a detailed introductory piece on [React and the Play Framework](http://matthiasnehlsen.com/blog/2014/01/05/play-framework-and-facebooks-react-library/), including a helpful architectural diagram of a typical React app.

Nehlsen’s React frontend is the second implementation of his chat application’s frontend, following an AngularJS version. Both implementations are functionally equivalent and offer some perspective on differences between the two frameworks.

In [another article](http://matthiasnehlsen.com/blog/2014/01/24/scala-dot-js-and-reactjs/), he walks us through the process of using React with scala.js to implement app-wide undo functionality.

Also check out his [talk](http://m.ustream.tv/recorded/42780242) at Ping Conference 2014, in which he walks through a lot of the previously content in great detail.

## [](#react-and-backbone)React and Backbone

The folks over at [Venmo](https://venmo.com/) are using React in conjunction with Backbone. Thomas Boyt ([@thomasaboyt](https://twitter.com/thomasaboyt)) wrote [this detailed piece](http://www.thomasboyt.com/2013/12/17/using-reactjs-as-a-backbone-view.html) about why React and Backbone are “a fantastic pairing”.

## [](#react-vs-ember)React vs. Ember

Eric Berry ([@coderberry](https://twitter.com/coderberry)) developed Ember equivalents for some of the official React examples. Read his post for a side-by-side comparison of the respective implementations: [“Facebook React vs. Ember”](https://instructure.github.io/blog/2013/12/17/facebook-react-vs-ember/).

## [](#react-and-plain-old-html)React and plain old HTML

Daniel Lo Nigro ([@Daniel15](https://twitter.com/Daniel15)) created [React-Magic](https://github.com/reactjs/react-magic), which leverages React to ajaxify plain old html pages and even [allows CSS transitions between pageloads](http://stuff.dan.cx/facebook/react-hacks/magic/red.php).

> React-Magic intercepts all navigation (link clicks and form posts) and loads the requested page via an AJAX request. React is then used to “diff” the old HTML with the new HTML, and only update the parts of the DOM that have been changed.
>
> [Check out the project on GitHub…](https://github.com/reactjs/react-magic)

On a related note, [Reactize](https://turbo-react.herokuapp.com/) by Ross Allen ([@ssorallen](https://twitter.com/ssorallen)) is a similarly awesome project: A wrapper for Rails’ [Turbolinks](https://github.com/rails/turbolinks/), which seems to have inspired John Lynch ([@johnrlynch](https://twitter.com/johnrlynch)) to then create [a server-rendered version using the JSX transformer in Rails middleware](http://www.rigelgroupllc.com/blog/2014/01/12/react-jsx-transformer-in-rails-middleware/).

## [](#react-and-objectobserve)React and Object.observe

Check out [François de Campredon](https://github.com/fdecampredon)’s implementation of [TodoMVC based on React and ES6’s Object.observe](https://github.com/fdecampredon/react-observe-todomvc/).

## [](#react-and-angular)React and Angular

Ian Bicking ([@ianbicking](https://twitter.com/ianbicking)) of Mozilla Labs [explains why he “decided to go with React instead of Angular.js”](https://plus.google.com/+IanBicking/posts/Qj8R5SWAsfE).

### [](#ng-react-update)ng-React Update

[David Chang](https://github.com/davidchang) works through some performance improvements of his [ngReact](https://github.com/davidchang/ngReact) project. His post [“ng-React Update - React 0.9 and Angular Track By”](http://davidandsuzi.com/ngreact-update/) includes some helpful advice on boosting render performance for Angular components.

> Angular gives you a ton of functionality out of the box - a full MV\* framework - and I am a big fan, but I’ll admit that you need to know how to twist the right knobs to get performance.
>
> That said, React gives you a very strong view component out of the box with the performance baked right in. Try as I did, I couldn’t actually get it any faster. So pretty impressive stuff.
>
> [Read the full post…](http://davidandsuzi.com/ngreact-update/)

React was also recently mentioned at ng-conf, where the Angular team commented on React’s concept of the virtual DOM:

## [](#react-and-web-components)React and Web Components

Jonathan Krause ([@jonykrause](https://twitter.com/jonykrause)) offers his thoughts regarding [parallels between React and Web Components](http://jonykrau.se/posts/the-value-of-react), highlighting the value of React’s ability to render pages on the server practically for free.

## [](#immutable-react)Immutable React

[Peter Hausel](http://pk11.kinja.com/) shows how to build a Wikipedia auto-complete demo based on immutable data structures (similar to [mori](https://npmjs.org/package/mori)), really taking advantage of the framework’s one-way reactive data binding:

> Its truly reactive design makes DOM updates finally sane and when combined with persistent data structures one can experience JavaScript development like it was never done before.
>
> [Read the full post](http://tech.kinja.com/immutable-react-1495205675)

## [](#d3-and-react)D3 and React

[Ben Smith](http://10consulting.com/) built some great SVG-based charting components using a little less of D3 and a little more of React: [D3 and React - the future of charting components?](http://10consulting.com/2014/02/19/d3-plus-reactjs-for-charting/)

## [](#om-and-react)Om and React

Josh Haberman ([@joshhaberman](https://twitter.com/JoshHaberman)) discusses performance differences between React, Om and traditional MVC frameworks in ”[A closer look at OM vs React performance](http://blog.reverberate.org/2014/02/on-future-of-javascript-mvc-frameworks.html)“.

Speaking of Om: [Omchaya](https://github.com/sgrove/omchaya) by Sean Grove ([@sgrove](https://twitter.com/sgrove)) is a neat Cljs/Om example project.

## [](#random-tweets)Random Tweets

> Worked for 2 hours on a \[@react\_js]\(https\://twitter.com/react\_js) app sans internet. Love that I could get stuff done with it without googling every question.
>
> — John Shimek (@varikin) [February 20, 2014](https://twitter.com/varikin/status/436606891657949185)

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2014-03-14-community-roundup-18.md)

----
url: https://18.react.dev/reference/react/components
----

[API Reference](/reference/react)

# Built-in React Components[](#undefined "Link for this heading")

React exposes a few built-in components that you can use in your JSX.

***

## Built-in components[](#built-in-components "Link for Built-in components ")

* [`<Fragment>`](/reference/react/Fragment), alternatively written as `<>...</>`, lets you group multiple JSX nodes together.
* [`<Profiler>`](/reference/react/Profiler) lets you measure rendering performance of a React tree programmatically.
* [`<Suspense>`](/reference/react/Suspense) lets you display a fallback while the child components are loading.
* [`<StrictMode>`](/reference/react/StrictMode) enables extra development-only checks that help you find bugs early.

***

## Your own components[](#your-own-components "Link for Your own components ")

You can also [define your own components](/learn/your-first-component) as JavaScript functions.

[PrevioususeTransition](/reference/react/useTransition)

[Next\<Fragment> (<>)](/reference/react/Fragment)

***

----
url: https://18.react.dev/reference/react/cloneElement
----

[API Reference](/reference/react)

[Legacy React APIs](/reference/react/legacy)

# cloneElement[](#undefined "Link for this heading")

### Pitfall

Using `cloneElement` is uncommon and can lead to fragile code. [See common alternatives.](#alternatives)

`cloneElement` lets you create a new React element using another element as a starting point.

```
const clonedElement = cloneElement(element, props, ...children)
```

***

## Reference[](#reference "Link for Reference ")

### `cloneElement(element, props, ...children)`[](#cloneelement "Link for this heading")

Call `cloneElement` to create a React element based on the `element`, but with different `props` and `children`:

```
import { cloneElement } from 'react';



// ...

const clonedElement = cloneElement(

  <Row title="Cabbage">

    Hello

  </Row>,

  { isHighlighted: true },

  'Goodbye'

);



console.log(clonedElement); // <Row title="Cabbage" isHighlighted={true}>Goodbye</Row>
```

***

## Usage[](#usage "Link for Usage ")

### Overriding props of an element[](#overriding-props-of-an-element "Link for Overriding props of an element ")

To override the props of some React element, pass it to `cloneElement` with the props you want to override:

```
import { cloneElement } from 'react';



// ...

const clonedElement = cloneElement(

  <Row title="Cabbage" />,

  { isHighlighted: true }

);
```

Here, the resulting cloned element will be `<Row title="Cabbage" isHighlighted={true} />`.

**Let’s walk through an example to see when it’s useful.**

Imagine a `List` component that renders its [`children`](/learn/passing-props-to-a-component#passing-jsx-as-children) as a list of selectable rows with a “Next” button that changes which row is selected. The `List` component needs to render the selected `Row` differently, so it clones every `<Row>` child that it has received, and adds an extra `isHighlighted: true` or `isHighlighted: false` prop:

```
export default function List({ children }) {

  const [selectedIndex, setSelectedIndex] = useState(0);

  return (

    <div className="List">

      {Children.map(children, (child, index) =>

        cloneElement(child, {

          isHighlighted: index === selectedIndex 

        })

      )}
```

Let’s say the original JSX received by `List` looks like this:

```
<List>

  <Row title="Cabbage" />

  <Row title="Garlic" />

  <Row title="Apple" />

</List>
```

By cloning its children, the `List` can pass extra information to every `Row` inside. The result looks like this:

```
<List>

  <Row

    title="Cabbage"

    isHighlighted={true} 

  />

  <Row

    title="Garlic"

    isHighlighted={false} 

  />

  <Row

    title="Apple"

    isHighlighted={false} 

  />

</List>
```

Notice how pressing “Next” updates the state of the `List`, and highlights a different row:

```
import { Children, cloneElement, useState } from 'react';

export default function List({ children }) {
  const [selectedIndex, setSelectedIndex] = useState(0);
  return (
    <div className="List">
      {Children.map(children, (child, index) =>
        cloneElement(child, {
          isHighlighted: index === selectedIndex 
        })
      )}
      <hr />
      <button onClick={() => {
        setSelectedIndex(i =>
          (i + 1) % Children.count(children)
        );
      }}>
        Next
      </button>
    </div>
  );
}
```

To summarize, the `List` cloned the `<Row />` elements it received and added an extra prop to them.

### Pitfall

Cloning children makes it hard to tell how the data flows through your app. Try one of the [alternatives.](#alternatives)

***

## Alternatives[](#alternatives "Link for Alternatives ")

### Passing data with a render prop[](#passing-data-with-a-render-prop "Link for Passing data with a render prop ")

Instead of using `cloneElement`, consider accepting a *render prop* like `renderItem`. Here, `List` receives `renderItem` as a prop. `List` calls `renderItem` for every item and passes `isHighlighted` as an argument:

```
export default function List({ items, renderItem }) {

  const [selectedIndex, setSelectedIndex] = useState(0);

  return (

    <div className="List">

      {items.map((item, index) => {

        const isHighlighted = index === selectedIndex;

        return renderItem(item, isHighlighted);

      })}
```

The `renderItem` prop is called a “render prop” because it’s a prop that specifies how to render something. For example, you can pass a `renderItem` implementation that renders a `<Row>` with the given `isHighlighted` value:

```
<List

  items={products}

  renderItem={(product, isHighlighted) =>

    <Row

      key={product.id}

      title={product.title}

      isHighlighted={isHighlighted}

    />

  }

/>
```

The end result is the same as with `cloneElement`:

```
<List>

  <Row

    title="Cabbage"

    isHighlighted={true} 

  />

  <Row

    title="Garlic"

    isHighlighted={false} 

  />

  <Row

    title="Apple"

    isHighlighted={false} 

  />

</List>
```

However, you can clearly trace where the `isHighlighted` value is coming from.

```
import { useState } from 'react';

export default function List({ items, renderItem }) {
  const [selectedIndex, setSelectedIndex] = useState(0);
  return (
    <div className="List">
      {items.map((item, index) => {
        const isHighlighted = index === selectedIndex;
        return renderItem(item, isHighlighted);
      })}
      <hr />
      <button onClick={() => {
        setSelectedIndex(i =>
          (i + 1) % items.length
        );
      }}>
        Next
      </button>
    </div>
  );
}
```

This pattern is preferred to `cloneElement` because it is more explicit.

***

### Passing data through context[](#passing-data-through-context "Link for Passing data through context ")

Another alternative to `cloneElement` is to [pass data through context.](/learn/passing-data-deeply-with-context)

For example, you can call [`createContext`](/reference/react/createContext) to define a `HighlightContext`:

```
export const HighlightContext = createContext(false);
```

Your `List` component can wrap every item it renders into a `HighlightContext` provider:

```
export default function List({ items, renderItem }) {

  const [selectedIndex, setSelectedIndex] = useState(0);

  return (

    <div className="List">

      {items.map((item, index) => {

        const isHighlighted = index === selectedIndex;

        return (

          <HighlightContext.Provider key={item.id} value={isHighlighted}>

            {renderItem(item)}

          </HighlightContext.Provider>

        );

      })}
```

With this approach, `Row` does not need to receive an `isHighlighted` prop at all. Instead, it reads the context:

```
export default function Row({ title }) {

  const isHighlighted = useContext(HighlightContext);

  // ...
```

This allows the calling component to not know or worry about passing `isHighlighted` to `<Row>`:

```
<List

  items={products}

  renderItem={product =>

    <Row title={product.title} />

  }

/>
```

Instead, `List` and `Row` coordinate the highlighting logic through context.

```
import { useState } from 'react';
import { HighlightContext } from './HighlightContext.js';

export default function List({ items, renderItem }) {
  const [selectedIndex, setSelectedIndex] = useState(0);
  return (
    <div className="List">
      {items.map((item, index) => {
        const isHighlighted = index === selectedIndex;
        return (
          <HighlightContext.Provider
            key={item.id}
            value={isHighlighted}
          >
            {renderItem(item)}
          </HighlightContext.Provider>
        );
      })}
      <hr />
      <button onClick={() => {
        setSelectedIndex(i =>
          (i + 1) % items.length
        );
      }}>
        Next
      </button>
    </div>
  );
}
```

[Learn more about passing data through context.](/reference/react/useContext#passing-data-deeply-into-the-tree)

***

### Extracting logic into a custom Hook[](#extracting-logic-into-a-custom-hook "Link for Extracting logic into a custom Hook ")

Another approach you can try is to extract the “non-visual” logic into your own Hook, and use the information returned by your Hook to decide what to render. For example, you could write a `useList` custom Hook like this:

```
import { useState } from 'react';



export default function useList(items) {

  const [selectedIndex, setSelectedIndex] = useState(0);



  function onNext() {

    setSelectedIndex(i =>

      (i + 1) % items.length

    );

  }



  const selected = items[selectedIndex];

  return [selected, onNext];

}
```

Then you could use it like this:

```
export default function App() {

  const [selected, onNext] = useList(products);

  return (

    <div className="List">

      {products.map(product =>

        <Row

          key={product.id}

          title={product.title}

          isHighlighted={selected === product}

        />

      )}

      <hr />

      <button onClick={onNext}>

        Next

      </button>

    </div>

  );

}
```

The data flow is explicit, but the state is inside the `useList` custom Hook that you can use from any component:

```
import Row from './Row.js';
import useList from './useList.js';
import { products } from './data.js';

export default function App() {
  const [selected, onNext] = useList(products);
  return (
    <div className="List">
      {products.map(product =>
        <Row
          key={product.id}
          title={product.title}
          isHighlighted={selected === product}
        />
      )}
      <hr />
      <button onClick={onNext}>
        Next
      </button>
    </div>
  );
}
```

This approach is particularly useful if you want to reuse this logic between different components.

[PreviousChildren](/reference/react/Children)

[NextComponent](/reference/react/Component)

***

----
url: https://18.react.dev/reference/react/apis
----

[API Reference](/reference/react)

# Built-in React APIs[](#undefined "Link for this heading")

In addition to [Hooks](/reference/react) and [Components](/reference/react/components), the `react` package exports a few other APIs that are useful for defining components. This page lists all the remaining modern React APIs.

***

* [`createContext`](/reference/react/createContext) lets you define and provide context to the child components. Used with [`useContext`.](/reference/react/useContext)
* [`forwardRef`](/reference/react/forwardRef) lets your component expose a DOM node as a ref to the parent. Used with [`useRef`.](/reference/react/useRef)
* [`lazy`](/reference/react/lazy) lets you defer loading a component’s code until it’s rendered for the first time.
* [`memo`](/reference/react/memo) lets your component skip re-renders with same props. Used with [`useMemo`](/reference/react/useMemo) and [`useCallback`.](/reference/react/useCallback)
* [`startTransition`](/reference/react/startTransition) lets you mark a state update as non-urgent. Similar to [`useTransition`.](/reference/react/useTransition)
* [`act`](/reference/react/act) lets you wrap renders and interactions in tests to ensure updates have processed before making assertions.

***

## Resource APIs[](#resource-apis "Link for Resource APIs ")

*Resources* can be accessed by a component without having them as part of their state. For example, a component can read a message from a Promise or read styling information from a context.

To read a value from a resource, use this API:

* [`use`](/reference/react/use) lets you read the value of a resource like a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) or [context](/learn/passing-data-deeply-with-context).

```
function MessageComponent({ messagePromise }) {

  const message = use(messagePromise);

  const theme = use(ThemeContext);

  // ...

}
```

[Previous\<Suspense>](/reference/react/Suspense)

[Nextact](/reference/react/act)

***

----
url: https://legacy.reactjs.org/blog/2013/08/05/community-roundup-6.html
----

August 05, 2013 by [Vjeux](https://twitter.com/vjeux)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

This is the first Community Round-up where none of the items are from Facebook/Instagram employees. It’s great to see the adoption of React growing.

## [](#react-game-tutorial)React Game Tutorial

[Caleb Cassel](https://twitter.com/CalebCassel) wrote a [step-by-step tutorial](https://rawgithub.com/calebcassel/react-demo/master/part1.html) about making a small game. It covers JSX, State and Events, Embedded Components and Integration with Backbone.

[](https://rawgithub.com/calebcassel/react-demo/master/part1.html)

## [](#reactify)Reactify

[Andrey Popp](http://andreypopp.com/) created a [Browserify](http://browserify.org/) helper to compile JSX files.

> Browserify v2 transform for `text/jsx`. Basic usage is:
>
> ```
> % browserify -t reactify main.jsx
> ```
>
> `reactify` transform activates for files with either `.jsx` extension or `/** @jsx React.DOM */` pragma as a first line for any `.js` file.
>
> [Check it out on GitHub…](https://github.com/andreypopp/reactify)

## [](#react-integration-with-este)React Integration with Este

[Daniel Steigerwald](http://daniel.steigerwald.cz/) is now using React within [Este](https://github.com/steida/este), which is a development stack for web apps in CoffeeScript that are statically typed using the Closure Library.

```
este.demos.react.todoApp = este.react.create (`/** @lends {React.ReactComponent.prototype} */`)
  render: ->
    @div [
      este.demos.react.todoList 'items': @state['items']
      if @state['items'].length
        @p "#{@state['items'].length} items."
      @form 'onSubmit': @onFormSubmit, [
        @input
          'onChange': @onChange
          'value': @state['text']
          'autoFocus': true
          'ref': 'textInput'
        @button "Add ##{@state['items'].length + 1}"
      ]
    ]
```

[Check it out on GitHub…](https://github.com/steida/este-library/blob/master/este/demos/thirdparty/react/start.coffee)

## [](#react-stylus-boilerplate)React Stylus Boilerplate

[Zaim Bakar](https://zaim.github.io/) shared his boilerplate to get started with Stylus CSS processor.

> This is my boilerplate React project using Grunt as the build tool, and Stylus as my CSS preprocessor.
>
> * Very minimal HTML boilerplate
>
> * Uses Stylus, with nib included
>
> * Uses two build targets:
>
>   * `grunt build` to compile JSX and Stylus into a development build
>   * `grunt dist` to minify and optimize the development build for production
>
> [Check it out on GitHub…](https://github.com/zaim/react-stylus-boilerplate)

## [](#webfui)WebFUI

[Conrad Barski](http://lisperati.com/), author of the popular book [Land of Lisp](http://landoflisp.com/), wants to use React for his ClojureScript library called [WebFUI](https://github.com/drcode/webfui).

> I’m the author of ”[Land of Lisp](http://landoflisp.com/)” and I love your framework. I built a somewhat similar framework a year ago [WebFUI](https://github.com/drcode/webfui) aimed at ClojureScript. My framework also uses global event delegates, a global “render” function, DOM reconciliation, etc just like react.js. (Of course these ideas all have been floating around the ether for ages, always great to see more people building on them.)
>
> Your implementation is more robust, and so I think the next point release of webfui will simply delegate all the “hard work” to react.js and will only focus on the areas where it adds value (enabling purely functional UI programming in clojurescript, and some other stuff related to streamlining event handling)
>
> [](https://groups.google.com/forum/#!msg/reactjs/e3bYersyd64/qODfcuBR9LwJ)
>
> [Read the full post…](https://groups.google.com/forum/#!msg/reactjs/e3bYersyd64/qODfcuBR9LwJ)

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2013-08-05-community-roundup-6.md)

----
url: https://legacy.reactjs.org/acknowledgements.html
----

# Acknowledgements

We'd like to thank all of our contributors:

* 839
* Aaron Ackerman
* Aaron Cannon
* Aaron Franks
* Aaron Gelter
* Abhay Nikam
* Abhishek Soni
* Adam
* Adam Bloomston
* Adam Krebs
* Adam Mark
* Adam Solove
* Adam Stankiewicz
* Adam Timberlake
* Adam Zapletal
* Addy Osmani
* Adrian Sieber
* Aesop Wolf
* Ahmad Wali Sidiqi
* Alan Plum
* Alan Souza
* Alan deLevie
* Alastair Hole
* Alex
* Alex Babkov
* Alex Baumgertner
* Alex Boatwright
* Alex Boyd
* Alex Dajani
* Alex Jacobs
* Alex Katopodis
* Alex Lopatin
* Alex Mykyta
* Alex Pien
* Alex Smith
* Alex Zelenskiy
* Alex Zherdev
* Alexander
* Alexander Shtuchkin
* Alexander Solovyov
* Alexander Tseung
* Alexandre Gaudencio
* Alexandre Kirszenberg
* Alexey Raspopov
* Alexey Shamrin
* Ali Taheri Moghaddar
* Ali Ukani
* Alireza Mostafizi
* Almero Steyn
* Amanvir Sangha
* Amjad Masad
* Anastasia A
* Andre Giron
* Andre Z Sanchez
* Andreas Möller
* Andreas Savvides
* Andreas Svensson
* Andres Kalle
* Andres Suarez
* Andrew Clark
* Andrew Cobby
* Andrew Davey
* Andrew Henderson
* Andrew Imm
* Andrew Kulakov
* Andrew Lo
* Andrew Poliakov
* Andrew Rasmussen
* Andrew Rota
* Andrew Sokolov
* Andrew Zich
* Andrey Marchenko
* Andrey Okonetchnikov
* Andrey Popp
* Andrey Safronov
* Andy Edwards
* Ankeet Maini
* Anthony van der Hoorn
* Anto Aravinth
* Antonio Ruberto
* Antti Ahti
* António Nuno Monteiro
* Anuj Tomar
* Anuja Ware
* AoDev
* April Arcus
* Areeb Malik
* Aria Buckles
* Aria Stewart
* Arian Faurtosh
* Arni Fannar
* Arshabh Kumar Agarwal
* Artem Nezvigin
* Arthur Gunn
* Ashish
* Austin Wright
* Avinash Kondeti
* Ayman Osman
* B.Orlov
* BDav24
* BEAUDRU Manuel
* Baraa Hamodi
* Bartosz Kaszubowski
* Basarat Ali Syed
* Battaile Fauber
* Beau Smith
* Ben Anderson
* Ben Berman
* Ben Brooks
* Ben Foxall
* Ben Halpern
* Ben Jaffe
* Ben Moss
* Ben Newman
* Ben Ripkens
* Benedikt Meurer
* Benjamin Keen
* Benjamin Leiken
* Benjamin Woodruff
* Benjy Cui
* Benoit Girard
* Benton Rochester
* Bernard Lin
* Bill Blanchard
* Bill Fisher
* Billy Shih
* Blaine Hatab
* Blaine Kasten
* Bob Eagan
* Bob Ralian
* Bob Renwick
* Bobby
* Bogdan Chadkin
* Bojan Mihelac
* Boris Yankov
* Brad Vogel
* Bradford
* Bradley Spaulding
* Brandon Bloom
* Brandon Dail
* Brandon Tilley
* Brenard Cubacub
* Brent Vatne
* Brian Cooke
* Brian Emil Hartz
* Brian Holt
* Brian Hsu
* Brian Kim
* Brian Kung
* Brian Reavis
* Brian Rue
* Brian Vaughn
* Bruce Harris
* Bruno Heridet
* Bruno Škvorc
* Bryan Braun
* CT Wu
* Cam Song
* Cam Spiers
* Cameron Chamberlain
* Cameron Matheson
* Carolina Powers
* Carter Chung
* Cassus Adam Banko
* Cat Chen
* Cedric Sohrauer
* Cesar William Alvarenga
* Chad Fawcett
* Changsoon Bok
* Charles Marsh
* Charlie Garcia
* Chase Adams
* Cheng Lou
* Chitharanjan Das
* Chris
* Chris Bolin
* Chris Grovers
* Chris Ha
* Chris Pearce
* Chris Rebert
* Chris Sciolla
* Christian Alfoni
* Christian Oliff
* Christian Roman
* Christoffer Sawicki
* Christoph Pojer
* Christophe Hurpeau
* Christopher Monsanto
* Claudio Brandolino
* Clay Allsopp
* Clay Miller
* Clement Hoang
* CodinCat
* Cody Reichert
* Colin Wren
* Connor McSheffrey
* Conor Hastings
* Constantin Gavrilete
* Cory House
* Cotton Hou
* Craig Akimoto
* Cristovao Verstraeten
* DQNEO
* Dai Nguyen
* Damian Nicholson
* Damien Pellier
* Damien Soulard
* Dan Abramov
* Dan Fox
* Dan Schafer
* DanZeuss
* Daniel Carlsson
* Daniel Cousens
* Daniel Friesen
* Daniel Gasienica
* Daniel Hejl
* Daniel Hejl
* Daniel Liburd
* Daniel Lo Nigro
* Daniel Mané
* Daniel Miladinov
* Daniel Rodgers-Pryor
* Daniel Rosenwasser
* Daniel Rotter
* Daniel Schonfeld
* Daniela Borges
* Danilo Vitoriano
* Danny Ben-David
* Danny Hurlburt
* Darcy
* Daryl Lau
* Darío Javier Cravero
* Dave Galbraith
* Dave Lunny
* Dave Voyles
* David Aurelio
* David Baker
* David Beitey
* David Ed Mellum
* David Goldberg
* David Granado
* David Greenspan
* David Hellsing
* David Hu
* David Khourshid
* David Mininger
* David Neubauer
* David Percy
* Dean Shi
* Denis Laxalde
* Denis Pismenny
* Denis Sokolov
* Deniss Jacenko
* Dennis Johnson
* Desmond Brand
* Devedse
* Devinsuit
* Devon Blandin
* Devon Harvey
* Dheeraj Kumar
* Dhyey Thakore
* Diego Muracciole
* Dima Beznos
* Dimzel Sobolev
* Dmitri Zaitsev
* Dmitrii Abramov
* Dmitriy Kubyshkin
* Dmitriy Rozhkov
* Dmitry Blues
* Dmitry Mazuro
* Dmitry Zhuravlev-Nevsky
* Domenico Matteo
* Dominic Gannaway
* Don Abrams
* Dongsheng Liu
* Duke Pham
* Dustan Kasten
* Dustin Getz
* Dylan Harrington
* Dylan Kirby
* Edgar (Algebr)
* Eduard
* Eduardo Garcia
* Edvin Erikson
* Elaine Fang
* Eli White
* Enguerran
* Eoin Hennessy
* Eric Churchill
* Eric Clemmons
* Eric Douglas
* Eric Eastwood
* Eric Elliott
* Eric Florenzano
* Eric Matthys
* Eric Nakagawa
* Eric O'Connell
* Eric Pitcher
* Eric Sakmar
* Eric Schoffstall
* Erik Harper
* Erik Hellman
* Espen Hovlandsdal
* Esteban
* Eugene
* EugeneGarbuzov
* Evan Coonrod
* Evan Jacobs
* Evan Scott
* Evan Vosberg
* Fabio M. Costa
* Fabrizio Castellarin
* Faheel Ahmad
* Fatih
* Federico Rampazzo
* Felipe Oliveira Carvalho
* Felix Gnass
* Felix Kling
* Fernando Alex Helwanger
* Fernando Correia
* Fernando Montoya
* Filip Hoško
* Filip Spiridonov
* Flarnie Marchan
* Fokke Zandbergen
* Frank Yan
* Frankie Bagnardi
* François Chalifour
* François-Xavier Bois
* Fraser Haer
* Fred Zhao
* Freddy Rangel
* Fyodor Ivanishchev
* G Scott Olson
* G. Kay Lee
* Gabe Levi
* Gabriel Lett Viviani
* Gajus Kuizinas
* Gant Laborde
* Gareth Nicholson
* Garmash Nikolay
* Garren Smith
* Garrett McCullough
* Gavin McQuistin
* Gaëtan Renaudeau
* Geert Pasteels
* Geert-Jan Brits
* George A Sisco III
* Georgii Dolzhykov
* Gert Hengeveld
* Giamir Buoncristiani
* Gil Chen-Zion
* Gilbert
* Giorgio Polvara
* Giuseppe
* Glen Mailer
* Grant Timmerman
* Greg Hurrell
* Greg Palmer
* Greg Perkins
* Greg Roodt
* Gregory
* Grgur Grisogono
* Griffin Michl
* Guangqiang Dong
* Guido Bouman
* Guilherme Oenning
* Guilherme Ruiz
* Guillaume Claret
* Harry Hull
* Harry Marr
* Harry Moreno
* Harshad Sabne
* Hekar Khani
* Hendrik Swanepoel
* Henrik Nyh
* Henry Harris
* Henry Wong
* Henry Zhu
* Hideo Matsumoto
* Hikaru Suido
* Hiroyuki Wada
* Hou Chia
* Huang-Wei Chang
* Hugo Agbonon
* Hugo Jobling
* Hyeock Kwon
* Héctor Ramos
* Héliton Nordt
* Ian Obermiller
* Ian Sutherland
* Ignacio Carbajo
* Igor Scekic
* Ike Peters
* Ilia Pavlenkov
* Ilya Gelman
* Ilya Shuklin
* Ilyá Belsky
* Ingvar Stepanyan
* Irae Carvalho
* Isaac Salier-Hellendag
* Islam Sharabash
* Iurii Kucherov
* Ivan
* Ivan Kozik
* Ivan Krechetov
* Ivan Vergiliev
* Ivan Zotov
* J. Andrew Brassington
* J. Renée Beach
* JD Isaacks
* JJ Weber
* JW
* Jack
* Jack Cross
* Jack Ford
* Jack Zhang
* Jackie Wung
* Jackson Huang
* Jacob Gable
* Jacob Greenleaf
* Jacob Lamont
* Jae Hun Lee
* Jae Hun Ro
* Jaeho Lee
* Jaime Mingo
* Jake Boone
* Jake Worth
* Jakub Malinowski
* James
* James Brantly
* James Burnett
* James Friend
* James Ide
* James Long
* James Pearce
* James Seppi
* James South
* James Wen
* Jamie Wong
* Jamis Charles
* Jamison Dance
* Jan Hancic
* Jan Kassens
* Jan Raasch
* Jan Schär
* Jane Manchun Wong
* Jared Forsyth
* Jared Fox
* Jarrod Mosen
* Jason
* Jason Bonta
* Jason Grlicky
* Jason Ly
* Jason Miller
* Jason Quense
* Jason Trill
* Jason Webster
* Jay Jaeho Lee
* Jay Phelps
* Jayen Ashar
* Jean Lauliac
* Jed Watson
* Jeff Barczewski
* Jeff Carpenter
* Jeff Chan
* Jeff Hicken
* Jeff Kolesky
* Jeff Morrison
* Jeff Welch
* Jeffrey Lin
* Jeffrey Wan
* Jen Wong
* Jeremy Fairbank
* Jess Telford
* Jesse Skinner
* Jignesh Kakadiya
* Jim OBrien
* Jim Sproch
* Jiminikiz
* Jimmy Jea
* Jing Chen
* Jinwoo Oh
* Jinxiu Lee
* Jirat Ki
* Jiyeon Seo
* Jody McIntyre
* Joe Critchley
* Joe Stein
* Joel Auterson
* Joel Denning
* Joel Sequeira
* Johan Tinglöf
* Johannes Baiter
* Johannes Emerich
* Johannes Lumpe
* John Heroy
* John Longanecker
* John Ryan
* John Watson
* John-David Dalton
* Jon Beebe
* Jon Bretman
* Jon Chester
* Jon Hester
* Jon Madison
* Jon Scott Clark
* Jon Tewksbury
* Jonas Enlund
* Jonas Gebhardt
* Jonathan Hsu
* Jonathan Persson
* Jordan Harband
* Jordan Walke
* Jorrit Schippers
* Joseph Nudell
* Joseph Savona
* Josh Bassett
* Josh Duck
* Josh Hunt
* Josh Perez
* Josh Yudaken
* Joshua Evans
* Joshua Go
* Joshua Goldberg
* Joshua Ma
* João Valente
* Juan
* Juan Serrano
* Julen Ruiz Aizpuru
* Julian Viereck
* Julien Bordellier
* Julio Lopez
* Jun Kim
* Jun Wu
* Juraj Dudak
* Justas Brazauskas
* Justin
* Justin Grant
* Justin Jaffray
* Justin Robison
* Justin Woo
* KB
* Kale
* Kamron Batman
* Karl Horky
* Karl Mikkelsen
* Karpich Dmitry
* Karthik Balakrishnan
* Karthik Chintapalli
* Kateryna
* Kaylee Knowles
* KeicaM
* Keito Uchiyama
* Ken Powers
* Kenneth Chau
* Kent C. Dodds
* Kevin Cheng
* Kevin Coughlin
* Kevin Huang
* Kevin Lacker
* Kevin Lau
* Kevin Lin
* Kevin Old
* Kevin Robinson
* Kevin Suttle
* Kewei Jiang
* Keyan Zhang
* Kier Borromeo
* Kiho · Cham
* KimCoding
* Kirk Steven Hansen
* Kit Randel
* Kite
* Kohei TAKATA
* Koo Youngmin
* Krystian Karczewski
* Kunal Mehta
* Kurt Furbush
* Kurt Ruppel
* Kurt Weiberth
* Kyle Kelley
* Kyle Mathews
* Laurence Rowe
* Laurent Etiemble
* Lee Byron
* Lee Jaeyoung
* Lee Sanghyeon
* Lei
* Leland Richardson
* Leon Fedotov
* Leon Yip
* Leonardo YongUk Kim
* Levi Buzolic
* Levi McCallum
* Lewis Blackwood
* Liangzhen Zhu
* Lily
* Linus Unnebäck
* Lipis
* Liz
* Logan Allen
* Lovisa Svallingson
* Lucas
* Ludovico Fischer
* Luigy Leon
* Luke Belliveau
* Luke Horvat
* Lutz Rosema
* MICHAEL JACKSON
* MIKAMI Yoshiyuki
* Maciej Kasprzyk
* Maher Beg
* Maksim Shastsel
* Manas
* Marcelo Alves
* Marcin K.
* Marcin Kwiatkowski
* Marcin Mazurek
* Marcin Szczepanski
* Marcio Puga
* Marcos Ojeda
* Marcy Sutton
* Mariano Desanze
* Mario Souto
* Marius Skaar Ludvigsen
* Marjan
* Mark Anderson
* Mark Funk
* Mark Hintz
* Mark IJbema
* Mark Murphy
* Mark Pedrotti
* Mark Penner
* Mark Richardson
* Mark Rushakoff
* Mark Sun
* Marks Polakovs
* Marlon Landaverde
* Marshall Bowers
* Marshall Roch
* Martin Andert
* Martin Hochel
* Martin Hujer
* Martin Jul
* Martin Konicek
* Martin Mihaylov
* Martin V
* Masaki KOBAYASHI
* Mateusz Burzyński
* Mathieu M-Gosselin
* Mathieu Savy
* Matias Singers
* Matsunoki
* Matt Brookes
* Matt Dunn-Rankin
* Matt Harrison
* Matt Huggins
* Matt Stow
* Matt Zabriskie
* Matthew Dapena-Tretter
* Matthew Herbst
* Matthew Hodgson
* Matthew Johnston
* Matthew King
* Matthew Looi
* Matthew Miner
* Matthew Shotton
* Matthias Le Brun
* Matti Nelimarkka
* Mattijs Kneppers
* Max Donchenko
* Max F. Albrecht
* Max Heiber
* Max Stoiber
* Maxi Ferreira
* Maxim Abramchuk
* Maxwel D'souza
* Merrick Christensen
* Mert Kahyaoğlu
* Michael Chan
* Michael Jackson
* Michael McDermott
* Michael O'Brien
* Michael Randers-Pehrson
* Michael Ridgway
* Michael Sinov
* Michael Terry
* Michael Warner
* Michael Wiencek
* Michael Ziwisky
* Michal Srb
* Michał Ordon
* Michał Pierzchała
* Michele Bertoli
* Michelle Todd
* Michiya
* Mihai Parparita
* Mike D Pilsbury
* Mike Groseclose
* Mike Nordick
* Mikhail Osher
* Mikolaj Dadela
* Miles Johnson
* Miller Medeiros
* Minwe LUO
* Minwei Xu
* Miorel Palii
* Mitchel Humpherys
* Mitermayer Reis
* Moacir Rosa
* Mojtaba Dashtinejad
* Morhaus
* Moshe Kolodny
* Mouad Debbar
* Murad
* Murray M. Moss
* Murtaza Haveliwala
* NE-SmallTown
* Nadeesha Cabral
* Naman Goel
* Nate
* Nate Hunzaker
* Nate Lee
* Nate Norberg
* Nathan Hardy
* Nathan Smith
* Nathan White
* Nee
* Neo
* Neri Marschik
* NestorTejero
* Nguyen Truong Duy
* Nicholas Bergson-Shilcock
* Nicholas Clawson
* Nick Balestra
* Nick Fitzgerald
* Nick Gavalas
* Nick Kasten
* Nick Merwin
* Nick Presta
* Nick Raienko
* Nick Thompson
* Nick Williams
* Nik Nyby
* Nikita Lebedev
* Niklas Boström
* Nikoloz Buligini
* Nima Jahanshahi
* Ning Xia
* Niole Nelson
* Nolan Lawson
* Nuno Campos
* OJ Kwon
* Oiva Eskola
* Oleg
* Oleksii Markhovskyi
* Oliver Zeigermann
* Olivier Tassinari
* Omid Hezaveh
* Oscar Bolmsten
* Oskari Mantere
* Owen Coutts
* Pablo Lacerda de Miranda
* Paolo Moretti
* Pascal Hartig
* Patrick
* Patrick Finnigan
* Patrick Laughlin
* Patrick Stapleton
* Paul Benigeri
* Paul Harper
* Paul Kehrer
* Paul Manta
* Paul O’Shannessy
* Paul Seiffert
* Paul Shen
* Pedro Nauck
* Pete Hunt
* Peter Blazejewicz
* Peter Cottle
* Peter Jaros
* Peter Newnham
* Peter Ruibal
* Petri Lehtinen
* Petri Lievonen
* Phil Quinn
* Phil Rajchgot
* Philip Jackson
* Philipp Spieß
* Pieter De Baets
* Pieter Vanderwerff
* Piotr Czajkowski
* Piper Chester
* Pontus Abrahamsson
* Pouja Nikray
* Prathamesh Sonpatki
* Prayag Verma
* Preston Parry
* Qin Junwen
* RSG
* Rachel D. Cartwright
* Rafael
* Rafael Angeline
* Rafal Dittwald
* Ragnar Þór Valgeirsson
* Rahul Gupta
* Rainer Oviir
* Raito Bezarius
* Rajat Sehgal
* Rajiv Tirumalareddy
* Ram Kaniyur
* Randall Randall
* Ray
* Ray Dai
* Raymond Ha
* Reed Loden
* Remko Tronçon
* Ricardo
* Rich Harris
* Richard
* Richard D. Worth
* Richard Feldman
* Richard Kho
* Richard Littauer
* Richard Livesey
* Richard Maisano
* Richard Roncancio
* Richard Wood
* Richie Thomas
* Rick Beerendonk
* Rick Ford
* Riley Tomasek
* Rob Arnold
* Robert Binna
* Robert Chang
* Robert Haritonov
* Robert Kielty
* Robert Knight
* Robert Martin
* Robert Sedovsek
* Robin Berjon
* Robin Frischmann
* Robin Ricard
* Roderick Hsiao
* Rodrigo Pombo
* Rohan Nair
* Roman Liutikov
* Roman Matusevich
* Roman Pominov
* Roman Vanesyan
* Rui Araújo
* Russ
* Ryan Lahfa
* Ryan Seddon
* Ryo Shibayama
* Sahat Yalkabov
* Saif Hakim
* Saiichi Hashimoto
* Sakina Crocker
* Sam Balana
* Sam Beveridge
* Sam Saccone
* Sam Selikoff
* Samer Buna
* Samuel
* Samuel Hapák
* Samuel Reed
* Samuel Scheiderich
* Samy Al Zahrani
* Sander Spies
* Sasha Aickin
* Sassan Haradji
* Satoshi Nakajima
* Scott
* Scott Burch
* Scott Feeney
* Sean Gransee
* Sean Kinsey
* Sean Smith
* Seba
* Sebastian Markbåge
* Sebastian McKenzie
* Senin Roman
* Seoh Char
* Sercan Eraslan
* Serg
* Sergey Generalov
* Sergey Rubanov
* Seyi Adebajo
* Shane O'Sullivan
* Shaun Trennery
* ShihChi Huang
* Shim Won
* Shinnosuke Watanabe
* Shogun Sea
* Shota Kubota
* Shripad K
* Shubheksha Jalan
* Shuhei Kagawa
* Sibi
* Simen Bekkhus
* Simon Højberg
* Simon Welsh
* Simone Vittori
* Skasi
* Snowmanzzz(Zhengzhong Zhao)
* Soichiro Kawamura
* Soo Jae Hwang
* Sophia
* Sophia Westwood
* Sophie Alpert
* Sota Ohara
* Spen Taylor
* Spencer Ahrens
* Spencer Handley
* Sriram Thiagarajan
* Stefan Dombrowski
* Stephen John Sorensen
* Stephen Murphy
* Stephie
* Sterling Cobb
* Steve Baker
* Steve Mao
* Steven Luscher
* Steven Syrek
* Steven Vachon
* Stolenkid
* Stoyan Stefanov
* Stuart Harris
* SunHuawei
* Sundeep Malladi
* Sung Won Cho
* Sunny Juneja
* Sunny Ripert
* Superlaziness
* Sven Helmberger
* Sverre Johansen
* Swaroop SM
* Sébastien Lorber
* Sławomir Laskowski
* Taegon Kim
* Taeho Kim
* Taehwan, No
* Tanase Hagi
* Tanner
* Tay Yang Shun
* Ted Kim
* TedPowers
* Tengfei Guo
* Teodor Szente
* Tetsuharu OHZEKI
* Tetsuya Hasegawa
* Thibaut Rizzi
* Thomas Aylott
* Thomas Boyt
* Thomas Broadley
* Thomas Reggi
* Thomas Röggla
* Thomas Shaddox
* Thomas Shafer
* ThomasCrvsr
* Tiago Fernandez
* Tienchai Wirojsaksaree
* Tim Routowicz
* Tim Schaub
* Timothy Yung
* Timur Carpeev
* Tobias Reiss
* Tom Duncalf
* Tom Gasson
* Tom Haggie
* Tom Hauburger
* Tom MacWright
* Tom Occhino
* Tomasz Kołodziejski
* Tomoya Suzuki
* Tomáš Hromada
* Tony Rossi
* Tony Spiro
* Toru Kobayashi
* Trevor Smith
* Trinh Hoang Nhu
* Troy DeMonbreun
* Tsung Hung
* Tyler Brock
* Tyler Buchea
* Tyler Deitz
* Ujjwal Ojha
* Uladzimir Havenchyk
* Usman
* Ustin Zarubin
* Vadim Chernysh
* Valentin Shergin
* Van der Auwermeulen Grégoire
* Varayut Lerdkanlayanawat
* Varun Bhuvanendran
* Varun Rau
* Vasiliy Loginevskiy
* Vedat Mahir YILMAZ
* Veljko Tornjanski
* Vesa Laakso
* Victor Alvarez
* Victor Homyakov
* Victor Koenders
* Victoria Quirante
* Vikash Agrawal
* Ville Immonen
* Vincent Riemer
* Vincent Siao
* Vincent Taing
* Vipul A M
* Vitaliy Potapov
* Vitaly Kramskikh
* Vitor Balocco
* Vjeux
* Vladimir Kovpak
* Vladimir Tikunov
* Volkan Unsal
* Wander Wang
* Wayne Larsen
* Weizenlol
* Whien
* WickyNilliams
* Will Myers
* William Hoffmann
* Wincent Colaiuta
* Wout Mertens
* Xavier Morel
* XuefengWu
* Yakov Dalinchuk
* Yan Li
* Yasar icli
* Yaxian
* YouBao Nong
* Yuichi Hagio
* Yura Chuchola
* Yuriy Dybskiy
* Yusong Liu
* Yutaka Nakajima
* Yuval Dekel
* Zac Braddy
* Zac Smith
* Zach Bruggeman
* Zach Ramaekers
* Zacharias
* Zeke Sikelianos
* Zhangjd
* adraeth
* ankitml
* arush
* bel3atar
* brafdlog
* brillout
* chen
* chocolateboy
* cjshawMIT
* clariroid
* claudiopro
* cloudy1
* comerc
* cutbko
* davidxi
* dfrownfelter
* djskinner
* dongmeng.ldm
* everdimension
* gillchristian
* gitanupam
* guoyong yi
* hanumanthan
* hao.huang
* hjmoss
* hkal
* iamchenxin
* iamdoron
* iawia002
* imagentleman
* imjanghyuk
* inkinworld
* jaaberg
* jddxf
* jinmmd
* koh-taka
* kohashi85
* ksvitkovsky
* laiso
* lamo2k123
* leeyoungalias
* li.li
* lucas
* maxprafferty
* mdogadailo
* mfijas
* mguidotto
* mondaychen
* najisawas
* neeldeep
* newvlad
* nhducit
* ogom
* pingan1927
* rgarifullin
* saiyagg
* scloudyy
* segmentationfaulter
* shifengchen
* songawee
* starkch
* sugarshin
* tokikuch
* ventuno
* wacii
* wali-s
* walrusfruitcake
* yiminghe
* youmoo
* yuntao.qyt
* z.ky
* zhangjg
* zhangs
* zombieJ
* zwhitchcox
* Árni Hermann Reynisson
* 元彦
* 凌恒
* 张敏
* 王晓勇
* 龙海燕

In addition, we're grateful to

* [Jeff Barczewski](https://github.com/jeffbski) for allowing us to use the [react](https://www.npmjs.com/package/react) package name on npm.
* [Christopher Aue](https://christopheraue.net/) for letting us use the [reactjs.com](https://reactjs.com/) domain name and the [@reactjs](https://twitter.com/reactjs) username on Twitter.
* [ProjectMoon](https://github.com/ProjectMoon) for letting us use the [flux](https://www.npmjs.com/package/flux) package name on npm.
* Shane Anderson for allowing us to use the [react](https://github.com/react) org on GitHub.
* [Dmitri Voronianski](https://github.com/voronianski) for letting us use the [Oceanic Next](https://labs.voronianski.dev/oceanic-next-color-scheme/) color scheme on this website.

----
url: https://legacy.reactjs.org/blog/2013/12/18/react-v0.5.2-v0.4.2.html
----

December 18, 2013 by [Paul O’Shannessy](https://twitter.com/zpao)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

Today we’re releasing an update to address a potential XSS vulnerability that can arise when using user data as a `key`. Typically “safe” data is used for a `key`, for example, an id from your database, or a unique hash. However there are cases where it may be reasonable to use user generated content. A carefully crafted piece of content could result in arbitrary JS execution. While we make a very concerted effort to ensure all text is escaped before inserting it into the DOM, we missed one case. Immediately following the discovery of this vulnerability, we performed an audit to ensure we this was the only such vulnerability.

This only affects v0.5.x and v0.4.x. Versions in the 0.3.x family are unaffected.

Updated versions are available for immediate download via npm, bower, and on our [download page](/react/downloads.html).

We take security very seriously at Facebook. For most of our products, users don’t need to know that a security issue has been fixed. But with libraries like React, we need to make sure developers using React have access to fixes to keep their users safe.

While we’ve encouraged responsible disclosure as part of [Facebook’s whitehat bounty program](https://www.facebook.com/whitehat/) since we launched, we don’t have a good process for notifying our users. Hopefully we don’t need to use it, but moving forward we’ll set up a little bit more process to ensure the safety of our users. Ember.js has [an excellent policy](http://emberjs.com/security/) which we may use as our model.

You can learn more about the vulnerability discussed here: [CVE-2013-7035](https://groups.google.com/forum/#!topic/reactjs/OIqxlB2aGfU).

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2013-12-18-react-v0.5.2-v0.4.2.md)

----
url: https://react.dev/reference/react/createContext
----

[API Reference](/reference/react)

[APIs](/reference/react/apis)

# createContext[](#undefined "Link for this heading")

`createContext` lets you create a [context](/learn/passing-data-deeply-with-context) that components can provide or read.

```
const SomeContext = createContext(defaultValue)
```

* [Reference](#reference)

  * [`createContext(defaultValue)`](#createcontext)
  * [`SomeContext` Provider](#provider)
  * [`SomeContext.Consumer`](#consumer)

* [Usage](#usage)

  * [Creating context](#creating-context)
  * [Importing and exporting context from a file](#importing-and-exporting-context-from-a-file)

* [Troubleshooting](#troubleshooting)
  * [I can’t find a way to change the context value](#i-cant-find-a-way-to-change-the-context-value)

***

## Reference[](#reference "Link for Reference ")

### `createContext(defaultValue)`[](#createcontext "Link for this heading")

Call `createContext` outside of any components to create a context.

```
import { createContext } from 'react';



const ThemeContext = createContext('light');
```

[See more examples below.](#usage)

#### Parameters[](#parameters "Link for Parameters ")

* `defaultValue`: The value that you want the context to have when there is no matching context provider in the tree above the component that reads context. If you don’t have any meaningful default value, specify `null`. The default value is meant as a “last resort” fallback. It is static and never changes over time.

#### Returns[](#returns "Link for Returns ")

`createContext` returns a context object.

**The context object itself does not hold any information.** It represents *which* context other components read or provide. Typically, you will use [`SomeContext`](#provider) in components above to specify the context value, and call [`useContext(SomeContext)`](/reference/react/useContext) in components below to read it. The context object has a few properties:

* `SomeContext` lets you provide the context value to components.
* `SomeContext.Consumer` is an alternative and rarely used way to read the context value.
* `SomeContext.Provider` is a legacy way to provide the context value before React 19.

***

### `SomeContext` Provider[](#provider "Link for this heading")

Wrap your components into a context provider to specify the value of this context for all components inside:

```
function App() {

  const [theme, setTheme] = useState('light');

  // ...

  return (

    <ThemeContext value={theme}>

      <Page />

    </ThemeContext>

  );

}
```

### Note

Starting in React 19, you can render `<SomeContext>` as a provider.

In older versions of React, use `<SomeContext.Provider>`.

#### Props[](#provider-props "Link for Props ")

* `value`: The value that you want to pass to all the components reading this context inside this provider, no matter how deep. The context value can be of any type. A component calling [`useContext(SomeContext)`](/reference/react/useContext) inside of the provider receives the `value` of the innermost corresponding context provider above it.

***

### `SomeContext.Consumer`[](#consumer "Link for this heading")

Before `useContext` existed, there was an older way to read context:

```
function Button() {

  // 🟡 Legacy way (not recommended)

  return (

    <ThemeContext.Consumer>

      {theme => (

        <button className={theme} />

      )}

    </ThemeContext.Consumer>

  );

}
```

Although this older way still works, **newly written code should read context with [`useContext()`](/reference/react/useContext) instead:**

```
function Button() {

  // ✅ Recommended way

  const theme = useContext(ThemeContext);

  return <button className={theme} />;

}
```

#### Props[](#consumer-props "Link for Props ")

* `children`: A function. React will call the function you pass with the current context value determined by the same algorithm as [`useContext()`](/reference/react/useContext) does, and render the result you return from this function. React will also re-run this function and update the UI whenever the context from the parent components changes.

***

## Usage[](#usage "Link for Usage ")

### Creating context[](#creating-context "Link for Creating context ")

Context lets components [pass information deep down](/learn/passing-data-deeply-with-context) without explicitly passing props.

Call `createContext` outside any components to create one or more contexts.

```
import { createContext } from 'react';



const ThemeContext = createContext('light');

const AuthContext = createContext(null);
```

`createContext` returns a context object. Components can read context by passing it to [`useContext()`](/reference/react/useContext):

```
function Button() {

  const theme = useContext(ThemeContext);

  // ...

}



function Profile() {

  const currentUser = useContext(AuthContext);

  // ...

}
```

By default, the values they receive will be the default values you have specified when creating the contexts. However, by itself this isn’t useful because the default values never change.

Context is useful because you can **provide other, dynamic values from your components:**

```
function App() {

  const [theme, setTheme] = useState('dark');

  const [currentUser, setCurrentUser] = useState({ name: 'Taylor' });



  // ...



  return (

    <ThemeContext value={theme}>

      <AuthContext value={currentUser}>

        <Page />

      </AuthContext>

    </ThemeContext>

  );

}
```

Now the `Page` component and any components inside it, no matter how deep, will “see” the passed context values. If the passed context values change, React will re-render the components reading the context as well.

[Read more about reading and providing context and see examples.](/reference/react/useContext)

***

### Importing and exporting context from a file[](#importing-and-exporting-context-from-a-file "Link for Importing and exporting context from a file ")

Often, components in different files will need access to the same context. This is why it’s common to declare contexts in a separate file. Then you can use the [`export` statement](https://developer.mozilla.org/en-US/docs/web/javascript/reference/statements/export) to make context available for other files:

```
// Contexts.js

import { createContext } from 'react';



export const ThemeContext = createContext('light');

export const AuthContext = createContext(null);
```

Components declared in other files can then use the [`import`](https://developer.mozilla.org/en-US/docs/web/javascript/reference/statements/import) statement to read or provide this context:

```
// Button.js

import { ThemeContext } from './Contexts.js';



function Button() {

  const theme = useContext(ThemeContext);

  // ...

}
```

```
// App.js

import { ThemeContext, AuthContext } from './Contexts.js';



function App() {

  // ...

  return (

    <ThemeContext value={theme}>

      <AuthContext value={currentUser}>

        <Page />

      </AuthContext>

    </ThemeContext>

  );

}
```

This works similar to [importing and exporting components.](/learn/importing-and-exporting-components)

***

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### I can’t find a way to change the context value[](#i-cant-find-a-way-to-change-the-context-value "Link for I can’t find a way to change the context value ")

Code like this specifies the *default* context value:

```
const ThemeContext = createContext('light');
```

This value never changes. React only uses this value as a fallback if it can’t find a matching provider above.

To make context change over time, [add state and wrap components in a context provider.](/reference/react/useContext#updating-data-passed-via-context)

[PreviouscaptureOwnerStack](/reference/react/captureOwnerStack)

[Nextlazy](/reference/react/lazy)

***

----
url: https://react.dev/learn/state-as-a-snapshot
----

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function Form() {
  const [isSent, setIsSent] = useState(false);
  const [message, setMessage] = useState('Hi!');
  if (isSent) {
    return <h1>Your message is on its way!</h1>
  }
  return (
    <form onSubmit={(e) => {
      e.preventDefault();
      setIsSent(true);
      sendMessage(message);
    }}>
      <textarea
        placeholder="Message"
        value={message}
        onChange={e => setMessage(e.target.value)}
      />
      <button type="submit">Send</button>
    </form>
  );
}

function sendMessage(message) {
  // ...
}
```

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function Counter() {
  const [number, setNumber] = useState(0);

  return (
    <>
      <h1>{number}</h1>
      <button onClick={() => {
        setNumber(number + 1);
        setNumber(number + 1);
        setNumber(number + 1);
      }}>+3</button>
    </>
  )
}
```

Notice that `number` only increments once per click!

**Setting state only changes it for the *next* render.** During the first render, `number` was `0`. This is why, in *that render’s* `onClick` handler, the value of `number` is still `0` even after `setNumber(number + 1)` was called:

```
<button onClick={() => {

  setNumber(number + 1);

  setNumber(number + 1);

  setNumber(number + 1);

}}>+3</button>
```

```
<button onClick={() => {

  setNumber(0 + 1);

  setNumber(0 + 1);

  setNumber(0 + 1);

}}>+3</button>
```

For the next render, `number` is `1`, so *that render’s* click handler looks like this:

```
<button onClick={() => {

  setNumber(1 + 1);

  setNumber(1 + 1);

  setNumber(1 + 1);

}}>+3</button>
```

This is why clicking the button again will set the counter to `2`, then to `3` on the next click, and so on.

## State over time[](#state-over-time "Link for State over time ")

Well, that was fun. Try to guess what clicking this button will alert:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function Counter() {
  const [number, setNumber] = useState(0);

  return (
    <>
      <h1>{number}</h1>
      <button onClick={() => {
        setNumber(number + 5);
        alert(number);
      }}>+5</button>
    </>
  )
}
```

If you use the substitution method from before, you can guess that the alert shows “0”:

```
setNumber(0 + 5);

alert(0);
```

But what if you put a timer on the alert, so it only fires *after* the component re-rendered? Would it say “0” or “5”? Have a guess!

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function Counter() {
  const [number, setNumber] = useState(0);

  return (
    <>
      <h1>{number}</h1>
      <button onClick={() => {
        setNumber(number + 5);
        setTimeout(() => {
          alert(number);
        }, 3000);
      }}>+5</button>
    </>
  )
}
```

Surprised? If you use the substitution method, you can see the “snapshot” of the state passed to the alert.

```
setNumber(0 + 5);

setTimeout(() => {

  alert(0);

}, 3000);
```

The state stored in React may have changed by the time the alert runs, but it was scheduled using a snapshot of the state at the time the user interacted with it!

**A state variable’s value never changes within a render,** even if its event handler’s code is asynchronous. Inside *that render’s* `onClick`, the value of `number` continues to be `0` even after `setNumber(number + 5)` was called. Its value was “fixed” when React “took the snapshot” of the UI by calling your component.

Here is an example of how that makes your event handlers less prone to timing mistakes. Below is a form that sends a message with a five-second delay. Imagine this scenario:

1. You press the “Send” button, sending “Hello” to Alice.
2. Before the five-second delay ends, you change the value of the “To” field to “Bob”.

What do you expect the `alert` to display? Would it display, “You said Hello to Alice”? Or would it display, “You said Hello to Bob”? Make a guess based on what you know, and then try it:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function Form() {
  const [to, setTo] = useState('Alice');
  const [message, setMessage] = useState('Hello');

  function handleSubmit(e) {
    e.preventDefault();
    setTimeout(() => {
      alert(`You said ${message} to ${to}`);
    }, 5000);
  }

  return (
    <form onSubmit={handleSubmit}>
      <label>
        To:{' '}
        <select
          value={to}
          onChange={e => setTo(e.target.value)}>
          <option value="Alice">Alice</option>
          <option value="Bob">Bob</option>
        </select>
      </label>
      <textarea
        placeholder="Message"
        value={message}
        onChange={e => setMessage(e.target.value)}
      />
      <button type="submit">Send</button>
    </form>
  );
}
```

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function TrafficLight() {
  const [walk, setWalk] = useState(true);

  function handleClick() {
    setWalk(!walk);
  }

  return (
    <>
      <button onClick={handleClick}>
        Change to {walk ? 'Stop' : 'Walk'}
      </button>
      <h1 style={{
        color: walk ? 'darkgreen' : 'darkred'
      }}>
        {walk ? 'Walk' : 'Stop'}
      </h1>
    </>
  );
}
```

Add an `alert` to the click handler. When the light is green and says “Walk”, clicking the button should say “Stop is next”. When the light is red and says “Stop”, clicking the button should say “Walk is next”.

Does it make a difference whether you put the `alert` before or after the `setWalk` call?

[PreviousRender and Commit](/learn/render-and-commit)

[NextQueueing a Series of State Updates](/learn/queueing-a-series-of-state-updates)

***

----
url: https://react.dev/reference/react/PureComponent
----

[API Reference](/reference/react)

[Legacy React APIs](/reference/react/legacy)

# PureComponent[](#undefined "Link for this heading")

### Pitfall

We recommend defining components as functions instead of classes. [See how to migrate.](#alternatives)

`PureComponent` is similar to [`Component`](/reference/react/Component) but it skips re-renders for same props and state. Class components are still supported by React, but we don’t recommend using them in new code.

```
class Greeting extends PureComponent {

  render() {

    return <h1>Hello, {this.props.name}!</h1>;

  }

}
```

* [Reference](#reference)
  * [`PureComponent`](#purecomponent)
* [Usage](#usage)
  * [Skipping unnecessary re-renders for class components](#skipping-unnecessary-re-renders-for-class-components)
* [Alternatives](#alternatives)
  * [Migrating from a `PureComponent` class component to a function](#migrating-from-a-purecomponent-class-component-to-a-function)

***

## Reference[](#reference "Link for Reference ")

### `PureComponent`[](#purecomponent "Link for this heading")

To skip re-rendering a class component for same props and state, extend `PureComponent` instead of [`Component`:](/reference/react/Component)

```
import { PureComponent } from 'react';



class Greeting extends PureComponent {

  render() {

    return <h1>Hello, {this.props.name}!</h1>;

  }

}
```

`PureComponent` is a subclass of `Component` and supports [all the `Component` APIs.](/reference/react/Component#reference) Extending `PureComponent` is equivalent to defining a custom [`shouldComponentUpdate`](/reference/react/Component#shouldcomponentupdate) method that shallowly compares props and state.

[See more examples below.](#usage)

***

## Usage[](#usage "Link for Usage ")

### Skipping unnecessary re-renders for class components[](#skipping-unnecessary-re-renders-for-class-components "Link for Skipping unnecessary re-renders for class components ")

React normally re-renders a component whenever its parent re-renders. As an optimization, you can create a component that React will not re-render when its parent re-renders so long as its new props and state are the same as the old props and state. [Class components](/reference/react/Component) can opt into this behavior by extending `PureComponent`:

```
class Greeting extends PureComponent {

  render() {

    return <h1>Hello, {this.props.name}!</h1>;

  }

}
```

A React component should always have [pure rendering logic.](/learn/keeping-components-pure) This means that it must return the same output if its props, state, and context haven’t changed. By using `PureComponent`, you are telling React that your component complies with this requirement, so React doesn’t need to re-render as long as its props and state haven’t changed. However, your component will still re-render if a context that it’s using changes.

In this example, notice that the `Greeting` component re-renders whenever `name` is changed (because that’s one of its props), but not when `address` is changed (because it’s not passed to `Greeting` as a prop):

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { PureComponent, useState } from 'react';

class Greeting extends PureComponent {
  render() {
    console.log("Greeting was rendered at", new Date().toLocaleTimeString());
    return <h3>Hello{this.props.name && ', '}{this.props.name}!</h3>;
  }
}

export default function MyApp() {
  const [name, setName] = useState('');
  const [address, setAddress] = useState('');
  return (
    <>
      <label>
        Name{': '}
        <input value={name} onChange={e => setName(e.target.value)} />
      </label>
      <label>
        Address{': '}
        <input value={address} onChange={e => setAddress(e.target.value)} />
      </label>
      <Greeting name={name} />
    </>
  );
}
```

### Pitfall

We recommend defining components as functions instead of classes. [See how to migrate.](#alternatives)

***

## Alternatives[](#alternatives "Link for Alternatives ")

### Migrating from a `PureComponent` class component to a function[](#migrating-from-a-purecomponent-class-component-to-a-function "Link for this heading")

We recommend using function components instead of [class components](/reference/react/Component) in new code. If you have some existing class components using `PureComponent`, here is how you can convert them. This is the original code:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { PureComponent, useState } from 'react';

class Greeting extends PureComponent {
  render() {
    console.log("Greeting was rendered at", new Date().toLocaleTimeString());
    return <h3>Hello{this.props.name && ', '}{this.props.name}!</h3>;
  }
}

export default function MyApp() {
  const [name, setName] = useState('');
  const [address, setAddress] = useState('');
  return (
    <>
      <label>
        Name{': '}
        <input value={name} onChange={e => setName(e.target.value)} />
      </label>
      <label>
        Address{': '}
        <input value={address} onChange={e => setAddress(e.target.value)} />
      </label>
      <Greeting name={name} />
    </>
  );
}
```

When you [convert this component from a class to a function,](/reference/react/Component#alternatives) wrap it in [`memo`:](/reference/react/memo)

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { memo, useState } from 'react';

const Greeting = memo(function Greeting({ name }) {
  console.log("Greeting was rendered at", new Date().toLocaleTimeString());
  return <h3>Hello{name && ', '}{name}!</h3>;
});

export default function MyApp() {
  const [name, setName] = useState('');
  const [address, setAddress] = useState('');
  return (
    <>
      <label>
        Name{': '}
        <input value={name} onChange={e => setName(e.target.value)} />
      </label>
      <label>
        Address{': '}
        <input value={address} onChange={e => setAddress(e.target.value)} />
      </label>
      <Greeting name={name} />
    </>
  );
}
```

### Note

Unlike `PureComponent`, [`memo`](/reference/react/memo) does not compare the new and the old state. In function components, calling the [`set` function](/reference/react/useState#setstate) with the same state [already prevents re-renders by default,](/reference/react/memo#updating-a-memoized-component-using-state) even without `memo`.

[PreviousisValidElement](/reference/react/isValidElement)

***

----
url: https://react.dev/reference/react-dom/findDOMNode
----

[API Reference](/reference/react)

[APIs](/reference/react-dom)

# findDOMNode[](#undefined "Link for this heading")

### Deprecated

This API will be removed in a future major version of React. [See the alternatives.](#alternatives)

`findDOMNode` finds the browser DOM node for a React [class component](/reference/react/Component) instance.

```
const domNode = findDOMNode(componentInstance)
```

***

## Reference[](#reference "Link for Reference ")

### `findDOMNode(componentInstance)`[](#finddomnode "Link for this heading")

Call `findDOMNode` to find the browser DOM node for a given React [class component](/reference/react/Component) instance.

```
import { findDOMNode } from 'react-dom';



const domNode = findDOMNode(componentInstance);
```

***

## Usage[](#usage "Link for Usage ")

### Finding the root DOM node of a class component[](#finding-the-root-dom-node-of-a-class-component "Link for Finding the root DOM node of a class component ")

Call `findDOMNode` with a [class component](/reference/react/Component) instance (usually, `this`) to find the DOM node it has rendered.

```
class AutoselectingInput extends Component {

  componentDidMount() {

    const input = findDOMNode(this);

    input.select()

  }



  render() {

    return <input defaultValue="Hello" />

  }

}
```

Here, the `input` variable will be set to the `<input>` DOM element. This lets you do something with it. For example, when clicking “Show example” below mounts the input, [`input.select()`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/select) selects all text in the input:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { Component } from 'react';
import { findDOMNode } from 'react-dom';

class AutoselectingInput extends Component {
  componentDidMount() {
    const input = findDOMNode(this);
    input.select()
  }

  render() {
    return <input defaultValue="Hello" />
  }
}

export default AutoselectingInput;
```

***

## Alternatives[](#alternatives "Link for Alternatives ")

### Reading component’s own DOM node from a ref[](#reading-components-own-dom-node-from-a-ref "Link for Reading component’s own DOM node from a ref ")

Code using `findDOMNode` is fragile because the connection between the JSX node and the code manipulating the corresponding DOM node is not explicit. For example, try wrapping this `<input />` into a `<div>`:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { Component } from 'react';
import { findDOMNode } from 'react-dom';

class AutoselectingInput extends Component {
  componentDidMount() {
    const input = findDOMNode(this);
    input.select()
  }
  render() {
    return <input defaultValue="Hello" />
  }
}

export default AutoselectingInput;
```

This will break the code because now, `findDOMNode(this)` finds the `<div>` DOM node, but the code expects an `<input>` DOM node. To avoid these kinds of problems, use [`createRef`](/reference/react/createRef) to manage a specific DOM node.

In this example, `findDOMNode` is no longer used. Instead, `inputRef = createRef(null)` is defined as an instance field on the class. To read the DOM node from it, you can use `this.inputRef.current`. To attach it to the JSX, you render `<input ref={this.inputRef} />`. This connects the code using the DOM node to its JSX:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { createRef, Component } from 'react';

class AutoselectingInput extends Component {
  inputRef = createRef(null);

  componentDidMount() {
    const input = this.inputRef.current;
    input.select()
  }

  render() {
    return (
      <input ref={this.inputRef} defaultValue="Hello" />
    );
  }
}

export default AutoselectingInput;
```

In modern React without class components, the equivalent code would call [`useRef`](/reference/react/useRef) instead:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useRef, useEffect } from 'react';

export default function AutoselectingInput() {
  const inputRef = useRef(null);

  useEffect(() => {
    const input = inputRef.current;
    input.select();
  }, []);

  return <input ref={inputRef} defaultValue="Hello" />
}
```

[Read more about manipulating the DOM with refs.](/learn/manipulating-the-dom-with-refs)

***

### Reading a child component’s DOM node from a forwarded ref[](#reading-a-child-components-dom-node-from-a-forwarded-ref "Link for Reading a child component’s DOM node from a forwarded ref ")

In this example, `findDOMNode(this)` finds a DOM node that belongs to another component. The `AutoselectingInput` renders `MyInput`, which is your own component that renders a browser `<input>`.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { Component } from 'react';
import { findDOMNode } from 'react-dom';
import MyInput from './MyInput.js';

class AutoselectingInput extends Component {
  componentDidMount() {
    const input = findDOMNode(this);
    input.select()
  }
  render() {
    return <MyInput />;
  }
}

export default AutoselectingInput;
```

Notice that calling `findDOMNode(this)` inside `AutoselectingInput` still gives you the DOM `<input>`—even though the JSX for this `<input>` is hidden inside the `MyInput` component. This seems convenient for the above example, but it leads to fragile code. Imagine that you wanted to edit `MyInput` later and add a wrapper `<div>` around it. This would break the code of `AutoselectingInput` (which expects to find an `<input>`).

To replace `findDOMNode` in this example, the two components need to coordinate:

1. `AutoSelectingInput` should declare a ref, like [in the earlier example](#reading-components-own-dom-node-from-a-ref), and pass it to `<MyInput>`.
2. `MyInput` should be declared with [`forwardRef`](/reference/react/forwardRef) to take that ref and forward it down to the `<input>` node.

This version does that, so it no longer needs `findDOMNode`:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { createRef, Component } from 'react';
import MyInput from './MyInput.js';

class AutoselectingInput extends Component {
  inputRef = createRef(null);

  componentDidMount() {
    const input = this.inputRef.current;
    input.select()
  }

  render() {
    return (
      <MyInput ref={this.inputRef} />
    );
  }
}

export default AutoselectingInput;
```

Here is how this code would look like with function components instead of classes:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useRef, useEffect } from 'react';
import MyInput from './MyInput.js';

export default function AutoselectingInput() {
  const inputRef = useRef(null);

  useEffect(() => {
    const input = inputRef.current;
    input.select();
  }, []);

  return <MyInput ref={inputRef} defaultValue="Hello" />
}
```

***

### Adding a wrapper `<div>` element[](#adding-a-wrapper-div-element "Link for this heading")

Sometimes a component needs to know the position and size of its children. This makes it tempting to find the children with `findDOMNode(this)`, and then use DOM methods like [`getBoundingClientRect`](https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect) for measurements.

There is currently no direct equivalent for this use case, which is why `findDOMNode` is deprecated but is not yet removed completely from React. In the meantime, you can try rendering a wrapper `<div>` node around the content as a workaround, and getting a ref to that node. However, extra wrappers can break styling.

```
<div ref={someRef}>

  {children}

</div>
```

This also applies to focusing and scrolling to arbitrary children.

[PreviousflushSync](/reference/react-dom/flushSync)

[Nexthydrate](/reference/react-dom/hydrate)

***

----
url: https://legacy.reactjs.org/blog/2019/08/08/react-v16.9.0.html
----

August 08, 2019 by [Dan Abramov](https://twitter.com/dan_abramov) and [Brian Vaughn](https://github.com/bvaughn)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

Today we are releasing React 16.9. It contains several new features, bugfixes, and new deprecation warnings to help prepare for a future major release.

## [](#new-deprecations)New Deprecations

### [](#renaming-unsafe-lifecycle-methods)Renaming Unsafe Lifecycle Methods

[Over a year ago](/blog/2018/03/27/update-on-async-rendering.html), we announced that unsafe lifecycle methods are getting renamed:

* `componentWillMount` → `UNSAFE_componentWillMount`
* `componentWillReceiveProps` → `UNSAFE_componentWillReceiveProps`
* `componentWillUpdate` → `UNSAFE_componentWillUpdate`

**React 16.9 does not contain breaking changes, and the old names continue to work in this release.** But you will now see a warning when using any of the old names:

As the warning suggests, there are usually [better approaches](/blog/2018/03/27/update-on-async-rendering.html#migrating-from-legacy-lifecycles) for each of the unsafe methods. However, maybe you don’t have the time to migrate or test these components. In that case, we recommend running a [“codemod”](https://medium.com/@cpojer/effective-javascript-codemods-5a6686bb46fb) script that renames them automatically:

```
cd your_project
npx react-codemod rename-unsafe-lifecycles
```

*(Note that it says `npx`, not `npm`. `npx` is a utility that comes with Node 6+ by default.)*

Running this codemod will replace the old names like `componentWillMount` with the new names like `UNSAFE_componentWillMount`:

The new names like `UNSAFE_componentWillMount` **will keep working in both React 16.9 and in React 17.x**. However, the new `UNSAFE_` prefix will help components with problematic patterns stand out during the code review and debugging sessions. (If you’d like, you can further discourage their use inside your app with the opt-in [Strict Mode](/docs/strict-mode.html).)

> Note
>
> Learn more about our [versioning policy and commitment to stability](/docs/faq-versioning.html#commitment-to-stability).

### [](#deprecating-javascript-urls)Deprecating `javascript:` URLs

URLs starting with `javascript:` are a dangerous attack surface because it’s easy to accidentally include unsanitized output in a tag like `<a href>` and create a security hole:

```
const userProfile = {
  website: "javascript: alert('you got hacked')",
};
// This will now warn:
<a href={userProfile.website}>Profile</a>
```

**In React 16.9,** this pattern continues to work, but it will log a warning. If you use `javascript:` URLs for logic, try to use React event handlers instead. (As a last resort, you can circumvent the protection with [`dangerouslySetInnerHTML`](/docs/dom-elements.html#dangerouslysetinnerhtml), but it is highly discouraged and often leads to security holes.)

**In a future major release,** React will throw an error if it encounters a `javascript:` URL.

### [](#deprecating-factory-components)Deprecating “Factory” Components

Before compiling JavaScript classes with Babel became popular, React had support for a “factory” component that returns an object with a `render` method:

```
function FactoryComponent() {
  return { render() { return <div />; } }
}
```

This pattern is confusing because it looks too much like a function component — but it isn’t one. (A function component would just return the `<div />` in the above example.)

This pattern was almost never used in the wild, and supporting it causes React to be slightly larger and slower than necessary. So we are deprecating this pattern in 16.9 and logging a warning if it’s encountered. If you rely on it, adding `FactoryComponent.prototype = React.Component.prototype` can serve as a workaround. Alternatively, you can convert it to either a class or a function component.

We don’t expect most codebases to be affected by this.

## [](#new-features)New Features

### [](#async-act-for-testing)Async [`act()`](/docs/test-utils.html#act) for Testing

[React 16.8](/blog/2019/02/06/react-v16.8.0.html) introduced a new testing utility called [`act()`](/docs/test-utils.html#act) to help you write tests that better match the browser behavior. For example, multiple state updates inside a single `act()` get batched. This matches how React already works when handling real browser events, and helps prepare your components for the future in which React will batch updates more often.

However, in 16.8 `act()` only supported synchronous functions. Sometimes, you might have seen a warning like this in a test but [could not easily fix it](https://github.com/facebook/react/issues/14769):

```
An update to SomeComponent inside a test was not wrapped in act(...).
```

**In React 16.9, `act()` also accepts asynchronous functions,** and you can `await` its call:

```
await act(async () => {
  // ...
});
```

This solves the remaining cases where you couldn’t use `act()` before, such as when the state update was inside an asynchronous function. As a result, **you should be able to fix all the remaining `act()` warnings in your tests now.**

We’ve heard there wasn’t enough information about how to write tests with `act()`. The new [Testing Recipes](/docs/testing-recipes.html) guide describes common scenarios, and how `act()` can help you write good tests. These examples use vanilla DOM APIs, but you can also use [React Testing Library](https://testing-library.com/docs/react-testing-library/intro) to reduce the boilerplate code. Many of its methods already use `act()` internally.

Please let us know [on the issue tracker](https://github.com/facebook/react/issues) if you bump into any other scenarios where `act()` doesn’t work well for you, and we’ll try to help.

### [](#performance-measurements-with-reactprofiler)Performance Measurements with [`<React.Profiler>`](/docs/profiler.html)

In React 16.5, we introduced a new [React Profiler for DevTools](/blog/2018/09/10/introducing-the-react-profiler.html) that helps find performance bottlenecks in your application. **In React 16.9, we are also adding a *programmatic* way to gather measurements** called `<React.Profiler>`. We expect that most smaller apps won’t use it, but it can be handy to track performance regressions over time in larger apps.

The `<Profiler>` measures how often a React application renders and what the “cost” of rendering is. Its purpose is to help identify parts of an application that are slow and may benefit from [optimizations such as memoization](/docs/hooks-faq.html#how-to-memoize-calculations).

A `<Profiler>` can be added anywhere in a React tree to measure the cost of rendering that part of the tree. It requires two props: an `id` (string) and an [`onRender` callback](/docs/profiler.html#onrender-callback) (function) which React calls any time a component within the tree “commits” an update.

```
render(
  <Profiler id="application" onRender={onRenderCallback}>    <App>
      <Navigation {...props} />
      <Main {...props} />
    </App>
  </Profiler>);
```

To learn more about the `Profiler` and the parameters passed to the `onRender` callback, check out [the `Profiler` docs](/docs/profiler.html).

> Note:
>
> Profiling adds some additional overhead, so **it is disabled in [the production build](https://reactjs.org/docs/optimizing-performance.html#use-the-production-build)**.
>
> To opt into production profiling, React provides a special production build with profiling enabled. Read more about how to use this build at [fb.me/react-profiling](https://fb.me/react-profiling).

## [](#notable-bugfixes)Notable Bugfixes

This release contains a few other notable improvements:

* A crash when calling `findDOMNode()` inside a `<Suspense>` tree [has been fixed](https://github.com/facebook/react/pull/15312).
* A memory leak caused by retaining deleted subtrees [has been fixed](https://github.com/facebook/react/pull/16115) too.
* An infinite loop caused by `setState` in `useEffect` now [logs an error](https://github.com/facebook/react/pull/15180). (This is similar to the error you see when you call `setState` in `componentDidUpdate` in a class.)

We’re thankful to all the contributors who helped surface and fix these and other issues. You can find the full changelog [below](#changelog).

## [](#an-update-to-the-roadmap)An Update to the Roadmap

In [November 2018](/blog/2018/11/27/react-16-roadmap.html), we have posted this roadmap for the 16.x releases:

* A minor 16.x release with React Hooks (past estimate: Q1 2019)
* A minor 16.x release with Concurrent Mode (past estimate: Q2 2019)
* A minor 16.x release with Suspense for Data Fetching (past estimate: mid 2019)

These estimates were too optimistic, and we’ve needed to adjust them.

**tldr:** We shipped Hooks on time, but we’re regrouping Concurrent Mode and Suspense for Data Fetching into a single release that we intend to release later this year.

In February, we [shipped a stable 16.8 release](/blog/2019/02/06/react-v16.8.0.html) including React Hooks, with React Native support coming [a month later](https://reactnative.dev/blog/2019/03/12/releasing-react-native-059). However, we underestimated the follow-up work for this release, including the lint rules, developer tools, examples, and more documentation. This shifted the timeline by a few months.

Now that React Hooks are rolled out, the work on Concurrent Mode and Suspense for Data Fetching is in full swing. The [new Facebook website that’s currently in active development](https://twitter.com/facebook/status/1123322299418124289) is built on top of these features. Testing them with real code helped discover and address many issues before they can affect the open source users. Some of these fixes involved an internal redesign of these features, which has also caused the timeline to slip.

With this new understanding, here’s what we plan to do next.

### [](#one-release-instead-of-two)One Release Instead of Two

Concurrent Mode and Suspense [power the new Facebook website](https://developers.facebook.com/videos/2019/building-the-new-facebookcom-with-react-graphql-and-relay/) that’s in active development, so we are confident that they’re close to a stable state technically. We also now better understand the concrete steps before they are ready for open source adoption.

Originally we thought we would split Concurrent Mode and Suspense for Data Fetching into two releases. We’ve found that this sequencing is confusing to explain because these features are more related than we thought at first. So we plan to release support for both Concurrent Mode and Suspense for Data Fetching in a single combined release instead.

We don’t want to overpromise the release date again. Given that we rely on both of them in production code, we expect to provide a 16.x release with opt-in support for them this year.

### [](#an-update-on-data-fetching)An Update on Data Fetching

While React is not opinionated about how you fetch data, the first release of Suspense for Data Fetching will likely focus on integrating with *opinionated data fetching libraries*. For example, at Facebook we are using upcoming Relay APIs that integrate with Suspense. We will document how other opinionated libraries like Apollo can support a similar integration.

In the first release, we *don’t* intend to focus on the ad-hoc “fire an HTTP request” solution we used in earlier demos (also known as “React Cache”). However, we expect that both we and the React community will be exploring that space in the months after the initial release.

### [](#an-update-on-server-rendering)An Update on Server Rendering

We have started the work on the [new Suspense-capable server renderer](/blog/2018/11/27/react-16-roadmap.html#suspense-for-server-rendering), but we *don’t* expect it to be ready for the initial release of Concurrent Mode. This release will, however, provide a temporary solution that lets the existing server renderer emit HTML for Suspense fallbacks immediately, and then render their real content on the client. This is the solution we are currently using at Facebook ourselves until the streaming renderer is ready.

### [](#why-is-it-taking-so-long)Why Is It Taking So Long?

We’ve shipped the individual pieces leading up to Concurrent Mode as they became stable, including [new context API](/blog/2018/03/29/react-v-16-3.html), [lazy loading with Suspense](/blog/2018/10/23/react-v-16-6.html), and [Hooks](/blog/2019/02/06/react-v16.8.0.html). We are also eager to release the other missing parts, but [trying them at scale](/docs/design-principles.html#dogfooding) is an important part of the process. The honest answer is that it just took more work than we expected when we started. As always, we appreciate your questions and feedback on [Twitter](https://twitter.com/reactjs) and in our [issue tracker](https://github.com/facebook/react/issues).

## [](#installation)Installation

### [](#react)React

React v16.9.0 is available on the npm registry.

To install React 16 with Yarn, run:

```
yarn add react@^16.9.0 react-dom@^16.9.0
```

To install React 16 with npm, run:

```
npm install --save react@^16.9.0 react-dom@^16.9.0
```

We also provide UMD builds of React via a CDN:

```
<script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
```

Refer to the documentation for [detailed installation instructions](/docs/installation.html).

## [](#changelog)Changelog

### [](#react)React

* Add `<React.Profiler>` API for gathering performance measurements programmatically. ([@bvaughn](https://github.com/bvaughn) in [#15172](https://github.com/facebook/react/pull/15172))
* Remove `unstable_ConcurrentMode` in favor of `unstable_createRoot`. ([@acdlite](https://github.com/acdlite) in [#15532](https://github.com/facebook/react/pull/15532))

### [](#react-dom)React DOM

* Deprecate old names for the `UNSAFE_*` lifecycle methods. ([@bvaughn](https://github.com/bvaughn) in [#15186](https://github.com/facebook/react/pull/15186) and [@threepointone](https://github.com/threepointone) in [#16103](https://github.com/facebook/react/pull/16103))
* Deprecate `javascript:` URLs as a common attack surface. ([@sebmarkbage](https://github.com/sebmarkbage) in [#15047](https://github.com/facebook/react/pull/15047))
* Deprecate uncommon “module pattern” (factory) components. ([@sebmarkbage](https://github.com/sebmarkbage) in [#15145](https://github.com/facebook/react/pull/15145))
* Add support for the `disablePictureInPicture` attribute on `<video>`. ([@eek](https://github.com/eek) in [#15334](https://github.com/facebook/react/pull/15334))
* Add support for `onLoad` event for `<embed>`. ([@cherniavskii](https://github.com/cherniavskii) in [#15614](https://github.com/facebook/react/pull/15614))
* Add support for editing `useState` state from DevTools. ([@bvaughn](https://github.com/bvaughn) in [#14906](https://github.com/facebook/react/pull/14906))
* Add support for toggling Suspense from DevTools. ([@gaearon](https://github.com/gaearon) in [#15232](https://github.com/facebook/react/pull/15232))
* Warn when `setState` is called from `useEffect`, creating a loop. ([@gaearon](https://github.com/gaearon) in [#15180](https://github.com/facebook/react/pull/15180))
* Fix a memory leak. ([@paulshen](https://github.com/paulshen) in [#16115](https://github.com/facebook/react/pull/16115))
* Fix a crash inside `findDOMNode` for components wrapped in `<Suspense>`. ([@acdlite](https://github.com/acdlite) in [#15312](https://github.com/facebook/react/pull/15312))
* Fix pending effects from being flushed too late. ([@acdlite](https://github.com/acdlite) in [#15650](https://github.com/facebook/react/pull/15650))
* Fix incorrect argument order in a warning message. ([@brickspert](https://github.com/brickspert) in [#15345](https://github.com/facebook/react/pull/15345))
* Fix hiding Suspense fallback nodes when there is an `!important` style. ([@acdlite](https://github.com/acdlite) in [#15861](https://github.com/facebook/react/pull/15861) and [#15882](https://github.com/facebook/react/pull/15882))
* Slightly improve hydration performance. ([@bmeurer](https://github.com/bmeurer) in [#15998](https://github.com/facebook/react/pull/15998))

### [](#react-dom-server)React DOM Server

* Fix incorrect output for camelCase custom CSS property names. ([@bedakb](https://github.com/bedakb) in [#16167](https://github.com/facebook/react/pull/16167))

### [](#react-test-utilities-and-test-renderer)React Test Utilities and Test Renderer

* Add `act(async () => ...)` for testing asynchronous state updates. ([@threepointone](https://github.com/threepointone) in [#14853](https://github.com/facebook/react/pull/14853))
* Add support for nesting `act` from different renderers. ([@threepointone](https://github.com/threepointone) in [#16039](https://github.com/facebook/react/pull/16039) and [#16042](https://github.com/facebook/react/pull/16042))
* Warn in Strict Mode if effects are scheduled outside an `act()` call. ([@threepointone](https://github.com/threepointone) in [#15763](https://github.com/facebook/react/pull/15763) and [#16041](https://github.com/facebook/react/pull/16041))
* Warn when using `act` from the wrong renderer. ([@threepointone](https://github.com/threepointone) in [#15756](https://github.com/facebook/react/pull/15756))

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2019-08-08-react-v16.9.0.md)

----
url: https://react.dev/reference/react/useEffectEvent
----

[API Reference](/reference/react)

[Hooks](/reference/react/hooks)

# useEffectEvent[](#undefined "Link for this heading")

`useEffectEvent` is a React Hook that lets you separate events from Effects.

```
const onEvent = useEffectEvent(callback)
```

* [Reference](#reference)
  * [`useEffectEvent(callback)`](#useeffectevent)

* [Usage](#usage)

  * [Using an event in an Effect](#using-an-event-in-an-effect)
  * [Using a timer with latest values](#using-a-timer-with-latest-values)
  * [Using an event listener with latest values](#using-an-event-listener-with-latest-values)
  * [Avoid reconnecting to external systems](#showing-a-notification-without-reconnecting)
  * [Using Effect Events in custom Hooks](#using-effect-events-in-custom-hooks)

* [Troubleshooting](#troubleshooting)

  * [I’m getting an error: “A function wrapped in useEffectEvent can’t be called during rendering”](#cant-call-during-rendering)
  * [I’m getting a lint error: “Functions returned from useEffectEvent must not be included in the dependency array”](#effect-event-in-deps)
  * [I’m getting a lint error: ”… is a function created with useEffectEvent, and can only be called from Effects”](#effect-event-called-outside-effect)

***

## Reference[](#reference "Link for Reference ")

### `useEffectEvent(callback)`[](#useeffectevent "Link for this heading")

Call `useEffectEvent` at the top level of your component to create an Effect Event.

```
import { useEffectEvent, useEffect } from 'react';



function ChatRoom({ roomId, theme }) {

  const onConnected = useEffectEvent(() => {

    showNotification('Connected!', theme);

  });

}
```

Effect Events are a part of your Effect logic, but they behave more like an event handler. They always “see” the latest values from render (like props and state) without re-synchronizing your Effect, so they’re excluded from Effect dependencies. See [Separating Events from Effects](/learn/separating-events-from-effects#extracting-non-reactive-logic-out-of-effects) to learn more.

[See more examples below.](#usage)

#### Parameters[](#parameters "Link for Parameters ")

* `callback`: A function containing the logic for your Effect Event. The function can accept any number of arguments and return any value. When you call the returned Effect Event function, the `callback` always accesses the latest committed values from render at the time of the call.

#### Returns[](#returns "Link for Returns ")

`useEffectEvent` returns an Effect Event function with the same type signature as your `callback`.

You can call this function inside `useEffect`, `useLayoutEffect`, `useInsertionEffect`, or from within other Effect Events in the same component.

#### Caveats[](#caveats "Link for Caveats ")

* `useEffectEvent` is a Hook, so you can only call it **at the top level of your component** or your own Hooks. You can’t call it inside loops or conditions. If you need that, extract a new component and move the Effect Event into it.
* Effect Events can only be called from inside Effects or other Effect Events. Do not call them during rendering or pass them to other components or Hooks. The [`eslint-plugin-react-hooks`](/reference/eslint-plugin-react-hooks) linter enforces this restriction.
* Do not use `useEffectEvent` to avoid specifying dependencies in your Effect’s dependency array. This hides bugs and makes your code harder to understand. Only use it for logic that is genuinely an event fired from Effects.
* Effect Event functions do not have a stable identity. Their identity intentionally changes on every render.

##### Deep Dive#### Why are Effect Events not stable?[](#why-are-effect-events-not-stable "Link for Why are Effect Events not stable? ")

Unlike `set` functions from `useState` or refs, Effect Event functions do not have a stable identity. Their identity intentionally changes on every render:

```
// 🔴 Wrong: including Effect Event in dependencies

useEffect(() => {

  onSomething();

}, [onSomething]); // ESLint will warn about this
```

This is a deliberate design choice. Effect Events are meant to be called only from within Effects in the same component. Since you can only call them locally and cannot pass them to other components or include them in dependency arrays, a stable identity would serve no purpose, and would actually mask bugs.

The non-stable identity acts as a runtime assertion: if your code incorrectly depends on the function identity, you’ll see the Effect re-running on every render, making the bug obvious.

This design reinforces that Effect Events conceptually belong to a particular effect, and are not a general purpose API to opt-out of reactivity.

***

## Usage[](#usage "Link for Usage ")

### Using an event in an Effect[](#using-an-event-in-an-effect "Link for Using an event in an Effect ")

Call `useEffectEvent` at the top level of your component to create an *Effect Event*:

```
const onConnected = useEffectEvent(() => {

  if (!muted) {

    showNotification('Connected!');

  }

});
```

`useEffectEvent` accepts an `event callback` and returns an Effect Event. The Effect Event is a function that can be called inside of Effects without re-connecting the Effect:

```
useEffect(() => {

  const connection = createConnection(roomId);

  connection.on('connected', onConnected);

  connection.connect();

  return () => {

    connection.disconnect();

  }

}, [roomId]);
```

Since `onConnected` is an Effect Event, `muted` and `onConnect` are not in the Effect dependencies.

### Pitfall

##### Don’t use Effect Events to skip dependencies[](#pitfall-skip-dependencies "Link for Don’t use Effect Events to skip dependencies ")

It might be tempting to use `useEffectEvent` to avoid listing dependencies that you think are “unnecessary.” However, this hides bugs and makes your code harder to understand:

```
// 🔴 Wrong: Using Effect Events to hide dependencies

const logVisit = useEffectEvent(() => {

  log(pageUrl);

});



useEffect(() => {

  logVisit()

}, []); // Missing pageUrl means you miss logs
```

If a value should cause your Effect to re-run, keep it as a dependency. Only use Effect Events for logic that genuinely should not re-trigger your Effect.

See [Separating Events from Effects](/learn/separating-events-from-effects) to learn more.

***

### Using a timer with latest values[](#using-a-timer-with-latest-values "Link for Using a timer with latest values ")

When you use `setInterval` or `setTimeout` in an Effect, you often want to read the latest values from render without restarting the timer whenever those values change.

This counter increments `count` by the current `increment` value every second. The `onTick` Effect Event reads the latest `count` and `increment` without causing the interval to restart:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useEffect, useEffectEvent } from 'react';

export default function Timer() {
  const [count, setCount] = useState(0);
  const [increment, setIncrement] = useState(1);

  const onTick = useEffectEvent(() => {
    setCount(count + increment);
  });

  useEffect(() => {
    const id = setInterval(() => {
      onTick();
    }, 1000);
    return () => {
      clearInterval(id);
    };
  }, []);

  return (
    <>
      <h1>
        Counter: {count}
        <button onClick={() => setCount(0)}>Reset</button>
      </h1>
      <hr />
      <p>
        Every second, increment by:
        <button disabled={increment === 0} onClick={() => {
          setIncrement(i => i - 1);
        }}>–</button>
        <b>{increment}</b>
        <button onClick={() => {
          setIncrement(i => i + 1);
        }}>+</button>
      </p>
    </>
  );
}
```

Try changing the increment value while the timer is running. The counter immediately uses the new increment value, but the timer keeps ticking smoothly without restarting.

***

### Using an event listener with latest values[](#using-an-event-listener-with-latest-values "Link for Using an event listener with latest values ")

When you set up an event listener in an Effect, you often need to read the latest values from render in the callback. Without `useEffectEvent`, you would need to include the values in your dependencies, causing the listener to be removed and re-added on every change.

This example shows a dot that follows the cursor, but only when “Can move” is checked. The `onMove` Effect Event always reads the latest `canMove` value without re-running the Effect:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useEffect, useEffectEvent } from 'react';

export default function App() {
  const [position, setPosition] = useState({ x: 0, y: 0 });
  const [canMove, setCanMove] = useState(true);

  const onMove = useEffectEvent(e => {
    if (canMove) {
      setPosition({ x: e.clientX, y: e.clientY });
    }
  });

  useEffect(() => {
    window.addEventListener('pointermove', onMove);
    return () => window.removeEventListener('pointermove', onMove);
  }, []);

  return (
    <>
      <label>
        <input
          type="checkbox"
          checked={canMove}
          onChange={e => setCanMove(e.target.checked)}
        />
        The dot is allowed to move
      </label>
      <hr />
      <div style={{
        position: 'absolute',
        backgroundColor: 'pink',
        borderRadius: '50%',
        opacity: 0.6,
        transform: `translate(${position.x}px, ${position.y}px)`,
        pointerEvents: 'none',
        left: -20,
        top: -20,
        width: 40,
        height: 40,
      }} />
    </>
  );
}
```

Toggle the checkbox and move your cursor. The dot responds immediately to the checkbox state, but the event listener is only set up once when the component mounts.

***

### Avoid reconnecting to external systems[](#showing-a-notification-without-reconnecting "Link for Avoid reconnecting to external systems ")

A common use case for `useEffectEvent` is when you want to do something in response to an Effect, but that “something” depends on a value you don’t want to react to.

In this example, a chat component connects to a room and shows a notification when connected. The user can mute notifications with a checkbox. However, you don’t want to reconnect to the chat room every time the user changes the settings:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useEffect, useEffectEvent } from 'react';
import { createConnection } from './chat.js';
import { showNotification } from './notifications.js';

function ChatRoom({ roomId, muted }) {
  const onConnected = useEffectEvent((roomId) => {
    console.log('✅ Connected to ' + roomId + ' (muted: ' + muted + ')');
    if (!muted) {
      showNotification('Connected to ' + roomId);
    }
  });

  useEffect(() => {
    const connection = createConnection(roomId);
    console.log('⏳ Connecting to ' + roomId + '...');
    connection.on('connected', () => {
      onConnected(roomId);
    });
    connection.connect();
    return () => {
      console.log('❌ Disconnected from ' + roomId);
      connection.disconnect();
    }
  }, [roomId]);

  return <h1>Welcome to the {roomId} room!</h1>;
}

export default function App() {
  const [roomId, setRoomId] = useState('general');
  const [muted, setMuted] = useState(false);
  return (
    <>
      <label>
        Choose the chat room:{' '}
        <select
          value={roomId}
          onChange={e => setRoomId(e.target.value)}
        >
          <option value="general">general</option>
          <option value="travel">travel</option>
          <option value="music">music</option>
        </select>
      </label>
      <label>
        <input
          type="checkbox"
          checked={muted}
          onChange={e => setMuted(e.target.checked)}
        />
        Mute notifications
      </label>
      <hr />
      <ChatRoom
        roomId={roomId}
        muted={muted}
      />
    </>
  );
}
```

Try switching rooms. The chat reconnects and shows a notification. Now mute the notifications. Since `muted` is read inside the Effect Event rather than the Effect, the chat stays connected.

***

### Using Effect Events in custom Hooks[](#using-effect-events-in-custom-hooks "Link for Using Effect Events in custom Hooks ")

You can use `useEffectEvent` inside your own custom Hooks. This lets you create reusable Hooks that encapsulate Effects while keeping some values non-reactive:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useEffect, useEffectEvent } from 'react';

function useInterval(callback, delay) {
  const onTick = useEffectEvent(callback);

  useEffect(() => {
    if (delay === null) {
      return;
    }
    const id = setInterval(() => {
      onTick();
    }, delay);
    return () => clearInterval(id);
  }, [delay]);
}

function Counter({ incrementBy }) {
  const [count, setCount] = useState(0);

  useInterval(() => {
    setCount(c => c + incrementBy);
  }, 1000);

  return (
    <div>
      <h2>Count: {count}</h2>
      <p>Incrementing by {incrementBy} every second</p>
    </div>
  );
}

export default function App() {
  const [incrementBy, setIncrementBy] = useState(1);

  return (
    <>
      <label>
        Increment by:{' '}
        <select
          value={incrementBy}
          onChange={(e) => setIncrementBy(Number(e.target.value))}
        >
          <option value={1}>1</option>
          <option value={5}>5</option>
          <option value={10}>10</option>
        </select>
      </label>
      <hr />
      <Counter incrementBy={incrementBy} />
    </>
  );
}
```

In this example, `useInterval` is a custom Hook that sets up an interval. The `callback` passed to it is wrapped in an Effect Event, so the interval does not reset even if a new `callback` is passed in every render.

***

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### I’m getting an error: “A function wrapped in useEffectEvent can’t be called during rendering”[](#cant-call-during-rendering "Link for I’m getting an error: “A function wrapped in useEffectEvent can’t be called during rendering” ")

This error means you’re calling an Effect Event function during the render phase of your component. Effect Events can only be called from inside Effects or other Effect Events.

```
function MyComponent({ data }) {

  const onLog = useEffectEvent(() => {

    console.log(data);

  });



  // 🔴 Wrong: calling during render

  onLog();



  // ✅ Correct: call from an Effect

  useEffect(() => {

    onLog();

  }, []);



  return <div>{data}</div>;

}
```

If you need to run logic during render, don’t wrap it in `useEffectEvent`. Call the logic directly or move it into an Effect.

***

### I’m getting a lint error: “Functions returned from useEffectEvent must not be included in the dependency array”[](#effect-event-in-deps "Link for I’m getting a lint error: “Functions returned from useEffectEvent must not be included in the dependency array” ")

If you see a warning like “Functions returned from `useEffectEvent` must not be included in the dependency array”, remove the Effect Event from your dependencies:

```
const onSomething = useEffectEvent(() => {

  // ...

});



// 🔴 Wrong: Effect Event in dependencies

useEffect(() => {

  onSomething();

}, [onSomething]);



// ✅ Correct: no Effect Event in dependencies

useEffect(() => {

  onSomething();

}, []);
```

Effect Events are designed to be called from Effects without being listed as dependencies. The linter enforces this because the function identity is [intentionally not stable](#why-are-effect-events-not-stable). Including it would cause your Effect to re-run on every render.

***

### I’m getting a lint error: ”… is a function created with useEffectEvent, and can only be called from Effects”[](#effect-event-called-outside-effect "Link for I’m getting a lint error: ”… is a function created with useEffectEvent, and can only be called from Effects” ")

If you see a warning like ”… is a function created with React Hook `useEffectEvent`, and can only be called from Effects and Effect Events”, you’re calling the function from the wrong place:

```
const onSomething = useEffectEvent(() => {

  console.log(value);

});



// 🔴 Wrong: calling from event handler

function handleClick() {

  onSomething();

}



// 🔴 Wrong: passing to child component

return <Child onSomething={onSomething} />;



// ✅ Correct: calling from Effect

useEffect(() => {

  onSomething();

}, []);
```

Effect Events are specifically designed to be used in Effects local to the component they’re defined in. If you need a callback for event handlers or to pass to children, use a regular function or `useCallback` instead.

[PrevioususeEffect](/reference/react/useEffect)

[NextuseId](/reference/react/useId)

***

----
url: https://react.dev/reference/react/hooks
----

[API Reference](/reference/react)

# Built-in React Hooks[](#undefined "Link for this heading")

*Hooks* let you use different React features from your components. You can either use the built-in Hooks or combine them to build your own. This page lists all built-in Hooks in React.

***

## State Hooks[](#state-hooks "Link for State Hooks ")

*State* lets a component [“remember” information like user input.](/learn/state-a-components-memory) For example, a form component can use state to store the input value, while an image gallery component can use state to store the selected image index.

To add state to a component, use one of these Hooks:

* [`useState`](/reference/react/useState) declares a state variable that you can update directly.
* [`useReducer`](/reference/react/useReducer) declares a state variable with the update logic inside a [reducer function.](/learn/extracting-state-logic-into-a-reducer)

```
function ImageGallery() {

  const [index, setIndex] = useState(0);

  // ...
```

***

## Context Hooks[](#context-hooks "Link for Context Hooks ")

*Context* lets a component [receive information from distant parents without passing it as props.](/learn/passing-props-to-a-component) For example, your app’s top-level component can pass the current UI theme to all components below, no matter how deep.

* [`useContext`](/reference/react/useContext) reads and subscribes to a context.

```
function Button() {

  const theme = useContext(ThemeContext);

  // ...
```

***

## Ref Hooks[](#ref-hooks "Link for Ref Hooks ")

*Refs* let a component [hold some information that isn’t used for rendering,](/learn/referencing-values-with-refs) like a DOM node or a timeout ID. Unlike with state, updating a ref does not re-render your component. Refs are an “escape hatch” from the React paradigm. They are useful when you need to work with non-React systems, such as the built-in browser APIs.

* [`useRef`](/reference/react/useRef) declares a ref. You can hold any value in it, but most often it’s used to hold a DOM node.
* [`useImperativeHandle`](/reference/react/useImperativeHandle) lets you customize the ref exposed by your component. This is rarely used.

```
function Form() {

  const inputRef = useRef(null);

  // ...
```

***

## Effect Hooks[](#effect-hooks "Link for Effect Hooks ")

*Effects* let a component [connect to and synchronize with external systems.](/learn/synchronizing-with-effects) This includes dealing with network, browser DOM, animations, widgets written using a different UI library, and other non-React code.

* [`useEffect`](/reference/react/useEffect) connects a component to an external system.

```
function ChatRoom({ roomId }) {

  useEffect(() => {

    const connection = createConnection(roomId);

    connection.connect();

    return () => connection.disconnect();

  }, [roomId]);

  // ...
```

Effects are an “escape hatch” from the React paradigm. Don’t use Effects to orchestrate the data flow of your application. If you’re not interacting with an external system, [you might not need an Effect.](/learn/you-might-not-need-an-effect)

There are two rarely used variations of `useEffect` with differences in timing:

* [`useLayoutEffect`](/reference/react/useLayoutEffect) fires before the browser repaints the screen. You can measure layout here.
* [`useInsertionEffect`](/reference/react/useInsertionEffect) fires before React makes changes to the DOM. Libraries can insert dynamic CSS here.

You can also separate events from Effects:

* [`useEffectEvent`](/reference/react/useEffectEvent) creates a non-reactive event to fire from any Effect hook.

***

## Performance Hooks[](#performance-hooks "Link for Performance Hooks ")

A common way to optimize re-rendering performance is to skip unnecessary work. For example, you can tell React to reuse a cached calculation or to skip a re-render if the data has not changed since the previous render.

To skip calculations and unnecessary re-rendering, use one of these Hooks:

* [`useMemo`](/reference/react/useMemo) lets you cache the result of an expensive calculation.
* [`useCallback`](/reference/react/useCallback) lets you cache a function definition before passing it down to an optimized component.

```
function TodoList({ todos, tab, theme }) {

  const visibleTodos = useMemo(() => filterTodos(todos, tab), [todos, tab]);

  // ...

}
```

Sometimes, you can’t skip re-rendering because the screen actually needs to update. In that case, you can improve performance by separating blocking updates that must be synchronous (like typing into an input) from non-blocking updates which don’t need to block the user interface (like updating a chart).

To prioritize rendering, use one of these Hooks:

* [`useTransition`](/reference/react/useTransition) lets you mark a state transition as non-blocking and allow other updates to interrupt it.
* [`useDeferredValue`](/reference/react/useDeferredValue) lets you defer updating a non-critical part of the UI and let other parts update first.

***

## Other Hooks[](#other-hooks "Link for Other Hooks ")

These Hooks are mostly useful to library authors and aren’t commonly used in the application code.

* [`useDebugValue`](/reference/react/useDebugValue) lets you customize the label React DevTools displays for your custom Hook.
* [`useId`](/reference/react/useId) lets a component associate a unique ID with itself. Typically used with accessibility APIs.
* [`useSyncExternalStore`](/reference/react/useSyncExternalStore) lets a component subscribe to an external store.

- [`useActionState`](/reference/react/useActionState) allows you to manage state of actions.

***

## Your own Hooks[](#your-own-hooks "Link for Your own Hooks ")

You can also [define your own custom Hooks](/learn/reusing-logic-with-custom-hooks#extracting-your-own-custom-hook-from-a-component) as JavaScript functions.

[PreviousOverview](/reference/react)

[NextuseActionState](/reference/react/useActionState)

***

----
url: https://react.dev/reference/eslint-plugin-react-hooks/lints/preserve-manual-memoization
----

[API Reference](/reference/react)

[Lints](/reference/eslint-plugin-react-hooks)

# preserve-manual-memoization[](#undefined "Link for this heading")

Validates that existing manual memoization is preserved by the compiler. React Compiler will only compile components and hooks if its inference [matches or exceeds the existing manual memoization](/learn/react-compiler/introduction#what-should-i-do-about-usememo-usecallback-and-reactmemo).

## Rule Details[](#rule-details "Link for Rule Details ")

React Compiler preserves your existing `useMemo`, `useCallback`, and `React.memo` calls. If you’ve manually memoized something, the compiler assumes you had a good reason and won’t remove it. However, incomplete dependencies prevent the compiler from understanding your code’s data flow and applying further optimizations.

### Invalid[](#invalid "Link for Invalid ")

Examples of incorrect code for this rule:

```
// ❌ Missing dependencies in useMemo

function Component({ data, filter }) {

  const filtered = useMemo(

    () => data.filter(filter),

    [data] // Missing 'filter' dependency

  );



  return <List items={filtered} />;

}



// ❌ Missing dependencies in useCallback

function Component({ onUpdate, value }) {

  const handleClick = useCallback(() => {

    onUpdate(value);

  }, [onUpdate]); // Missing 'value'



  return <button onClick={handleClick}>Update</button>;

}
```

### Valid[](#valid "Link for Valid ")

Examples of correct code for this rule:

```
// ✅ Complete dependencies

function Component({ data, filter }) {

  const filtered = useMemo(

    () => data.filter(filter),

    [data, filter] // All dependencies included

  );



  return <List items={filtered} />;

}



// ✅ Or let the compiler handle it

function Component({ data, filter }) {

  // No manual memoization needed

  const filtered = data.filter(filter);

  return <List items={filtered} />;

}
```

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### Should I remove my manual memoization?[](#remove-manual-memoization "Link for Should I remove my manual memoization? ")

You might wonder if React Compiler makes manual memoization unnecessary:

```
// Do I still need this?

function Component({items, sortBy}) {

  const sorted = useMemo(() => {

    return [...items].sort((a, b) => {

      return a[sortBy] - b[sortBy];

    });

  }, [items, sortBy]);



  return <List items={sorted} />;

}
```

You can safely remove it if using React Compiler:

```
// ✅ Better: Let the compiler optimize

function Component({items, sortBy}) {

  const sorted = [...items].sort((a, b) => {

    return a[sortBy] - b[sortBy];

  });



  return <List items={sorted} />;

}
```

[Previousincompatible-library](/reference/eslint-plugin-react-hooks/lints/incompatible-library)

[Nextpurity](/reference/eslint-plugin-react-hooks/lints/purity)

***

----
url: https://react.dev/learn/adding-interactivity
----

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
export default function App() {
  return (
    <Toolbar
      onPlayMovie={() => alert('Playing!')}
      onUploadImage={() => alert('Uploading!')}
    />
  );
}

function Toolbar({ onPlayMovie, onUploadImage }) {
  return (
    <div>
      <Button onClick={onPlayMovie}>
        Play Movie
      </Button>
      <Button onClick={onUploadImage}>
        Upload Image
      </Button>
    </div>
  );
}

function Button({ onClick, children }) {
  return (
    <button onClick={onClick}>
      {children}
    </button>
  );
}
```

## Ready to learn this topic?

Read **[Responding to Events](/learn/responding-to-events)** to learn how to add event handlers.

[Read More](/learn/responding-to-events)

***

## State: a component’s memory[](#state-a-components-memory "Link for State: a component’s memory ")

Components often need to change what’s on the screen as a result of an interaction. Typing into the form should update the input field, clicking “next” on an image carousel should change which image is displayed, clicking “buy” puts a product in the shopping cart. Components need to “remember” things: the current input value, the current image, the shopping cart. In React, this kind of component-specific memory is called *state.*

You can add state to a component with a [`useState`](/reference/react/useState) Hook. *Hooks* are special functions that let your components use React features (state is one of those features). The `useState` Hook lets you declare a state variable. It takes the initial state and returns a pair of values: the current state, and a state setter function that lets you update it.

```
const [index, setIndex] = useState(0);

const [showMore, setShowMore] = useState(false);
```

Here is how an image gallery uses and updates state on click:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';
import { sculptureList } from './data.js';

export default function Gallery() {
  const [index, setIndex] = useState(0);
  const [showMore, setShowMore] = useState(false);
  const hasNext = index < sculptureList.length - 1;

  function handleNextClick() {
    if (hasNext) {
      setIndex(index + 1);
    } else {
      setIndex(0);
    }
  }

  function handleMoreClick() {
    setShowMore(!showMore);
  }

  let sculpture = sculptureList[index];
  return (
    <>
      <button onClick={handleNextClick}>
        Next
      </button>
      <h2>
        <i>{sculpture.name} </i>
        by {sculpture.artist}
      </h2>
      <h3>
        ({index + 1} of {sculptureList.length})
      </h3>
      <button onClick={handleMoreClick}>
        {showMore ? 'Hide' : 'Show'} details
      </button>
      {showMore && <p>{sculpture.description}</p>}
      <img
        src={sculpture.url}
        alt={sculpture.alt}
      />
    </>
  );
}
```

## Ready to learn this topic?

Read **[State: A Component’s Memory](/learn/state-a-components-memory)** to learn how to remember a value and update it on interaction.

[Read More](/learn/state-a-components-memory)

***

***

## State as a snapshot[](#state-as-a-snapshot "Link for State as a snapshot ")

Unlike regular JavaScript variables, React state behaves more like a snapshot. Setting it does not change the state variable you already have, but instead triggers a re-render. This can be surprising at first!

```
console.log(count);  // 0

setCount(count + 1); // Request a re-render with 1

console.log(count);  // Still 0!
```

This behavior helps you avoid subtle bugs. Here is a little chat app. Try to guess what happens if you press “Send” first and *then* change the recipient to Bob. Whose name will appear in the `alert` five seconds later?

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function Form() {
  const [to, setTo] = useState('Alice');
  const [message, setMessage] = useState('Hello');

  function handleSubmit(e) {
    e.preventDefault();
    setTimeout(() => {
      alert(`You said ${message} to ${to}`);
    }, 5000);
  }

  return (
    <form onSubmit={handleSubmit}>
      <label>
        To:{' '}
        <select
          value={to}
          onChange={e => setTo(e.target.value)}>
          <option value="Alice">Alice</option>
          <option value="Bob">Bob</option>
        </select>
      </label>
      <textarea
        placeholder="Message"
        value={message}
        onChange={e => setMessage(e.target.value)}
      />
      <button type="submit">Send</button>
    </form>
  );
}
```

## Ready to learn this topic?

Read **[State as a Snapshot](/learn/state-as-a-snapshot)** to learn why state appears “fixed” and unchanging inside the event handlers.

[Read More](/learn/state-as-a-snapshot)

***

## Queueing a series of state updates[](#queueing-a-series-of-state-updates "Link for Queueing a series of state updates ")

This component is buggy: clicking “+3” increments the score only once.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function Counter() {
  const [score, setScore] = useState(0);

  function increment() {
    setScore(score + 1);
  }

  return (
    <>
      <button onClick={() => increment()}>+1</button>
      <button onClick={() => {
        increment();
        increment();
        increment();
      }}>+3</button>
      <h1>Score: {score}</h1>
    </>
  )
}
```

[State as a Snapshot](/learn/state-as-a-snapshot) explains why this is happening. Setting state requests a new re-render, but does not change it in the already running code. So `score` continues to be `0` right after you call `setScore(score + 1)`.

```
console.log(score);  // 0

setScore(score + 1); // setScore(0 + 1);

console.log(score);  // 0

setScore(score + 1); // setScore(0 + 1);

console.log(score);  // 0

setScore(score + 1); // setScore(0 + 1);

console.log(score);  // 0
```

You can fix this by passing an *updater function* when setting state. Notice how replacing `setScore(score + 1)` with `setScore(s => s + 1)` fixes the “+3” button. This lets you queue multiple state updates.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function Counter() {
  const [score, setScore] = useState(0);

  function increment() {
    setScore(s => s + 1);
  }

  return (
    <>
      <button onClick={() => increment()}>+1</button>
      <button onClick={() => {
        increment();
        increment();
        increment();
      }}>+3</button>
      <h1>Score: {score}</h1>
    </>
  )
}
```

## Ready to learn this topic?

Read **[Queueing a Series of State Updates](/learn/queueing-a-series-of-state-updates)** to learn how to queue a sequence of state updates.

[Read More](/learn/queueing-a-series-of-state-updates)

***

## Updating objects in state[](#updating-objects-in-state "Link for Updating objects in state ")

State can hold any kind of JavaScript value, including objects. But you shouldn’t change objects and arrays that you hold in the React state directly. Instead, when you want to update an object and array, you need to create a new one (or make a copy of an existing one), and then update the state to use that copy.

Usually, you will use the `...` spread syntax to copy objects and arrays that you want to change. For example, updating a nested object could look like this:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function Form() {
  const [person, setPerson] = useState({
    name: 'Niki de Saint Phalle',
    artwork: {
      title: 'Blue Nana',
      city: 'Hamburg',
      image: 'https://react.dev/images/docs/scientists/Sd1AgUOm.jpg',
    }
  });

  function handleNameChange(e) {
    setPerson({
      ...person,
      name: e.target.value
    });
  }

  function handleTitleChange(e) {
    setPerson({
      ...person,
      artwork: {
        ...person.artwork,
        title: e.target.value
      }
    });
  }

  function handleCityChange(e) {
    setPerson({
      ...person,
      artwork: {
        ...person.artwork,
        city: e.target.value
      }
    });
  }

  function handleImageChange(e) {
    setPerson({
      ...person,
      artwork: {
        ...person.artwork,
        image: e.target.value
      }
    });
  }

  return (
    <>
      <label>
        Name:
        <input
          value={person.name}
          onChange={handleNameChange}
        />
      </label>
      <label>
        Title:
        <input
          value={person.artwork.title}
          onChange={handleTitleChange}
        />
      </label>
      <label>
        City:
        <input
          value={person.artwork.city}
          onChange={handleCityChange}
        />
      </label>
      <label>
        Image:
        <input
          value={person.artwork.image}
          onChange={handleImageChange}
        />
      </label>
      <p>
        <i>{person.artwork.title}</i>
        {' by '}
        {person.name}
        <br />
        (located in {person.artwork.city})
      </p>
      <img
        src={person.artwork.image}
        alt={person.artwork.title}
      />
    </>
  );
}
```

If copying objects in code gets tedious, you can use a library like [Immer](https://github.com/immerjs/use-immer) to reduce repetitive code:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
{
  "dependencies": {
    "immer": "1.7.3",
    "react": "latest",
    "react-dom": "latest",
    "react-scripts": "latest",
    "use-immer": "0.5.1"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject"
  },
  "devDependencies": {}
}
```

## Ready to learn this topic?

Read **[Updating Objects in State](/learn/updating-objects-in-state)** to learn how to update objects correctly.

[Read More](/learn/updating-objects-in-state)

***

## Updating arrays in state[](#updating-arrays-in-state "Link for Updating arrays in state ")

Arrays are another type of mutable JavaScript objects you can store in state and should treat as read-only. Just like with objects, when you want to update an array stored in state, you need to create a new one (or make a copy of an existing one), and then set state to use the new array:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

const initialList = [
  { id: 0, title: 'Big Bellies', seen: false },
  { id: 1, title: 'Lunar Landscape', seen: false },
  { id: 2, title: 'Terracotta Army', seen: true },
];

export default function BucketList() {
  const [list, setList] = useState(
    initialList
  );

  function handleToggle(artworkId, nextSeen) {
    setList(list.map(artwork => {
      if (artwork.id === artworkId) {
        return { ...artwork, seen: nextSeen };
      } else {
        return artwork;
      }
    }));
  }

  return (
    <>
      <h1>Art Bucket List</h1>
      <h2>My list of art to see:</h2>
      <ItemList
        artworks={list}
        onToggle={handleToggle} />
    </>
  );
}

function ItemList({ artworks, onToggle }) {
  return (
    <ul>
      {artworks.map(artwork => (
        <li key={artwork.id}>
          <label>
            <input
              type="checkbox"
              checked={artwork.seen}
              onChange={e => {
                onToggle(
                  artwork.id,
                  e.target.checked
                );
              }}
            />
            {artwork.title}
          </label>
        </li>
      ))}
    </ul>
  );
}
```

If copying arrays in code gets tedious, you can use a library like [Immer](https://github.com/immerjs/use-immer) to reduce repetitive code:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
{
  "dependencies": {
    "immer": "1.7.3",
    "react": "latest",
    "react-dom": "latest",
    "react-scripts": "latest",
    "use-immer": "0.5.1"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject"
  },
  "devDependencies": {}
}
```

## Ready to learn this topic?

Read **[Updating Arrays in State](/learn/updating-arrays-in-state)** to learn how to update arrays correctly.

[Read More](/learn/updating-arrays-in-state)

***

## What’s next?[](#whats-next "Link for What’s next? ")

Head over to [Responding to Events](/learn/responding-to-events) to start reading this chapter page by page!

Or, if you’re already familiar with these topics, why not read about [Managing State](/learn/managing-state)?

[PreviousYour UI as a Tree](/learn/understanding-your-ui-as-a-tree)

[NextResponding to Events](/learn/responding-to-events)

***

----
url: https://legacy.reactjs.org/docs/hooks-intro.html
----

> These docs are old and won’t be updated. Go to [react.dev](https://react.dev/) for the new React docs.
>
> These new documentation pages teach React with Hooks:
>
> * [Quick Start](https://react.dev/learn)
> * [Tutorial](https://react.dev/learn/tutorial-tic-tac-toe)
> * [`react`: Hooks](https://react.dev/reference/react)

*Hooks* are a new addition in React 16.8. They let you use state and other React features without writing a class.

```
import React, { useState } from 'react';

function Example() {
  // Declare a new state variable, which we'll call "count"  const [count, setCount] = useState(0);
  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}
```

This new function `useState` is the first “Hook” we’ll learn about, but this example is just a teaser. Don’t worry if it doesn’t make sense yet!

**You can start learning Hooks [on the next page](/docs/hooks-overview.html).** On this page, we’ll continue by explaining why we’re adding Hooks to React and how they can help you write great applications.

> Note
>
> React 16.8.0 is the first release to support Hooks. When upgrading, don’t forget to update all packages, including React DOM. React Native has supported Hooks since [the 0.59 release of React Native](https://reactnative.dev/blog/2019/03/12/releasing-react-native-059).

## [](#video-introduction)Video Introduction

At React Conf 2018, Sophie Alpert and Dan Abramov introduced Hooks, followed by Ryan Florence demonstrating how to refactor an application to use them. Watch the video here:



## [](#no-breaking-changes)No Breaking Changes

Before we continue, note that Hooks are:

* **Completely opt-in.** You can try Hooks in a few components without rewriting any existing code. But you don’t have to learn or use Hooks right now if you don’t want to.
* **100% backwards-compatible.** Hooks don’t contain any breaking changes.
* **Available now.** Hooks are now available with the release of v16.8.0.

**There are no plans to remove classes from React.** You can read more about the gradual adoption strategy for Hooks in the [bottom section](#gradual-adoption-strategy) of this page.

**Hooks don’t replace your knowledge of React concepts.** Instead, Hooks provide a more direct API to the React concepts you already know: props, state, context, refs, and lifecycle. As we will show later, Hooks also offer a new powerful way to combine them.

**If you just want to start learning Hooks, feel free to [jump directly to the next page!](/docs/hooks-overview.html)** You can also keep reading this page to learn more about why we’re adding Hooks, and how we’re going to start using them without rewriting our applications.

## [](#motivation)Motivation

Hooks solve a wide variety of seemingly unconnected problems in React that we’ve encountered over five years of writing and maintaining tens of thousands of components. Whether you’re learning React, use it daily, or even prefer a different library with a similar component model, you might recognize some of these problems.

### [](#its-hard-to-reuse-stateful-logic-between-components)It’s hard to reuse stateful logic between components

React doesn’t offer a way to “attach” reusable behavior to a component (for example, connecting it to a store). If you’ve worked with React for a while, you may be familiar with patterns like [render props](/docs/render-props.html) and [higher-order components](/docs/higher-order-components.html) that try to solve this. But these patterns require you to restructure your components when you use them, which can be cumbersome and make code harder to follow. If you look at a typical React application in React DevTools, you will likely find a “wrapper hell” of components surrounded by layers of providers, consumers, higher-order components, render props, and other abstractions. While we could [filter them out in DevTools](https://github.com/facebook/react-devtools/pull/503), this points to a deeper underlying problem: React needs a better primitive for sharing stateful logic.

With Hooks, you can extract stateful logic from a component so it can be tested independently and reused. **Hooks allow you to reuse stateful logic without changing your component hierarchy.** This makes it easy to share Hooks among many components or with the community.

We’ll discuss this more in [Building Your Own Hooks](/docs/hooks-custom.html).

### [](#complex-components-become-hard-to-understand)Complex components become hard to understand

We’ve often had to maintain components that started out simple but grew into an unmanageable mess of stateful logic and side effects. Each lifecycle method often contains a mix of unrelated logic. For example, components might perform some data fetching in `componentDidMount` and `componentDidUpdate`. However, the same `componentDidMount` method might also contain some unrelated logic that sets up event listeners, with cleanup performed in `componentWillUnmount`. Mutually related code that changes together gets split apart, but completely unrelated code ends up combined in a single method. This makes it too easy to introduce bugs and inconsistencies.

In many cases it’s not possible to break these components into smaller ones because the stateful logic is all over the place. It’s also difficult to test them. This is one of the reasons many people prefer to combine React with a separate state management library. However, that often introduces too much abstraction, requires you to jump between different files, and makes reusing components more difficult.

To solve this, **Hooks let you split one component into smaller functions based on what pieces are related (such as setting up a subscription or fetching data)**, rather than forcing a split based on lifecycle methods. You may also opt into managing the component’s local state with a reducer to make it more predictable.

We’ll discuss this more in [Using the Effect Hook](/docs/hooks-effect.html#tip-use-multiple-effects-to-separate-concerns).

### [](#classes-confuse-both-people-and-machines)Classes confuse both people and machines

In addition to making code reuse and code organization more difficult, we’ve found that classes can be a large barrier to learning React. You have to understand how `this` works in JavaScript, which is very different from how it works in most languages. You have to remember to bind the event handlers. Without [ES2022 public class fields](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Public_class_fields#public_instance_fields), the code is very verbose. People can understand props, state, and top-down data flow perfectly well but still struggle with classes. The distinction between function and class components in React and when to use each one leads to disagreements even between experienced React developers.

Additionally, React has been out for about five years, and we want to make sure it stays relevant in the next five years. As [Svelte](https://svelte.dev/), [Angular](https://angular.io/), [Glimmer](https://glimmerjs.com/), and others show, [ahead-of-time compilation](https://en.wikipedia.org/wiki/Ahead-of-time_compilation) of components has a lot of future potential. Especially if it’s not limited to templates. Recently, we’ve been experimenting with [component folding](https://github.com/facebook/react/issues/7323) using [Prepack](https://prepack.io/), and we’ve seen promising early results. However, we found that class components can encourage unintentional patterns that make these optimizations fall back to a slower path. Classes present issues for today’s tools, too. For example, classes don’t minify very well, and they make hot reloading flaky and unreliable. We want to present an API that makes it more likely for code to stay on the optimizable path.

To solve these problems, **Hooks let you use more of React’s features without classes.** Conceptually, React components have always been closer to functions. Hooks embrace functions, but without sacrificing the practical spirit of React. Hooks provide access to imperative escape hatches and don’t require you to learn complex functional or reactive programming techniques.

> Examples
>
> [Hooks at a Glance](/docs/hooks-overview.html) is a good place to start learning Hooks.

## [](#gradual-adoption-strategy)Gradual Adoption Strategy

> **TLDR: There are no plans to remove classes from React.**

We know that React developers are focused on shipping products and don’t have time to look into every new API that’s being released. Hooks are very new, and it might be better to wait for more examples and tutorials before considering learning or adopting them.

We also understand that the bar for adding a new primitive to React is extremely high. For curious readers, we have prepared a [detailed RFC](https://github.com/reactjs/rfcs/pull/68) that dives into the motivation with more details, and provides extra perspective on the specific design decisions and related prior art.

**Crucially, Hooks work side-by-side with existing code so you can adopt them gradually.** There is no rush to migrate to Hooks. We recommend avoiding any “big rewrites”, especially for existing, complex class components. It takes a bit of a mind shift to start “thinking in Hooks”. In our experience, it’s best to practice using Hooks in new and non-critical components first, and ensure that everybody on your team feels comfortable with them. After you give Hooks a try, please feel free to [send us feedback](https://github.com/facebook/react/issues/new), positive or negative.

We intend for Hooks to cover all existing use cases for classes, but **we will keep supporting class components for the foreseeable future.** At Facebook, we have tens of thousands of components written as classes, and we have absolutely no plans to rewrite them. Instead, we are starting to use Hooks in the new code side by side with classes.

## [](#frequently-asked-questions)Frequently Asked Questions

We’ve prepared a [Hooks FAQ page](/docs/hooks-faq.html) that answers the most common questions about Hooks.

## [](#next-steps)Next Steps

By the end of this page, you should have a rough idea of what problems Hooks are solving, but many details are probably unclear. Don’t worry! **Let’s now go to [the next page](/docs/hooks-overview.html) where we start learning about Hooks by example.**

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/hooks-intro.md)

*

* Next article

  [Hooks at a Glance](/docs/hooks-overview.html)

----
url: https://18.react.dev/community/versioning-policy
----

[Community](/community)

# Versioning Policy[](#undefined "Link for this heading")

All stable builds of React go through a high level of testing and follow semantic versioning (semver). React also offers unstable release channels to encourage early feedback on experimental features. This page describes what you can expect from React releases.

For a list of previous releases, see the [Versions](/versions) page.

### Breaking Changes[](#breaking-changes "Link for Breaking Changes ")

  ```
  npm update react@canary react-dom@canary
  ```

  Or yarn:

  ```
  yarn upgrade react@canary react-dom@canary
  ```

***

----
url: https://react.dev/reference/rules/components-and-hooks-must-be-pure
----

*Rendering* refers to calculating what the next version of your UI should look like. After rendering, React takes this new calculation and compares it to the calculation used to create the previous version of your UI. Then React commits just the minimum changes needed to the [DOM](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model) (what your user actually sees) to apply the changes. Finally, [Effects](/learn/synchronizing-with-effects) are flushed (meaning they are run until there are no more left). For more detailed information see the docs for [Render](/learn/render-and-commit) and [Commit and Effect Hooks](/reference/react/hooks#effect-hooks).

##### Deep Dive#### How to tell if code runs in render[](#how-to-tell-if-code-runs-in-render "Link for How to tell if code runs in render ")

One quick heuristic to tell if code runs during render is to examine where it is: if it’s written at the top level like in the example below, there’s a good chance it runs during render.

```
function Dropdown() {

  const selectedItems = new Set(); // created during render

  // ...

}
```

Event handlers and Effects don’t run in render:

```
function Dropdown() {

  const selectedItems = new Set();

  const onSelect = (item) => {

    // this code is in an event handler, so it's only run when the user triggers this

    selectedItems.add(item);

  }

}
```

```
function Dropdown() {

  const selectedItems = new Set();

  useEffect(() => {

    // this code is inside of an Effect, so it only runs after rendering

    logForAnalytics(selectedItems);

  }, [selectedItems]);

}
```

***

## Components and Hooks must be idempotent[](#components-and-hooks-must-be-idempotent "Link for Components and Hooks must be idempotent ")

Components must always return the same output with respect to their inputs – props, state, and context. This is known as *idempotency*. [Idempotency](https://en.wikipedia.org/wiki/Idempotence) is a term popularized in functional programming. It refers to the idea that you [always get the same result every time](/learn/keeping-components-pure) you run that piece of code with the same inputs.

This means that *all* code that runs [during render](#how-does-react-run-your-code) must also be idempotent in order for this rule to hold. For example, this line of code is not idempotent (and therefore, neither is the component):

```
function Clock() {

  const time = new Date(); // 🔴 Bad: always returns a different result!

  return <span>{time.toLocaleString()}</span>

}
```

`new Date()` is not idempotent as it always returns the current date and changes its result every time it’s called. When you render the above component, the time displayed on the screen will stay stuck on the time that the component was rendered. Similarly, functions like `Math.random()` also aren’t idempotent, because they return different results every time they’re called, even when the inputs are the same.

This doesn’t mean you shouldn’t use non-idempotent functions like `new Date()` *at all* – you should just avoid using them [during render](#how-does-react-run-your-code). In this case, we can *synchronize* the latest date to this component using an [Effect](/reference/react/useEffect):

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useEffect } from 'react';

function useTime() {
  // 1. Keep track of the current date's state. `useState` receives an initializer function as its
  //    initial state. It only runs once when the hook is called, so only the current date at the
  //    time the hook is called is set first.
  const [time, setTime] = useState(() => new Date());

  useEffect(() => {
    // 2. Update the current date every second using `setInterval`.
    const id = setInterval(() => {
      setTime(new Date()); // ✅ Good: non-idempotent code no longer runs in render
    }, 1000);
    // 3. Return a cleanup function so we don't leak the `setInterval` timer.
    return () => clearInterval(id);
  }, []);

  return time;
}

export default function Clock() {
  const time = useTime();
  return <span>{time.toLocaleString()}</span>;
}
```

By wrapping the non-idempotent `new Date()` call in an Effect, it moves that calculation [outside of rendering](#how-does-react-run-your-code).

If you don’t need to synchronize some external state with React, you can also consider using an [event handler](/learn/responding-to-events) if it only needs to be updated in response to a user interaction.

***

```
function FriendList({ friends }) {

  const items = []; // ✅ Good: locally created

  for (let i = 0; i < friends.length; i++) {

    const friend = friends[i];

    items.push(

      <Friend key={friend.id} friend={friend} />

    ); // ✅ Good: local mutation is okay

  }

  return <section>{items}</section>;

}
```

There is no need to contort your code to avoid local mutation. [`Array.map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) could also be used here for brevity, but there is nothing wrong with creating a local array and then pushing items into it [during render](#how-does-react-run-your-code).

Even though it looks like we are mutating `items`, the key point to note is that this code only does so *locally* – the mutation isn’t “remembered” when the component is rendered again. In other words, `items` only stays around as long as the component does. Because `items` is always *recreated* every time `<FriendList />` is rendered, the component will always return the same result.

On the other hand, if `items` was created outside of the component, it holds on to its previous values and remembers changes:

```
const items = []; // 🔴 Bad: created outside of the component

function FriendList({ friends }) {

  for (let i = 0; i < friends.length; i++) {

    const friend = friends[i];

    items.push(

      <Friend key={friend.id} friend={friend} />

    ); // 🔴 Bad: mutates a value created outside of render

  }

  return <section>{items}</section>;

}
```

When `<FriendList />` runs again, we will continue appending `friends` to `items` every time that component is run, leading to multiple duplicated results. This version of `<FriendList />` has observable side effects [during render](#how-does-react-run-your-code) and **breaks the rule**.

#### Lazy initialization[](#lazy-initialization "Link for Lazy initialization ")

Lazy initialization is also fine despite not being fully “pure”:

```
function ExpenseForm() {

  SuperCalculator.initializeIfNotReady(); // ✅ Good: if it doesn't affect other components

  // Continue rendering...

}
```

#### Changing the DOM[](#changing-the-dom "Link for Changing the DOM ")

Side effects that are directly visible to the user are not allowed in the render logic of React components. In other words, merely calling a component function shouldn’t by itself produce a change on the screen.

```
function ProductDetailPage({ product }) {

  document.title = product.title; // 🔴 Bad: Changes the DOM

}
```

One way to achieve the desired result of updating `document.title` outside of render is to [synchronize the component with `document`](/learn/synchronizing-with-effects).

As long as calling a component multiple times is safe and doesn’t affect the rendering of other components, React doesn’t care if it’s 100% pure in the strict functional programming sense of the word. It is more important that [components must be idempotent](/reference/rules/components-and-hooks-must-be-pure).

***

## Props and state are immutable[](#props-and-state-are-immutable "Link for Props and state are immutable ")

A component’s props and state are immutable [snapshots](/learn/state-as-a-snapshot). Never mutate them directly. Instead, pass new props down, and use the setter function from `useState`.

You can think of the props and state values as snapshots that are updated after rendering. For this reason, you don’t modify the props or state variables directly: instead you pass new props, or use the setter function provided to you to tell React that state needs to update the next time the component is rendered.

### Don’t mutate Props[](#props "Link for Don’t mutate Props ")

Props are immutable because if you mutate them, the application will produce inconsistent output, which can be hard to debug as it may or may not work depending on the circumstances.

```
function Post({ item }) {

  item.url = new Url(item.url, base); // 🔴 Bad: never mutate props directly

  return <Link url={item.url}>{item.title}</Link>;

}
```

```
function Post({ item }) {

  const url = new Url(item.url, base); // ✅ Good: make a copy instead

  return <Link url={url}>{item.title}</Link>;

}
```

### Don’t mutate State[](#state "Link for Don’t mutate State ")

`useState` returns the state variable and a setter to update that state.

```
const [stateVariable, setter] = useState(0);
```

Rather than updating the state variable in-place, we need to update it using the setter function that is returned by `useState`. Changing values on the state variable doesn’t cause the component to update, leaving your users with an outdated UI. Using the setter function informs React that the state has changed, and that we need to queue a re-render to update the UI.

```
function Counter() {

  const [count, setCount] = useState(0);



  function handleClick() {

    count = count + 1; // 🔴 Bad: never mutate state directly

  }



  return (

    <button onClick={handleClick}>

      You pressed me {count} times

    </button>

  );

}
```

```
function Counter() {

  const [count, setCount] = useState(0);



  function handleClick() {

    setCount(count + 1); // ✅ Good: use the setter function returned by useState

  }



  return (

    <button onClick={handleClick}>

      You pressed me {count} times

    </button>

  );

}
```

***

## Return values and arguments to Hooks are immutable[](#return-values-and-arguments-to-hooks-are-immutable "Link for Return values and arguments to Hooks are immutable ")

Once values are passed to a hook, you should not modify them. Like props in JSX, values become immutable when passed to a hook.

```
function useIconStyle(icon) {

  const theme = useContext(ThemeContext);

  if (icon.enabled) {

    icon.className = computeStyle(icon, theme); // 🔴 Bad: never mutate hook arguments directly

  }

  return icon;

}
```

```
function useIconStyle(icon) {

  const theme = useContext(ThemeContext);

  const newIcon = { ...icon }; // ✅ Good: make a copy instead

  if (icon.enabled) {

    newIcon.className = computeStyle(icon, theme);

  }

  return newIcon;

}
```

One important principle in React is *local reasoning*: the ability to understand what a component or hook does by looking at its code in isolation. Hooks should be treated like “black boxes” when they are called. For example, a custom hook might have used its arguments as dependencies to memoize values inside it:

```
function useIconStyle(icon) {

  const theme = useContext(ThemeContext);



  return useMemo(() => {

    const newIcon = { ...icon };

    if (icon.enabled) {

      newIcon.className = computeStyle(icon, theme);

    }

    return newIcon;

  }, [icon, theme]);

}
```

If you were to mutate the Hook’s arguments, the custom hook’s memoization will become incorrect, so it’s important to avoid doing that.

```
style = useIconStyle(icon);         // `style` is memoized based on `icon`

icon.enabled = false;               // Bad: 🔴 never mutate hook arguments directly

style = useIconStyle(icon);         // previously memoized result is returned
```

```
style = useIconStyle(icon);         // `style` is memoized based on `icon`

icon = { ...icon, enabled: false }; // Good: ✅ make a copy instead

style = useIconStyle(icon);         // new value of `style` is calculated
```

Similarly, it’s important to not modify the return values of Hooks, as they may have been memoized.

***

## Values are immutable after being passed to JSX[](#values-are-immutable-after-being-passed-to-jsx "Link for Values are immutable after being passed to JSX ")

Don’t mutate values after they’ve been used in JSX. Move the mutation to before the JSX is created.

When you use JSX in an expression, React may eagerly evaluate the JSX before the component finishes rendering. This means that mutating values after they’ve been passed to JSX can lead to outdated UIs, as React won’t know to update the component’s output.

```
function Page({ colour }) {

  const styles = { colour, size: "large" };

  const header = <Header styles={styles} />;

  styles.size = "small"; // 🔴 Bad: styles was already used in the JSX above

  const footer = <Footer styles={styles} />;

  return (

    <>

      {header}

      <Content />

      {footer}

    </>

  );

}
```

```
function Page({ colour }) {

  const headerStyles = { colour, size: "large" };

  const header = <Header styles={headerStyles} />;

  const footerStyles = { colour, size: "small" }; // ✅ Good: we created a new value

  const footer = <Footer styles={footerStyles} />;

  return (

    <>

      {header}

      <Content />

      {footer}

    </>

  );

}
```

[PreviousOverview](/reference/rules)

[NextReact calls Components and Hooks](/reference/rules/react-calls-components-and-hooks)

***

----
url: https://legacy.reactjs.org/blog/2015/03/26/introducing-react-native.html
----

March 26, 2015 by [Sophie Alpert](https://sophiebits.com/)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

In January at React.js Conf, we announced React Native, a new framework for building native apps using React. We’re happy to announce that we’re open-sourcing React Native and you can start building your apps with it today.

For more details, see [Tom Occhino’s post on the Facebook Engineering blog](https://code.facebook.com/posts/1014532261909640/react-native-bringing-modern-web-techniques-to-mobile/):

> *What we really want is the user experience of the native mobile platforms, combined with the developer experience we have when building with React on the web.*
>
> *With a bit of work, we can make it so the exact same React that’s on GitHub can power truly native mobile applications. The only difference in the mobile environment is that instead of running React in the browser and rendering to divs and spans, we run it an embedded instance of JavaScriptCore inside our apps and render to higher-level platform-specific components.*
>
> *It’s worth noting that we’re not chasing “write once, run anywhere.” Different platforms have different looks, feels, and capabilities, and as such, we should still be developing discrete apps for each platform, but the same set of engineers should be able to build applications for whatever platform they choose, without needing to learn a fundamentally different set of technologies for each. We call this approach “learn once, write anywhere.”*

To learn more, visit the [React Native website](https://reactnative.dev/).

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2015-03-26-introducing-react-native.md)

----
url: https://react.dev/learn/react-compiler/introduction
----

[Learn React](/learn)

[React Compiler](/learn/react-compiler)

# Introduction[](#undefined "Link for this heading")

React Compiler is a new build-time tool that automatically optimizes your React app. It works with plain JavaScript, and understands the [Rules of React](/reference/rules), so you don’t need to rewrite any code to use it.

### You will learn

* What React Compiler does
* Getting started with the compiler
* Incremental adoption strategies
* Debugging and troubleshooting when things go wrong
* Using the compiler on your React library

## What does React Compiler do?[](#what-does-react-compiler-do "Link for What does React Compiler do? ")

React Compiler automatically optimizes your React application at build time. React is often fast enough without optimization, but sometimes you need to manually memoize components and values to keep your app responsive. This manual memoization is tedious, easy to get wrong, and adds extra code to maintain. React Compiler does this optimization automatically for you, freeing you from this mental burden so you can focus on building features.

### Before React Compiler[](#before-react-compiler "Link for Before React Compiler ")

Without the compiler, you need to manually memoize components and values to optimize re-renders:

```
import { useMemo, useCallback, memo } from 'react';



const ExpensiveComponent = memo(function ExpensiveComponent({ data, onClick }) {

  const processedData = useMemo(() => {

    return expensiveProcessing(data);

  }, [data]);



  const handleClick = useCallback((item) => {

    onClick(item.id);

  }, [onClick]);



  return (

    <div>

      {processedData.map(item => (

        <Item key={item.id} onClick={() => handleClick(item)} />

      ))}

    </div>

  );

});
```

### Note

This manual memoization has a subtle bug that breaks memoization:

```
<Item key={item.id} onClick={() => handleClick(item)} />
```

Even though `handleClick` is wrapped in `useCallback`, the arrow function `() => handleClick(item)` creates a new function every time the component renders. This means that `Item` will always receive a new `onClick` prop, breaking memoization.

React Compiler is able to optimize this correctly with or without the arrow function, ensuring that `Item` only re-renders when `props.onClick` changes.

### After React Compiler[](#after-react-compiler "Link for After React Compiler ")

With React Compiler, you write the same code without manual memoization:

```
function ExpensiveComponent({ data, onClick }) {

  const processedData = expensiveProcessing(data);



  const handleClick = (item) => {

    onClick(item.id);

  };



  return (

    <div>

      {processedData.map(item => (

        <Item key={item.id} onClick={() => handleClick(item)} />

      ))}

    </div>

  );

}
```

*[See this example in the React Compiler Playground](https://playground.react.dev/#N4Igzg9grgTgxgUxALhAMygOzgFwJYSYAEAogB4AOCmYeAbggMIQC2Fh1OAFMEQCYBDHAIA0RQowA2eOAGsiAXwCURYAB1iROITA4iFGBERgwCPgBEhAogF4iCStVoMACoeO1MAcy6DhSgG4NDSItHT0ACwFMPkkmaTlbIi48HAQWFRsAPlUQ0PFMKRlZFLSWADo8PkC8hSDMPJgEHFhiLjzQgB4+eiyO-OADIwQTM0thcpYBClL02xz2zXz8zoBJMqJZBABPG2BU9Mq+BQKiuT2uTJyomLizkoOMk4B6PqX8pSUFfs7nnro3qEapgFCAFEA)*

React Compiler automatically applies the optimal memoization, ensuring your app only re-renders when necessary.

##### Deep Dive#### What kind of memoization does React Compiler add?[](#what-kind-of-memoization-does-react-compiler-add "Link for What kind of memoization does React Compiler add? ")

React Compiler’s automatic memoization is primarily focused on **improving update performance** (re-rendering existing components), so it focuses on these two use cases:

1. **Skipping cascading re-rendering of components**
   * Re-rendering `<Parent />` causes many components in its component tree to re-render, even though only `<Parent />` has changed
2. **Skipping expensive calculations from outside of React**
   * For example, calling `expensivelyProcessAReallyLargeArrayOfObjects()` inside of your component or hook that needs that data

#### Optimizing Re-renders[](#optimizing-re-renders "Link for Optimizing Re-renders ")

React lets you express your UI as a function of their current state (more concretely: their props, state, and context). In its current implementation, when a component’s state changes, React will re-render that component *and all of its children* — unless you have applied some form of manual memoization with `useMemo()`, `useCallback()`, or `React.memo()`. For example, in the following example, `<MessageButton>` will re-render whenever `<FriendList>`’s state changes:

```
function FriendList({ friends }) {

  const onlineCount = useFriendOnlineCount();

  if (friends.length === 0) {

    return <NoFriends />;

  }

  return (

    <div>

      <span>{onlineCount} online</span>

      {friends.map((friend) => (

        <FriendListCard key={friend.id} friend={friend} />

      ))}

      <MessageButton />

    </div>

  );

}
```

[*See this example in the React Compiler Playground*](https://playground.react.dev/#N4Igzg9grgTgxgUxALhAMygOzgFwJYSYAEAYjHgpgCYAyeYOAFMEWuZVWEQL4CURwADrEicQgyKEANnkwIAwtEw4iAXiJQwCMhWoB5TDLmKsTXgG5hRInjRFGbXZwB0UygHMcACzWr1ABn4hEWsYBBxYYgAeADkIHQ4uAHoAPksRbisiMIiYYkYs6yiqPAA3FMLrIiiwAAcAQ0wU4GlZBSUcbklDNqikusaKkKrgR0TnAFt62sYHdmp+VRT7SqrqhOo6Bnl6mCoiAGsEAE9VUfmqZzwqLrHqM7ubolTVol5eTOGigFkEMDB6u4EAAhKA4HCEZ5DNZ9ErlLIWYTcEDcIA)

React Compiler automatically applies the equivalent of manual memoization, ensuring that only the relevant parts of an app re-render as state changes, which is sometimes referred to as “fine-grained reactivity”. In the above example, React Compiler determines that the return value of `<FriendListCard />` can be reused even as `friends` changes, and can avoid recreating this JSX *and* avoid re-rendering `<MessageButton>` as the count changes.

#### Expensive calculations also get memoized[](#expensive-calculations-also-get-memoized "Link for Expensive calculations also get memoized ")

React Compiler can also automatically memoize expensive calculations used during rendering:

```
// **Not** memoized by React Compiler, since this is not a component or hook

function expensivelyProcessAReallyLargeArrayOfObjects() { /* ... */ }



// Memoized by React Compiler since this is a component

function TableContainer({ items }) {

  // This function call would be memoized:

  const data = expensivelyProcessAReallyLargeArrayOfObjects(items);

  // ...

}
```

[*See this example in the React Compiler Playground*](https://playground.react.dev/#N4Igzg9grgTgxgUxALhAejQAgFTYHIQAuumAtgqRAJYBeCAJpgEYCemASggIZyGYDCEUgAcqAGwQwANJjBUAdokyEAFlTCZ1meUUxdMcIcIjyE8vhBiYVECAGsAOvIBmURYSonMCAB7CzcgBuCGIsAAowEIhgYACCnFxioQAyXDAA5gixMDBcLADyzvlMAFYIvGAAFACUmMCYaNiYAHStOFgAvk5OGJgAshTUdIysHNy8AkbikrIKSqpaWvqGIiZmhE6u7p7ymAAqXEwSguZcCpKV9VSEFBodtcBOmAYmYHz0XIT6ALzefgFUYKhCJRBAxeLcJIsVIZLI5PKFYplCqVa63aoAbm6u0wMAQhFguwAPPRAQA+YAfL4dIloUmBMlODogDpAA)

However, if `expensivelyProcessAReallyLargeArrayOfObjects` is truly an expensive function, you may want to consider implementing its own memoization outside of React, because:

* React Compiler only memoizes React components and hooks, not every function
* React Compiler’s memoization is not shared across multiple components or hooks

So if `expensivelyProcessAReallyLargeArrayOfObjects` was used in many different components, even if the same exact items were passed down, that expensive calculation would be run repeatedly. We recommend [profiling](/reference/react/useMemo#how-to-tell-if-a-calculation-is-expensive) first to see if it really is that expensive before making code more complicated.

## Should I try out the compiler?[](#should-i-try-out-the-compiler "Link for Should I try out the compiler? ")

We encourage everyone to start using React Compiler. While the compiler is still an optional addition to React today, in the future some features may require the compiler in order to fully work.

### Is it safe to use?[](#is-it-safe-to-use "Link for Is it safe to use? ")

React Compiler is now stable and has been tested extensively in production. While it has been used in production at companies like Meta, rolling out the compiler to production for your app will depend on the health of your codebase and how well you’ve followed the [Rules of React](/reference/rules).

## What build tools are supported?[](#what-build-tools-are-supported "Link for What build tools are supported? ")

React Compiler can be installed across [several build tools](/learn/react-compiler/installation) such as Babel, Vite, Metro, and Rsbuild.

React Compiler is primarily a light Babel plugin wrapper around the core compiler, which was designed to be decoupled from Babel itself. While the initial stable version of the compiler will remain primarily a Babel plugin, we are working with the swc and [oxc](https://github.com/oxc-project/oxc/issues/10048) teams to build first class support for React Compiler so you won’t have to add Babel back to your build pipelines in the future.

Next.js users can enable the swc-invoked React Compiler by using [v15.3.1](https://github.com/vercel/next.js/releases/tag/v15.3.1) and up.

## What should I do about useMemo, useCallback, and React.memo?[](#what-should-i-do-about-usememo-usecallback-and-reactmemo "Link for What should I do about useMemo, useCallback, and React.memo? ")

By default, React Compiler will memoize your code based on its analysis and heuristics. In most cases, this memoization will be as precise, or moreso, than what you may have written.

However, in some cases developers may need more control over memoization. The `useMemo` and `useCallback` hooks can continue to be used with React Compiler as an escape hatch to provide control over which values are memoized. A common use-case for this is if a memoized value is used as an effect dependency, in order to ensure that an effect does not fire repeatedly even when its dependencies do not meaningfully change.

For new code, we recommend relying on the compiler for memoization and using `useMemo`/`useCallback` where needed to achieve precise control.

For existing code, we recommend either leaving existing memoization in place (removing it can change compilation output) or carefully testing before removing the memoization.

## Try React Compiler[](#try-react-compiler "Link for Try React Compiler ")

This section will help you get started with React Compiler and understand how to use it effectively in your projects.

* **[Installation](/learn/react-compiler/installation)** - Install React Compiler and configure it for your build tools
* **[React Version Compatibility](/reference/react-compiler/target)** - Support for React 17, 18, and 19
* **[Configuration](/reference/react-compiler/configuration)** - Customize the compiler for your specific needs
* **[Incremental Adoption](/learn/react-compiler/incremental-adoption)** - Strategies for gradually rolling out the compiler in existing codebases
* **[Debugging and Troubleshooting](/learn/react-compiler/debugging)** - Identify and fix issues when using the compiler
* **[Compiling Libraries](/reference/react-compiler/compiling-libraries)** - Best practices for shipping compiled code
* **[API Reference](/reference/react-compiler/configuration)** - Detailed documentation of all configuration options

## Additional resources[](#additional-resources "Link for Additional resources ")

In addition to these docs, we recommend checking the [React Compiler Working Group](https://github.com/reactwg/react-compiler) for additional information and discussion about the compiler.

[PreviousReact Compiler](/learn/react-compiler)

[NextInstallation](/learn/react-compiler/installation)

***

----
url: https://react.dev/blog/2022/03/29/react-v18
----

[Blog](/blog)

# React v18.0[](#undefined "Link for this heading")

March 29, 2022 by [The React Team](/community/team)

***

React 18 is now available on npm! In our last post, we shared step-by-step instructions for [upgrading your app to React 18](/blog/2022/03/08/react-18-upgrade-guide). In this post, we’ll give an overview of what’s new in React 18, and what it means for the future.

***

Our latest major version includes out-of-the-box improvements like automatic batching, new APIs like startTransition, and streaming server-side rendering with support for Suspense.

Many of the features in React 18 are built on top of our new concurrent renderer, a behind-the-scenes change that unlocks powerful new capabilities. Concurrent React is opt-in — it’s only enabled when you use a concurrent feature — but we think it will have a big impact on the way people build applications.

We’ve spent years researching and developing support for concurrency in React, and we’ve taken extra care to provide a gradual adoption path for existing users. Last summer, [we formed the React 18 Working Group](/blog/2021/06/08/the-plan-for-react-18) to gather feedback from experts in the community and ensure a smooth upgrade experience for the entire React ecosystem.

In case you missed it, we shared a lot of this vision at React Conf 2021:

* In [the keynote](https://www.youtube.com/watch?v=FZ0cG47msEk\&list=PLNG_1j3cPCaZZ7etkzWA7JfdmKWT0pMsa), we explain how React 18 fits into our mission to make it easy for developers to build great user experiences
* [Shruti Kapoor](https://twitter.com/shrutikapoor08) [demonstrated how to use the new features in React 18](https://www.youtube.com/watch?v=ytudH8je5ko\&list=PLNG_1j3cPCaZZ7etkzWA7JfdmKWT0pMsa\&index=2)
* [Shaundai Person](https://twitter.com/shaundai) gave us an overview of [streaming server rendering with Suspense](https://www.youtube.com/watch?v=pj5N-Khihgc\&list=PLNG_1j3cPCaZZ7etkzWA7JfdmKWT0pMsa\&index=3)

Below is a full overview of what to expect in this release, starting with Concurrent Rendering.

### Note

For React Native users, React 18 will ship in React Native with the New React Native Architecture. For more information, see the [React Conf keynote here](https://www.youtube.com/watch?v=FZ0cG47msEk\&t=1530s).

## What is Concurrent React?[](#what-is-concurrent-react "Link for What is Concurrent React? ")

## Gradually Adopting Concurrent Features[](#gradually-adopting-concurrent-features "Link for Gradually Adopting Concurrent Features ")

Technically, concurrent rendering is a breaking change. Because concurrent rendering is interruptible, components behave slightly differently when it is enabled.

In our testing, we’ve upgraded thousands of components to React 18. What we’ve found is that nearly all existing components “just work” with concurrent rendering, without any changes. However, some of them may require some additional migration effort. Although the changes are usually small, you’ll still have the ability to make them at your own pace. The new rendering behavior in React 18 is **only enabled in the parts of your app that use new features.**

The overall upgrade strategy is to get your application running on React 18 without breaking existing code. Then you can gradually start adding concurrent features at your own pace. You can use [`<StrictMode>`](/reference/react/StrictMode) to help surface concurrency-related bugs during development. Strict Mode doesn’t affect production behavior, but during development it will log extra warnings and double-invoke functions that are expected to be idempotent. It won’t catch everything, but it’s effective at preventing the most common types of mistakes.

After you upgrade to React 18, you’ll be able to start using concurrent features immediately. For example, you can use startTransition to navigate between screens without blocking user input. Or useDeferredValue to throttle expensive re-renders.

However, long term, we expect the main way you’ll add concurrency to your app is by using a concurrent-enabled library or framework. In most cases, you won’t interact with concurrent APIs directly. For example, instead of developers calling startTransition whenever they navigate to a new screen, router libraries will automatically wrap navigations in startTransition.

It may take some time for libraries to upgrade to be concurrent compatible. We’ve provided new APIs to make it easier for libraries to take advantage of concurrent features. In the meantime, please be patient with maintainers as we work to gradually migrate the React ecosystem.

For more info, see our previous post: [How to upgrade to React 18](/blog/2022/03/08/react-18-upgrade-guide).

## Suspense in Data Frameworks[](#suspense-in-data-frameworks "Link for Suspense in Data Frameworks ")

In React 18, you can start using [Suspense](/reference/react/Suspense) for data fetching in opinionated frameworks like Relay, Next.js, Hydrogen, or Remix. Ad hoc data fetching with Suspense is technically possible, but still not recommended as a general strategy.

In the future, we may expose additional primitives that could make it easier to access your data with Suspense, perhaps without the use of an opinionated framework. However, Suspense works best when it’s deeply integrated into your application’s architecture: your router, your data layer, and your server rendering environment. So even long term, we expect that libraries and frameworks will play a crucial role in the React ecosystem.

As in previous versions of React, you can also use Suspense for code splitting on the client with React.lazy. But our vision for Suspense has always been about much more than loading code — the goal is to extend support for Suspense so that eventually, the same declarative Suspense fallback can handle any asynchronous operation (loading code, data, images, etc).

## Server Components is Still in Development[](#server-components-is-still-in-development "Link for Server Components is Still in Development ")

[**Server Components**](/blog/2020/12/21/data-fetching-with-react-server-components) is an upcoming feature that allows developers to build apps that span the server and client, combining the rich interactivity of client-side apps with the improved performance of traditional server rendering. Server Components is not inherently coupled to Concurrent React, but it’s designed to work best with concurrent features like Suspense and streaming server rendering.

Server Components is still experimental, but we expect to release an initial version in a minor 18.x release. In the meantime, we’re working with frameworks like Next.js, Hydrogen, and Remix to advance the proposal and get it ready for broad adoption.

## What’s New in React 18[](#whats-new-in-react-18 "Link for What’s New in React 18 ")

### New Feature: Automatic Batching[](#new-feature-automatic-batching "Link for New Feature: Automatic Batching ")

Batching is when React groups multiple state updates into a single re-render for better performance. Without automatic batching, we only batched updates inside React event handlers. Updates inside of promises, setTimeout, native event handlers, or any other event were not batched in React by default. With automatic batching, these updates will be batched automatically:

```
// Before: only React events were batched.

setTimeout(() => {

  setCount(c => c + 1);

  setFlag(f => !f);

  // React will render twice, once for each state update (no batching)

}, 1000);



// After: updates inside of timeouts, promises,

// native event handlers or any other event are batched.

setTimeout(() => {

  setCount(c => c + 1);

  setFlag(f => !f);

  // React will only re-render once at the end (that's batching!)

}, 1000);
```

For more info, see this post for [Automatic batching for fewer renders in React 18](https://github.com/reactwg/react-18/discussions/21).

### New Feature: Transitions[](#new-feature-transitions "Link for New Feature: Transitions ")

A transition is a new concept in React to distinguish between urgent and non-urgent updates.

* **Urgent updates** reflect direct interaction, like typing, clicking, pressing, and so on.
* **Transition updates** transition the UI from one view to another.

Urgent updates like typing, clicking, or pressing, need immediate response to match our intuitions about how physical objects behave. Otherwise they feel “wrong”. However, transitions are different because the user doesn’t expect to see every intermediate value on screen.

For example, when you select a filter in a dropdown, you expect the filter button itself to respond immediately when you click. However, the actual results may transition separately. A small delay would be imperceptible and often expected. And if you change the filter again before the results are done rendering, you only care to see the latest results.

Typically, for the best user experience, a single user input should result in both an urgent update and a non-urgent one. You can use startTransition API inside an input event to inform React which updates are urgent and which are “transitions”:

```
import { startTransition } from 'react';



// Urgent: Show what was typed

setInputValue(input);



// Mark any state updates inside as transitions

startTransition(() => {

  // Transition: Show the results

  setSearchQuery(input);

});
```

Updates wrapped in startTransition are handled as non-urgent and will be interrupted if more urgent updates like clicks or key presses come in. If a transition gets interrupted by the user (for example, by typing multiple characters in a row), React will throw out the stale rendering work that wasn’t finished and render only the latest update.

* `useTransition`: a Hook to start transitions, including a value to track the pending state.
* `startTransition`: a method to start transitions when the Hook cannot be used.

Transitions will opt in to concurrent rendering, which allows the update to be interrupted. If the content re-suspends, transitions also tell React to continue showing the current content while rendering the transition content in the background (see the [Suspense RFC](https://github.com/reactjs/rfcs/blob/main/text/0213-suspense-in-react-18.md) for more info).

[See docs for transitions here](/reference/react/useTransition).

### New Suspense Features[](#new-suspense-features "Link for New Suspense Features ")

Suspense lets you declaratively specify the loading state for a part of the component tree if it’s not yet ready to be displayed:

```
<Suspense fallback={<Spinner />}>

  <Comments />

</Suspense>
```

Suspense makes the “UI loading state” a first-class declarative concept in the React programming model. This lets us build higher-level features on top of it.

We introduced a limited version of Suspense several years ago. However, the only supported use case was code splitting with React.lazy, and it wasn’t supported at all when rendering on the server.

In React 18, we’ve added support for Suspense on the server and expanded its capabilities using concurrent rendering features.

Suspense in React 18 works best when combined with the transition API. If you suspend during a transition, React will prevent already-visible content from being replaced by a fallback. Instead, React will delay the render until enough data has loaded to prevent a bad loading state.

For more, see the RFC for [Suspense in React 18](https://github.com/reactjs/rfcs/blob/main/text/0213-suspense-in-react-18.md).

### New Client and Server Rendering APIs[](#new-client-and-server-rendering-apis "Link for New Client and Server Rendering APIs ")

In this release we took the opportunity to redesign the APIs we expose for rendering on the client and server. These changes allow users to continue using the old APIs in React 17 mode while they upgrade to the new APIs in React 18.

#### React DOM Client[](#react-dom-client "Link for React DOM Client ")

These new APIs are now exported from `react-dom/client`:

* `createRoot`: New method to create a root to `render` or `unmount`. Use it instead of `ReactDOM.render`. New features in React 18 don’t work without it.
* `hydrateRoot`: New method to hydrate a server rendered application. Use it instead of `ReactDOM.hydrate` in conjunction with the new React DOM Server APIs. New features in React 18 don’t work without it.

Both `createRoot` and `hydrateRoot` accept a new option called `onRecoverableError` in case you want to be notified when React recovers from errors during rendering or hydration for logging. By default, React will use [`reportError`](https://developer.mozilla.org/en-US/docs/Web/API/reportError), or `console.error` in the older browsers.

[See docs for React DOM Client here](/reference/react-dom/client).

#### React DOM Server[](#react-dom-server "Link for React DOM Server ")

These new APIs are now exported from `react-dom/server` and have full support for streaming Suspense on the server:

* `renderToPipeableStream`: for streaming in Node environments.
* `renderToReadableStream`: for modern edge runtime environments, such as Deno and Cloudflare workers.

The existing `renderToString` method keeps working but is discouraged.

[See docs for React DOM Server here](/reference/react-dom/server).

### New Strict Mode Behaviors[](#new-strict-mode-behaviors "Link for New Strict Mode Behaviors ")

In the future, we’d like to add a feature that allows React to add and remove sections of the UI while preserving state. For example, when a user tabs away from a screen and back, React should be able to immediately show the previous screen. To do this, React would unmount and remount trees using the same component state as before.

This feature will give React apps better performance out-of-the-box, but requires components to be resilient to effects being mounted and destroyed multiple times. Most effects will work without any changes, but some effects assume they are only mounted or destroyed once.

To help surface these issues, React 18 introduces a new development-only check to Strict Mode. This new check will automatically unmount and remount every component, whenever a component mounts for the first time, restoring the previous state on the second mount.

Before this change, React would mount the component and create the effects:

```
* React mounts the component.

  * Layout effects are created.

  * Effects are created.
```

With Strict Mode in React 18, React will simulate unmounting and remounting the component in development mode:

```
* React mounts the component.

  * Layout effects are created.

  * Effects are created.

* React simulates unmounting the component.

  * Layout effects are destroyed.

  * Effects are destroyed.

* React simulates mounting the component with the previous state.

  * Layout effects are created.

  * Effects are created.
```

[See docs for ensuring reusable state here](/reference/react/StrictMode#fixing-bugs-found-by-re-running-effects-in-development).

### New Hooks[](#new-hooks "Link for New Hooks ")

#### useId[](#useid "Link for useId ")

`useId` is a new Hook for generating unique IDs on both the client and server, while avoiding hydration mismatches. It is primarily useful for component libraries integrating with accessibility APIs that require unique IDs. This solves an issue that already exists in React 17 and below, but it’s even more important in React 18 because of how the new streaming server renderer delivers HTML out-of-order. [See docs here](/reference/react/useId).

> Note
>
> `useId` is **not** for generating [keys in a list](/learn/rendering-lists#where-to-get-your-key). Keys should be generated from your data.

#### useTransition[](#usetransition "Link for useTransition ")

`useTransition` and `startTransition` let you mark some state updates as not urgent. Other state updates are considered urgent by default. React will allow urgent state updates (for example, updating a text input) to interrupt non-urgent state updates (for example, rendering a list of search results). [See docs here](/reference/react/useTransition).

#### useDeferredValue[](#usedeferredvalue "Link for useDeferredValue ")

`useDeferredValue` lets you defer re-rendering a non-urgent part of the tree. It is similar to debouncing, but has a few advantages compared to it. There is no fixed time delay, so React will attempt the deferred render right after the first render is reflected on the screen. The deferred render is interruptible and doesn’t block user input. [See docs here](/reference/react/useDeferredValue).

#### useSyncExternalStore[](#usesyncexternalstore "Link for useSyncExternalStore ")

`useSyncExternalStore` is a new Hook that allows external stores to support concurrent reads by forcing updates to the store to be synchronous. It removes the need for useEffect when implementing subscriptions to external data sources, and is recommended for any library that integrates with state external to React. [See docs here](/reference/react/useSyncExternalStore).

> Note
>
> `useSyncExternalStore` is intended to be used by libraries, not application code.

#### useInsertionEffect[](#useinsertioneffect "Link for useInsertionEffect ")

`useInsertionEffect` is a new Hook that allows CSS-in-JS libraries to address performance issues of injecting styles in render. Unless you’ve already built a CSS-in-JS library we don’t expect you to ever use this. This Hook will run after the DOM is mutated, but before layout effects read the new layout. This solves an issue that already exists in React 17 and below, but is even more important in React 18 because React yields to the browser during concurrent rendering, giving it a chance to recalculate layout. [See docs here](/reference/react/useInsertionEffect).

> Note
>
> `useInsertionEffect` is intended to be used by libraries, not application code.

## How to Upgrade[](#how-to-upgrade "Link for How to Upgrade ")

See [How to Upgrade to React 18](/blog/2022/03/08/react-18-upgrade-guide) for step-by-step instructions and a full list of breaking and notable changes.

## Changelog[](#changelog "Link for Changelog ")

### React[](#react "Link for React ")

### React DOM[](#react-dom "Link for React DOM ")

### React DOM Server[](#react-dom-server-1 "Link for React DOM Server ")

### React DOM Test Utils[](#react-dom-test-utils "Link for React DOM Test Utils ")

* Throw when `act` is used in production. ([#21686](https://github.com/facebook/react/pull/21686) by [@acdlite](https://github.com/acdlite))
* Support disabling spurious act warnings with `global.IS_REACT_ACT_ENVIRONMENT`. ([#22561](https://github.com/facebook/react/pull/22561) by [@acdlite](https://github.com/acdlite))
* Expand act warning to cover all APIs that might schedule React work. ([#22607](https://github.com/facebook/react/pull/22607) by [@acdlite](https://github.com/acdlite))
* Make `act` batch updates. ([#21797](https://github.com/facebook/react/pull/21797) by [@acdlite](https://github.com/acdlite))
* Remove warning for dangling passive effects. ([#22609](https://github.com/facebook/react/pull/22609) by [@acdlite](https://github.com/acdlite))

### React Refresh[](#react-refresh "Link for React Refresh ")

* Track late-mounted roots in Fast Refresh. ([#22740](https://github.com/facebook/react/pull/22740) by [@anc95](https://github.com/anc95))
* Add `exports` field to `package.json`. ([#23087](https://github.com/facebook/react/pull/23087) by [@otakustay](https://github.com/otakustay))

### Server Components (Experimental)[](#server-components-experimental "Link for Server Components (Experimental) ")

* Add Server Context support. ([#23244](https://github.com/facebook/react/pull/23244) by [@salazarm](https://github.com/salazarm))
* Add `lazy` support. ([#24068](https://github.com/facebook/react/pull/24068) by [@gnoff](https://github.com/gnoff))
* Update webpack plugin for webpack 5 ([#22739](https://github.com/facebook/react/pull/22739) by [@michenly](https://github.com/michenly))
* Fix a mistake in the Node loader. ([#22537](https://github.com/facebook/react/pull/22537) by [@btea](https://github.com/btea))
* Use `globalThis` instead of `window` for edge environments. ([#22777](https://github.com/facebook/react/pull/22777) by [@huozhi](https://github.com/huozhi))

[PreviousReact Labs: What We've Been Working On – June 2022](/blog/2022/06/15/react-labs-what-we-have-been-working-on-june-2022)

[NextHow to Upgrade to React 18](/blog/2022/03/08/react-18-upgrade-guide)

***

----
url: https://legacy.reactjs.org/docs/fragments.html
----

> These docs are old and won’t be updated. Go to [react.dev](https://react.dev/) for the new React docs.
>
> These new documentation pages teach modern React:
>
> * [`<Fragment>`](https://react.dev/reference/react/Fragment)

A common pattern in React is for a component to return multiple elements. Fragments let you group a list of children without adding extra nodes to the DOM.

```
render() {
  return (
    <React.Fragment>
      <ChildA />
      <ChildB />
      <ChildC />
    </React.Fragment>
  );
}
```

There is also a new [short syntax](#short-syntax) for declaring them.

## [](#motivation)Motivation

A common pattern is for a component to return a list of children. Take this example React snippet:

```
class Table extends React.Component {
  render() {
    return (
      <table>
        <tr>
          <Columns />
        </tr>
      </table>
    );
  }
}
```

`<Columns />` would need to return multiple `<td>` elements in order for the rendered HTML to be valid. If a parent div was used inside the `render()` of `<Columns />`, then the resulting HTML will be invalid.

```
class Columns extends React.Component {
  render() {
    return (
      <div>
        <td>Hello</td>
        <td>World</td>
      </div>
    );
  }
}
```

results in a `<Table />` output of:

```
<table>
  <tr>
    <div>
      <td>Hello</td>
      <td>World</td>
    </div>
  </tr>
</table>
```

Fragments solve this problem.

## [](#usage)Usage

```
class Columns extends React.Component {
  render() {
    return (
      <React.Fragment>        <td>Hello</td>
        <td>World</td>
      </React.Fragment>    );
  }
}
```

which results in a correct `<Table />` output of:

```
<table>
  <tr>
    <td>Hello</td>
    <td>World</td>
  </tr>
</table>
```

### [](#short-syntax)Short Syntax

There is a new, shorter syntax you can use for declaring fragments. It looks like empty tags:

```
class Columns extends React.Component {
  render() {
    return (
      <>        <td>Hello</td>
        <td>World</td>
      </>    );
  }
}
```

You can use `<></>` the same way you’d use any other element except that it doesn’t support keys or attributes.

### [](#keyed-fragments)Keyed Fragments

Fragments declared with the explicit `<React.Fragment>` syntax may have keys. A use case for this is mapping a collection to an array of fragments — for example, to create a description list:

```
function Glossary(props) {
  return (
    <dl>
      {props.items.map(item => (
        // Without the `key`, React will fire a key warning
        <React.Fragment key={item.id}>
          <dt>{item.term}</dt>
          <dd>{item.description}</dd>
        </React.Fragment>
      ))}
    </dl>
  );
}
```

`key` is the only attribute that can be passed to `Fragment`. In the future, we may add support for additional attributes, such as event handlers.

### [](#live-demo)Live Demo

You can try out the new JSX fragment syntax with this [CodePen](https://codepen.io/reactjs/pen/VrEbjE?editors=1000).

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/fragments.md)

----
url: https://legacy.reactjs.org/blog/2018/08/01/react-v-16-4-2.html
----

August 01, 2018 by [Dan Abramov](https://twitter.com/dan_abramov)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

We discovered a minor vulnerability that might affect some apps using ReactDOMServer. We are releasing a patch version for every affected React minor release so that you can upgrade with no friction. Read on for more details.

## [](#short-description)Short Description

Today, we are releasing a fix for a vulnerability we discovered in the `react-dom/server` implementation. It was introduced with the version 16.0.0 and has existed in all subsequent releases until today.

This vulnerability **can only affect some server-rendered React apps.** Purely client-rendered apps are **not** affected. Additionally, we expect that most server-rendered apps don’t contain the vulnerable pattern described below. Nevertheless, we recommend to follow the mitigation instructions at the earliest opportunity.

While we were investigating this vulnerability, we found similar vulnerabilities in a few other popular front-end libraries. We have coordinated this release together with [Vue](https://github.com/vuejs/vue/releases/tag/v2.5.17) and [Preact](https://github.com/developit/preact-render-to-string/releases/tag/3.7.1) releases fixing the same issue. The tracking number for this vulnerability is `CVE-2018-6341`.

## [](#mitigation)Mitigation

**We have prepared a patch release with a fix for every affected minor version.**

### [](#160x)16.0.x

If you’re using `react-dom/server` with this version:

* `react-dom@16.0.0`

Update to this version instead:

* `react-dom@16.0.1` **(contains the mitigation)**

### [](#161x)16.1.x

If you’re using `react-dom/server` with one of these versions:

* `react-dom@16.1.0`
* `react-dom@16.1.1`

Update to this version instead:

* `react-dom@16.1.2` **(contains the mitigation)**

### [](#162x)16.2.x

If you’re using `react-dom/server` with this version:

* `react-dom@16.2.0`

Update to this version instead:

* `react-dom@16.2.1` **(contains the mitigation)**

### [](#163x)16.3.x

If you’re using `react-dom/server` with one of these versions:

* `react-dom@16.3.0`
* `react-dom@16.3.1`
* `react-dom@16.3.2`

Update to this version instead:

* `react-dom@16.3.3` **(contains the mitigation)**

### [](#164x)16.4.x

If you’re using `react-dom/server` with one of these versions:

* `react-dom@16.4.0`
* `react-dom@16.4.1`

Update to this version instead:

* `react-dom@16.4.2` **(contains the mitigation)**

If you’re using a newer version of `react-dom`, no action is required.

Note that only the `react-dom` package needs to be updated.

## [](#detailed-description)Detailed Description

Your app might be affected by this vulnerability only if both of these two conditions are true:

* Your app is **being rendered to HTML using [ReactDOMServer API](/docs/react-dom-server.html)**, and
* Your app **includes a user-supplied attribute name in an HTML tag.**

Specifically, the vulnerable pattern looks like this:

```
let props = {};
props[userProvidedData] = "hello";let element = <div {...props} />;
let html = ReactDOMServer.renderToString(element);
```

In order to exploit it, the attacker would need to craft a special attribute name that triggers an [XSS](https://en.wikipedia.org/wiki/Cross-site_scripting) vulnerability. For example:

```
let userProvidedData = '></div><script>alert("hi")</script>';
```

In the vulnerable versions of `react-dom/server`, the output would let the attacker inject arbitrary markup:

```
<div ></div><script>alert("hi")</script>
```

In the versions after the vulnerability was [fixed](https://github.com/facebook/react/pull/13302) (and before it was introduced), attributes with invalid names are skipped:

```
<div></div>
```

You would also see a warning about an invalid attribute name.

Note that **we expect attribute names based on user input to be very rare in practice.** It doesn’t serve any common practical use case, and has other potential security implications that React can’t guard against.

## [](#installation)Installation

React v16.4.2 is available on the npm registry.

To install React 16 with Yarn, run:

```
yarn add react@^16.4.2 react-dom@^16.4.2
```

To install React 16 with npm, run:

```
npm install --save react@^16.4.2 react-dom@^16.4.2
```

We also provide UMD builds of React via a CDN:

```
<script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
```

Refer to the documentation for [detailed installation instructions](/docs/installation.html).

## [](#changelog)Changelog

### [](#react-dom-server)React DOM Server

* Fix a potential XSS vulnerability when the attacker controls an attribute name (`CVE-2018-6341`). This fix is available in the latest `react-dom@16.4.2`, as well as in previous affected minor versions: `react-dom@16.0.1`, `react-dom@16.1.2`, `react-dom@16.2.1`, and `react-dom@16.3.3`. ([@gaearon](https://github.com/gaearon) in [#13302](https://github.com/facebook/react/pull/13302))
* Fix a crash in the server renderer when an attribute is called `hasOwnProperty`. This fix is only available in `react-dom@16.4.2`. ([@gaearon](https://github.com/gaearon) in [#13303](https://github.com/facebook/react/pull/13303))

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2018-08-01-react-v-16-4-2.md)

----
url: https://legacy.reactjs.org/docs/testing-environments.html
----

This document goes through the factors that can affect your environment and recommendations for some scenarios.

### [](#test-runners)Test runners

Test runners like [Jest](https://jestjs.io/), [mocha](https://mochajs.org/), [ava](https://github.com/avajs/ava) let you write test suites as regular JavaScript, and run them as part of your development process. Additionally, test suites are run as part of continuous integration.

* Jest is widely compatible with React projects, supporting features like mocked [modules](#mocking-modules) and [timers](#mocking-timers), and [`jsdom`](#mocking-a-rendering-surface) support. **If you use Create React App, [Jest is already included out of the box](https://facebook.github.io/create-react-app/docs/running-tests) with useful defaults.**
* Libraries like [mocha](https://mochajs.org/#running-mocha-in-the-browser) work well in real browser environments, and could help for tests that explicitly need it.
* End-to-end tests are used for testing longer flows across multiple pages, and require a [different setup](#end-to-end-tests-aka-e2e-tests).

### [](#mocking-a-rendering-surface)Mocking a rendering surface

Tests often run in an environment without access to a real rendering surface like a browser. For these environments, we recommend simulating a browser with [`jsdom`](https://github.com/jsdom/jsdom), a lightweight browser implementation that runs inside Node.js.

In most cases, jsdom behaves like a regular browser would, but doesn’t have features like [layout and navigation](https://github.com/jsdom/jsdom#unimplemented-parts-of-the-web-platform). This is still useful for most web-based component tests, since it runs quicker than having to start up a browser for each test. It also runs in the same process as your tests, so you can write code to examine and assert on the rendered DOM.

Just like in a real browser, jsdom lets us model user interactions; tests can dispatch events on DOM nodes, and then observe and assert on the side effects of these actions [(example)](/docs/testing-recipes.html#events).

A large portion of UI tests can be written with the above setup: using Jest as a test runner, rendered to jsdom, with user interactions specified as sequences of browser events, powered by the `act()` helper [(example)](/docs/testing-recipes.html). For example, a lot of React’s own tests are written with this combination.

If you’re writing a library that tests mostly browser-specific behavior, and requires native browser behavior like layout or real inputs, you could use a framework like [mocha.](https://mochajs.org/)

In an environment where you *can’t* simulate a DOM (e.g. testing React Native components on Node.js), you could use [event simulation helpers](/docs/test-utils.html#simulate) to simulate interactions with elements. Alternately, you could use the `fireEvent` helper from [`@testing-library/react-native`](https://testing-library.com/docs/react-native-testing-library/intro).

Frameworks like [Cypress](https://www.cypress.io/), [puppeteer](https://github.com/GoogleChrome/puppeteer) and [webdriver](https://www.seleniumhq.org/projects/webdriver/) are useful for running [end-to-end tests](#end-to-end-tests-aka-e2e-tests).

### [](#mocking-functions)Mocking functions

When writing tests, we’d like to mock out the parts of our code that don’t have equivalents inside our testing environment (e.g. checking `navigator.onLine` status inside Node.js). Tests could also spy on some functions, and observe how other parts of the test interact with them. It is then useful to be able to selectively mock these functions with test-friendly versions.

This is especially useful for data fetching. It is usually preferable to use “fake” data for tests to avoid the slowness and flakiness due to fetching from real API endpoints [(example)](/docs/testing-recipes.html#data-fetching). This helps make the tests predictable. Libraries like [Jest](https://jestjs.io/) and [sinon](https://sinonjs.org/), among others, support mocked functions. For end-to-end tests, mocking network can be more difficult, but you might also want to test the real API endpoints in them anyway.

### [](#mocking-modules)Mocking modules

Some components have dependencies for modules that may not work well in test environments, or aren’t essential to our tests. It can be useful to selectively mock these modules out with suitable replacements [(example)](/docs/testing-recipes.html#mocking-modules).

On Node.js, runners like Jest [support mocking modules](https://jestjs.io/docs/en/manual-mocks). You could also use libraries like [`mock-require`](https://www.npmjs.com/package/mock-require).

### [](#mocking-timers)Mocking timers

Components might be using time-based functions like `setTimeout`, `setInterval`, or `Date.now`. In testing environments, it can be helpful to mock these functions out with replacements that let you manually “advance” time. This is great for making sure your tests run fast! Tests that are dependent on timers would still resolve in order, but quicker [(example)](/docs/testing-recipes.html#timers). Most frameworks, including [Jest](https://jestjs.io/docs/en/timer-mocks), [sinon](https://sinonjs.org/releases/latest/fake-timers) and [lolex](https://github.com/sinonjs/lolex), let you mock timers in your tests.

Sometimes, you may not want to mock timers. For example, maybe you’re testing an animation, or interacting with an endpoint that’s sensitive to timing (like an API rate limiter). Libraries with timer mocks let you enable and disable them on a per test/suite basis, so you can explicitly choose how these tests would run.

### [](#end-to-end-tests-aka-e2e-tests)End-to-end tests

End-to-end tests are useful for testing longer workflows, especially when they’re critical to your business (such as payments or signups). For these tests, you’d probably want to test how a real browser renders the whole app, fetches data from the real API endpoints, uses sessions and cookies, navigates between different links. You might also likely want to make assertions not just on the DOM state, but on the backing data as well (e.g. to verify whether the updates have been persisted to the database).

In this scenario, you would use a framework like [Cypress](https://www.cypress.io/), [Playwright](https://playwright.dev) or a library like [Puppeteer](https://pptr.dev/) so you can navigate between multiple routes and assert on side effects not just in the browser, but potentially on the backend as well.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/testing-environments.md)

* Previous article

  [Testing Recipes](/docs/testing-recipes.html)

----
url: https://legacy.reactjs.org/docs/design-principles.html
----

We wrote this document so that you have a better idea of how we decide what React does and what React doesn’t do, and what our development philosophy is like. While we are excited to see community contributions, we are not likely to choose a path that violates one or more of these principles.

> **Note:**
>
> This document assumes a strong understanding of React. It describes the design principles of *React itself*, not React components or applications.
>
> For an introduction to React, check out [Thinking in React](/docs/thinking-in-react.html) instead.

### [](#composition)Composition

The key feature of React is composition of components. Components written by different people should work well together. It is important to us that you can add functionality to a component without causing rippling changes throughout the codebase.

For example, it should be possible to introduce some local state into a component without changing any of the components using it. Similarly, it should be possible to add some initialization and teardown code to any component when necessary.

There is nothing “bad” about using state or lifecycle methods in components. Like any powerful feature, they should be used in moderation, but we have no intention to remove them. On the contrary, we think they are integral parts of what makes React useful. We might enable [more functional patterns](https://github.com/reactjs/react-future/tree/master/07%20-%20Returning%20State) in the future, but both local state and lifecycle methods will be a part of that model.

Components are often described as “just functions” but in our view they need to be more than that to be useful. In React, components describe any composable behavior, and this includes rendering, lifecycle, and state. Some external libraries like [Relay](https://facebook.github.io/relay/) augment components with other responsibilities such as describing data dependencies. It is possible that those ideas might make it back into React too in some form.

### [](#common-abstraction)Common Abstraction

In general we [resist adding features](https://www.youtube.com/watch?v=4anAwXYqLG8) that can be implemented in userland. We don’t want to bloat your apps with useless library code. However, there are exceptions to this.

For example, if React didn’t provide support for local state or lifecycle methods, people would create custom abstractions for them. When there are multiple abstractions competing, React can’t enforce or take advantage of the properties of either of them. It has to work with the lowest common denominator.

This is why sometimes we add features to React itself. If we notice that many components implement a certain feature in incompatible or inefficient ways, we might prefer to bake it into React. We don’t do it lightly. When we do it, it’s because we are confident that raising the abstraction level benefits the whole ecosystem. State, lifecycle methods, cross-browser event normalization are good examples of this.

We always discuss such improvement proposals with the community. You can find some of those discussions by the [“big picture”](https://github.com/facebook/react/issues?q=is:open+is:issue+label:%22Type:+Big+Picture%22) label on the React issue tracker.

### [](#escape-hatches)Escape Hatches

React is pragmatic. It is driven by the needs of the products written at Facebook. While it is influenced by some paradigms that are not yet fully mainstream such as functional programming, staying accessible to a wide range of developers with different skills and experience levels is an explicit goal of the project.

If we want to deprecate a pattern that we don’t like, it is our responsibility to consider all existing use cases for it and [educate the community about the alternatives](/blog/2016/07/13/mixins-considered-harmful.html) before we deprecate it. If some pattern that is useful for building apps is hard to express in a declarative way, we will [provide an imperative API](/docs/more-about-refs.html) for it. If we can’t figure out a perfect API for something that we found necessary in many apps, we will [provide a temporary subpar working API](/docs/legacy-context.html) as long as it is possible to get rid of it later and it leaves the door open for future improvements.

### [](#stability)Stability

We value API stability. At Facebook, we have more than 50 thousand components using React. Many other companies, including [Twitter](https://twitter.com/) and [Airbnb](https://www.airbnb.com/), are also heavy users of React. This is why we are usually reluctant to change public APIs or behavior.

However we think stability in the sense of “nothing changes” is overrated. It quickly turns into stagnation. Instead, we prefer the stability in the sense of “It is heavily used in production, and when something changes, there is a clear (and preferably automated) migration path.”

When we deprecate a pattern, we study its internal usage at Facebook and add deprecation warnings. They let us assess the impact of the change. Sometimes we back out if we see that it is too early, and we need to think more strategically about getting the codebases to the point where they are ready for this change.

If we are confident that the change is not too disruptive and the migration strategy is viable for all use cases, we release the deprecation warning to the open source community. We are closely in touch with many users of React outside of Facebook, and we monitor popular open source projects and guide them in fixing those deprecations.

Given the sheer size of the Facebook React codebase, successful internal migration is often a good indicator that other companies won’t have problems either. Nevertheless sometimes people point out additional use cases we haven’t thought of, and we add escape hatches for them or rethink our approach.

We don’t deprecate anything without a good reason. We recognize that sometimes deprecations warnings cause frustration but we add them because deprecations clean up the road for the improvements and new features that we and many people in the community consider valuable.

For example, we added a [warning about unknown DOM props](/warnings/unknown-prop.html) in React 15.2.0. Many projects were affected by this. However fixing this warning is important so that we can introduce the support for [custom attributes](https://github.com/facebook/react/issues/140) to React. There is a reason like this behind every deprecation that we add.

When we add a deprecation warning, we keep it for the rest of the current major version, and [change the behavior in the next major version](/blog/2016/02/19/new-versioning-scheme.html). If there is a lot of repetitive manual work involved, we release a [codemod](https://www.youtube.com/watch?v=d0pOgY8__JM) script that automates most of the change. Codemods enable us to move forward without stagnation in a massive codebase, and we encourage you to use them as well.

You can find the codemods that we released in the [react-codemod](https://github.com/reactjs/react-codemod) repository.

### [](#interoperability)Interoperability

We place high value in interoperability with existing systems and gradual adoption. Facebook has a massive non-React codebase. Its website uses a mix of a server-side component system called XHP, internal UI libraries that came before React, and React itself. It is important to us that any product team can [start using React for a small feature](https://www.youtube.com/watch?v=BF58ZJ1ZQxY) rather than rewrite their code to bet on it.

This is why React provides escape hatches to work with mutable models, and tries to work well together with other UI libraries. You can wrap an existing imperative UI into a declarative component, and vice versa. This is crucial for gradual adoption.

### [](#scheduling)Scheduling

Even when your components are described as functions, when you use React you don’t call them directly. Every component returns a [description of what needs to be rendered](/blog/2015/12/18/react-components-elements-and-instances.html#elements-describe-the-tree), and that description may include both user-written components like `<LikeButton>` and platform-specific components like `<div>`. It is up to React to “unroll” `<LikeButton>` at some point in the future and actually apply changes to the UI tree according to the render results of the components recursively.

This is a subtle distinction but a powerful one. Since you don’t call that component function but let React call it, it means React has the power to delay calling it if necessary. In its current implementation React walks the tree recursively and calls render functions of the whole updated tree during a single tick. However in the future it might start [delaying some updates to avoid dropping frames](https://github.com/facebook/react/issues/6170).

This is a common theme in React design. Some popular libraries implement the “push” approach where computations are performed when the new data is available. React, however, sticks to the “pull” approach where computations can be delayed until necessary.

React is not a generic data processing library. It is a library for building user interfaces. We think that it is uniquely positioned in an app to know which computations are relevant right now and which are not.

If something is offscreen, we can delay any logic related to it. If data is arriving faster than the frame rate, we can coalesce and batch updates. We can prioritize work coming from user interactions (such as an animation caused by a button click) over less important background work (such as rendering new content just loaded from the network) to avoid dropping frames.

To be clear, we are not taking advantage of this right now. However the freedom to do something like this is why we prefer to have control over scheduling, and why `setState()` is asynchronous. Conceptually, we think of it as “scheduling an update”.

The control over scheduling would be harder for us to gain if we let the user directly compose views with a “push” based paradigm common in some variations of [Functional Reactive Programming](https://en.wikipedia.org/wiki/Functional_reactive_programming). We want to own the “glue” code.

It is a key goal for React that the amount of the user code that executes before yielding back into React is minimal. This ensures that React retains the capability to schedule and split work in chunks according to what it knows about the UI.

There is an internal joke in the team that React should have been called “Schedule” because React does not want to be fully “reactive”.

### [](#developer-experience)Developer Experience

Providing a good developer experience is important to us.

For example, we maintain [React DevTools](https://github.com/facebook/react/tree/main/packages/react-devtools) which let you inspect the React component tree in Chrome and Firefox. We have heard that it brings a big productivity boost both to the Facebook engineers and to the community.

We also try to go an extra mile to provide helpful developer warnings. For example, React warns you in development if you nest tags in a way that the browser doesn’t understand, or if you make a common typo in the API. Developer warnings and the related checks are the main reason why the development version of React is slower than the production version.

The usage patterns that we see internally at Facebook help us understand what the common mistakes are, and how to prevent them early. When we add new features, we try to anticipate the common mistakes and warn about them.

We are always looking out for ways to improve the developer experience. We love to hear your suggestions and accept your contributions to make it even better.

### [](#debugging)Debugging

When something goes wrong, it is important that you have breadcrumbs to trace the mistake to its source in the codebase. In React, props and state are those breadcrumbs.

If you see something wrong on the screen, you can open React DevTools, find the component responsible for rendering, and then see if the props and state are correct. If they are, you know that the problem is in the component’s `render()` function, or some function that is called by `render()`. The problem is isolated.

If the state is wrong, you know that the problem is caused by one of the `setState()` calls in this file. This, too, is relatively simple to locate and fix because usually there are only a few `setState()` calls in a single file.

If the props are wrong, you can traverse the tree up in the inspector, looking for the component that first “poisoned the well” by passing bad props down.

This ability to trace any UI to the data that produced it in the form of current props and state is very important to React. It is an explicit design goal that state is not “trapped” in closures and combinators, and is available to React directly.

While the UI is dynamic, we believe that synchronous `render()` functions of props and state turn debugging from guesswork into a boring but finite procedure. We would like to preserve this constraint in React even though it makes some use cases, like complex animations, harder.

### [](#configuration)Configuration

We find global runtime configuration options to be problematic.

For example, it is occasionally requested that we implement a function like `React.configure(options)` or `React.register(component)`. However this poses multiple problems, and we are not aware of good solutions to them.

What if somebody calls such a function from a third-party component library? What if one React app embeds another React app, and their desired configurations are incompatible? How can a third-party component specify that it requires a particular configuration? We think that global configuration doesn’t work well with composition. Since composition is central to React, we don’t provide global configuration in code.

We do, however, provide some global configuration on the build level. For example, we provide separate development and production builds. We may also [add a profiling build](https://github.com/facebook/react/issues/6627) in the future, and we are open to considering other build flags.

### [](#beyond-the-dom)Beyond the DOM

We see the value of React in the way it allows us to write components that have fewer bugs and compose together well. DOM is the original rendering target for React but [React Native](https://reactnative.dev/) is just as important both to Facebook and the community.

Being renderer-agnostic is an important design constraint of React. It adds some overhead in the internal representations. On the other hand, any improvements to the core translate across platforms.

Having a single programming model lets us form engineering teams around products instead of platforms. So far the tradeoff has been worth it for us.

### [](#implementation)Implementation

We try to provide elegant APIs where possible. We are much less concerned with the implementation being elegant. The real world is far from perfect, and to a reasonable extent we prefer to put the ugly code into the library if it means the user does not have to write it. When we evaluate new code, we are looking for an implementation that is correct, performant and affords a good developer experience. Elegance is secondary.

We prefer boring code to clever code. Code is disposable and often changes. So it is important that it [doesn’t introduce new internal abstractions unless absolutely necessary](https://youtu.be/4anAwXYqLG8?t=13m9s). Verbose code that is easy to move around, change and remove is preferred to elegant code that is prematurely abstracted and hard to change.

### [](#optimized-for-tooling)Optimized for Tooling

Some commonly used APIs have verbose names. For example, we use `componentDidMount()` instead of `didMount()` or `onMount()`. This is [intentional](https://github.com/reactjs/react-future/issues/40#issuecomment-142442124). The goal is to make the points of interaction with the library highly visible.

In a massive codebase like Facebook, being able to search for uses of specific APIs is very important. We value distinct verbose names, and especially for the features that should be used sparingly. For example, `dangerouslySetInnerHTML` is hard to miss in a code review.

Optimizing for search is also important because of our reliance on [codemods](https://www.youtube.com/watch?v=d0pOgY8__JM) to make breaking changes. We want it to be easy and safe to apply vast automated changes across the codebase, and unique verbose names help us achieve this. Similarly, distinctive names make it easy to write custom [lint rules](https://github.com/yannickcr/eslint-plugin-react) about using React without worrying about potential false positives.

[JSX](/docs/introducing-jsx.html) plays a similar role. While it is not required with React, we use it extensively at Facebook both for aesthetic and pragmatic reasons.

In our codebase, JSX provides an unambiguous hint to the tools that they are dealing with a React element tree. This makes it possible to add build-time optimizations such as [hoisting constant elements](https://babeljs.io/docs/en/babel-plugin-transform-react-constant-elements/), safely lint and codemod internal component usage, and [include JSX source location](https://github.com/facebook/react/pull/6771) into the warnings.

### [](#dogfooding)Dogfooding

We try our best to address the problems raised by the community. However we are likely to prioritize the issues that people are *also* experiencing internally at Facebook. Perhaps counter-intuitively, we think this is the main reason why the community can bet on React.

Heavy internal usage gives us the confidence that React won’t disappear tomorrow. React was created at Facebook to solve its problems. It brings tangible business value to the company and is used in many of its products. [Dogfooding](https://en.wikipedia.org/wiki/Eating_your_own_dog_food) it means that our vision stays sharp and we have a focused direction going forward.

This doesn’t mean that we ignore the issues raised by the community. For example, we added support for [web components](/docs/webcomponents.html) and [SVG](https://github.com/facebook/react/pull/6243) to React even though we don’t rely on either of them internally. We are actively [listening to your pain points](https://github.com/facebook/react/issues/2686) and [address them](/blog/2016/07/11/introducing-reacts-error-code-system.html) to the best of our ability. The community is what makes React special to us, and we are honored to contribute back.

After releasing many open source projects at Facebook, we have learned that trying to make everyone happy at the same time produced projects with poor focus that didn’t grow well. Instead, we found that picking a small audience and focusing on making them happy brings a positive net effect. That’s exactly what we did with React, and so far solving the problems encountered by Facebook product teams has translated well to the open source community.

The downside of this approach is that sometimes we fail to give enough focus to the things that Facebook teams don’t have to deal with, such as the “getting started” experience. We are acutely aware of this, and we are thinking of how to improve in a way that would benefit everyone in the community without making the same mistakes we did with open source projects before.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/design-principles.md)

* Previous article

  [Implementation Notes](/docs/implementation-notes.html)

----
url: https://legacy.reactjs.org/blog/2014/10/17/community-roundup-23.html
----

October 17, 2014 by [Lou Husson](https://twitter.com/loukan42)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

This round-up is a special edition on [Flux](https://facebook.github.io/flux/). If you expect to see diagrams showing arrows that all point in the same direction, you won’t be disappointed!

## [](#react-and-flux-at-forwardjs)React And Flux at ForwardJS

Facebook engineers [Jing Chen](https://github.com/jingc) and [Bill Fisher](https://github.com/fisherwebdev) gave a talk about Flux and React at [ForwardJS](http://forwardjs.com/), and how using an application architecture with a unidirectional data flow helped solve recurring bugs.

# [](#yahoo)Yahoo

Yahoo is converting Yahoo Mail to React and Flux and in the process, they open sourced several components. This will help you get an isomorphic application up and running.

* [Flux Router Component](https://github.com/yahoo/flux-router-component)
* [Dispatchr](https://github.com/yahoo/dispatchr)
* [Fetchr](https://github.com/yahoo/fetchr)
* [Flux Examples](https://github.com/yahoo/flux-examples)

## [](#reflux)Reflux

[Mikael Brassman](https://spoike.ghost.io/) wrote [Reflux](https://github.com/spoike/refluxjs), a library that implements Flux concepts. Note that it diverges significantly from the way we use Flux at Facebook. He explains [the reasons why in a blog post](https://spoike.ghost.io/deconstructing-reactjss-flux/).

[](https://spoike.ghost.io/deconstructing-reactjss-flux/)

## [](#react-and-flux-interview)React and Flux Interview

[Ian Obermiller](http://ianobermiller.com/), engineer at Facebook, [made a lengthy interview](http://ianobermiller.com/blog/2014/09/15/react-and-flux-interview/) on the experience of using React and Flux in order to build probably the biggest React application ever written so far.

> I’ve actually said this many times to my team too, I love React. It’s really great for making these complex applications. One thing that really surprised me with it is that React combined with a sane module system like CommonJS, and making sure that you actually modulize your stuff properly has scaled really well to a team of almost 10 developers working on hundreds of files and tens of thousands of lines of code.
>
> Really, a fairly large code base… stuff just works. You don’t have to worry about mutating, and the state of the DOM just really makes stuff easy. Just conceptually it’s easier just to think about here’s what I have, here’s my data, here’s how it renders, I don’t care about anything else. For most cases that is really simplifying and makes it really fast to do stuff.
>
> [Read the full interview…](http://ianobermiller.com/blog/2014/09/15/react-and-flux-interview/)

## [](#adobes-brackets-project-tree)Adobe’s Brackets Project Tree

[Kevin Dangoor](http://www.kevindangoor.com/) is converting the project tree of [Adobe’s Bracket text editor](http://brackets.io/) to React and Flux. He wrote about his experience [using Flux](http://www.kevindangoor.com/2014/09/intro-to-the-new-brackets-project-tree/).

[](http://www.kevindangoor.com/2014/09/intro-to-the-new-brackets-project-tree/)

## [](#async-requests-with-flux-revisited)Async Requests with Flux Revisited

[Reto Schläpfer](http://www.code-experience.com/the-code-experience/) came back to a Flux project he hasn’t worked on for a month and [saw many ways to improve the way he implemented Flux](http://www.code-experience.com/async-requests-with-react-js-and-flux-revisited/). He summarized his learnings in a blog post.

> The smarter way is to call the Web Api directly from an Action Creator and then make the Api dispatch an event with the request result as a payload. The Store(s) can choose to listen on those request actions and change their state accordingly.
>
> Before I show some updated code snippets, let me explain why this is superior:
>
> * There should be only one channel for all state changes: The Dispatcher. This makes debugging easy because it just requires a single console.log in the dispatcher to observe every single state change trigger.
> * Asynchronously executed callbacks should not leak into Stores. The consequences of it are just too hard to fully foresee. This leads to elusive bugs. Stores should only execute synchronous code. Otherwise they are too hard to understand.
> * Avoiding actions firing other actions makes your app simple. We use the newest Dispatcher implementation from Facebook that does not allow a new dispatch while dispatching. It forces you to do things right.
>
> [Read the full article…](http://www.code-experience.com/async-requests-with-react-js-and-flux-revisited/)

## [](#undo-redo-with-immutable-data-structures)Undo-Redo with Immutable Data Structures

[Ameya Karve](https://github.com/ameyakarve) explained how to use [Mori](https://github.com/swannodette/mori), a library that provides immutable data structures, in order to [implement undo-redo](http://ameyakarve.com/jekyll/update/2014/02/06/Undo-React-Flux-Mori.html). This usually very challenging feature only takes a few lines of code with Flux!

```
undo: function() {
  this.redoStates = Mori.conj(this.redoStates, Mori.first(this.undoStates));
  this.undoStates = Mori.drop(1, this.undoStates);
  this.todosState = Mori.first(this.undoStates);
  this.canUndo = Mori.count(this.undoStates) > 1;
  this.canRedo = true;
  if (Mori.count(this.undoStates) > 1) {
    this.todos = JSON.parse(this.todosState);
  } else {
    this.todos = [];
  }
  this.emit('change');
},
```

## [](#flux-in-practice)Flux in practice

[Gary Chambers](https://twitter.com/garychambers108) wrote a [guide to get started with Flux](https://medium.com/@garychambers108/flux-in-practice-ec08daa9041a). This is a very practical introduction to Flux.

> So, what does it actually mean to write an application in the Flux way? At that moment of inspiration, when faced with an empty text editor, how should you begin? This post follows the process of building a Flux-compliant application from scratch.
>
> [Read the full guide…](https://medium.com/@garychambers108/flux-in-practice-ec08daa9041a)

## [](#components-react-and-flux)Components, React and Flux

[Dan Abramov](https://twitter.com/dan_abramov) working at Stampsy made a talk about React and Flux. It’s a very good overview of the concepts at play.

## [](#react-and-flux)React and Flux

[Christian Alfoni](https://github.com/christianalfoni) wrote an article where [he compares Backbone, Angular and Flux](https://christianalfoni.github.io/javascript/2014/08/20/react-js-and-flux.html) on a simple example that’s representative of a real project he worked on.

> Wow, that was a bit more code! Well, try to think of it like this. In the above examples, if we were to do any changes to the application we would probably have to move things around. In the FLUX example we have considered that from the start.
>
> Any changes to the application is adding, not moving things around. If you need a new store, just add it and make components dependant of it. If you need more views, create a component and use it inside any other component without affecting their current “parent controller or models”.
>
> [Read the full article…](https://christianalfoni.github.io/javascript/2014/08/20/react-js-and-flux.html)

## [](#flux-step-by-step-approach)Flux: Step by Step approach

[Nicola Paolucci](https://github.com/durdn) from Atlassian wrote a great guide to help your getting understand [Flux step by step](https://blogs.atlassian.com/2014/08/flux-architecture-step-by-step/).

[](https://blogs.atlassian.com/2014/08/flux-architecture-step-by-step/)

## [](#delorean-back-to-the-future)DeLorean: Back to the future!

[DeLorean](https://github.com/deloreanjs/delorean) is a tiny Flux pattern implementation developed by [Fatih Kadir Akin](https://github.com/f).

> * Unidirectional data flow, it makes your app logic simpler than MVC
> * Automatically listens to data changes and keeps your data updated
> * Makes data more consistent across your whole application
> * It’s framework agnostic, completely. There’s no view framework dependency
> * Very small, just 4K gzipped
> * Built-in React.js integration, easy to use with Flight.js and Ractive.js and probably all others
> * Improve your UI/data consistency using rollbacks

## [](#facebooks-ios-infrastructure)Facebook’s iOS Infrastructure

Last but not least, Flux and React ideas are not limited to JavaScript inside of the browser. The iOS team at Facebook re-implemented Newsfeed using very similar patterns.

## [](#random-tweet)Random Tweet

> If you build your app with flux, you can swap out React for a canvas or svg view layer and keep 85% of your code. (or the thing after React)
>
> — Ryan Florence (@ryanflorence) [September 3, 2014](https://twitter.com/ryanflorence/status/507309645372076034)

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2014-10-17-community-roundup-23.md)

----
url: https://react.dev/reference/react-dom/flushSync
----

[API Reference](/reference/react)

[APIs](/reference/react-dom)

# flushSync[](#undefined "Link for this heading")

### Pitfall

Using `flushSync` is uncommon and can hurt the performance of your app.

`flushSync` lets you force React to flush any updates inside the provided callback synchronously. This ensures that the DOM is updated immediately.

```
flushSync(callback)
```

* [Reference](#reference)
  * [`flushSync(callback)`](#flushsync)
* [Usage](#usage)
  * [Flushing updates for third-party integrations](#flushing-updates-for-third-party-integrations)
* [Troubleshooting](#troubleshooting)
  * [I’m getting an error: “flushSync was called from inside a lifecycle method”](#im-getting-an-error-flushsync-was-called-from-inside-a-lifecycle-method)

***

## Reference[](#reference "Link for Reference ")

### `flushSync(callback)`[](#flushsync "Link for this heading")

Call `flushSync` to force React to flush any pending work and update the DOM synchronously.

```
import { flushSync } from 'react-dom';



flushSync(() => {

  setSomething(123);

});
```

***

## Usage[](#usage "Link for Usage ")

### Flushing updates for third-party integrations[](#flushing-updates-for-third-party-integrations "Link for Flushing updates for third-party integrations ")

When integrating with third-party code such as browser APIs or UI libraries, it may be necessary to force React to flush updates. Use `flushSync` to force React to flush any state updates inside the callback synchronously:

```
flushSync(() => {

  setSomething(123);

});

// By this line, the DOM is updated.
```

This ensures that, by the time the next line of code runs, React has already updated the DOM.

**Using `flushSync` is uncommon, and using it often can significantly hurt the performance of your app.** If your app only uses React APIs, and does not integrate with third-party libraries, `flushSync` should be unnecessary.

However, it can be helpful for integrating with third-party code like browser APIs.

Some browser APIs expect results inside of callbacks to be written to the DOM synchronously, by the end of the callback, so the browser can do something with the rendered DOM. In most cases, React handles this for you automatically. But in some cases it may be necessary to force a synchronous update.

For example, the browser `onbeforeprint` API allows you to change the page immediately before the print dialog opens. This is useful for applying custom print styles that allow the document to display better for printing. In the example below, you use `flushSync` inside of the `onbeforeprint` callback to immediately “flush” the React state to the DOM. Then, by the time the print dialog opens, `isPrinting` displays “yes”:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useEffect } from 'react';
import { flushSync } from 'react-dom';

export default function PrintApp() {
  const [isPrinting, setIsPrinting] = useState(false);

  useEffect(() => {
    function handleBeforePrint() {
      flushSync(() => {
        setIsPrinting(true);
      })
    }

    function handleAfterPrint() {
      setIsPrinting(false);
    }

    window.addEventListener('beforeprint', handleBeforePrint);
    window.addEventListener('afterprint', handleAfterPrint);
    return () => {
      window.removeEventListener('beforeprint', handleBeforePrint);
      window.removeEventListener('afterprint', handleAfterPrint);
    }
  }, []);

  return (
    <>
      <h1>isPrinting: {isPrinting ? 'yes' : 'no'}</h1>
      <button onClick={() => window.print()}>
        Print
      </button>
    </>
  );
}
```

Without `flushSync`, the print dialog will display `isPrinting` as “no”. This is because React batches the updates asynchronously and the print dialog is displayed before the state is updated.

### Pitfall

`flushSync` can significantly hurt performance, and may unexpectedly force pending Suspense boundaries to show their fallback state.

Most of the time, `flushSync` can be avoided, so use `flushSync` as a last resort.

***

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### I’m getting an error: “flushSync was called from inside a lifecycle method”[](#im-getting-an-error-flushsync-was-called-from-inside-a-lifecycle-method "Link for I’m getting an error: “flushSync was called from inside a lifecycle method” ")

React cannot `flushSync` in the middle of a render. If you do, it will noop and warn:

Console

Warning: flushSync was called from inside a lifecycle method. React cannot flush when React is already rendering. Consider moving this call to a scheduler task or micro task.

This includes calling `flushSync` inside:

* rendering a component.
* `useLayoutEffect` or `useEffect` hooks.
* Class component lifecycle methods.

For example, calling `flushSync` in an Effect will noop and warn:

```
import { useEffect } from 'react';

import { flushSync } from 'react-dom';



function MyComponent() {

  useEffect(() => {

    // 🚩 Wrong: calling flushSync inside an effect

    flushSync(() => {

      setSomething(newValue);

    });

  }, []);



  return <div>{/* ... */}</div>;

}
```

To fix this, you usually want to move the `flushSync` call to an event:

```
function handleClick() {

  // ✅ Correct: flushSync in event handlers is safe

  flushSync(() => {

    setSomething(newValue);

  });

}
```

If it’s difficult to move to an event, you can defer `flushSync` in a microtask:

```
useEffect(() => {

  // ✅ Correct: defer flushSync to a microtask

  queueMicrotask(() => {

    flushSync(() => {

      setSomething(newValue);

    });

  });

}, []);
```

This will allow the current render to finish and schedule another syncronous render to flush the updates.

### Pitfall

`flushSync` can significantly hurt performance, but this particular pattern is even worse for performance. Exhaust all other options before calling `flushSync` in a microtask as an escape hatch.

[PreviouscreatePortal](/reference/react-dom/createPortal)

[Nextpreconnect](/reference/react-dom/preconnect)

***

----
url: https://18.react.dev/reference/react-dom/server
----

[API Reference](/reference/react)

# Server React DOM APIs[](#undefined "Link for this heading")

The `react-dom/server` APIs let you render React components to HTML on the server. These APIs are only used on the server at the top level of your app to generate the initial HTML. A [framework](/learn/start-a-new-react-project#production-grade-react-frameworks) may call them for you. Most of your components don’t need to import or use them.

***

## Server APIs for Node.js Streams[](#server-apis-for-nodejs-streams "Link for Server APIs for Node.js Streams ")

These methods are only available in the environments with [Node.js Streams:](https://nodejs.org/api/stream.html)

* [`renderToPipeableStream`](/reference/react-dom/server/renderToPipeableStream) renders a React tree to a pipeable [Node.js Stream.](https://nodejs.org/api/stream.html)
* [`renderToStaticNodeStream`](/reference/react-dom/server/renderToStaticNodeStream) renders a non-interactive React tree to a [Node.js Readable Stream.](https://nodejs.org/api/stream.html#readable-streams)

***

## Server APIs for Web Streams[](#server-apis-for-web-streams "Link for Server APIs for Web Streams ")

These methods are only available in the environments with [Web Streams](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API), which includes browsers, Deno, and some modern edge runtimes:

* [`renderToReadableStream`](/reference/react-dom/server/renderToReadableStream) renders a React tree to a [Readable Web Stream.](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream)

***

## Server APIs for non-streaming environments[](#server-apis-for-non-streaming-environments "Link for Server APIs for non-streaming environments ")

These methods can be used in the environments that don’t support streams:

* [`renderToString`](/reference/react-dom/server/renderToString) renders a React tree to a string.
* [`renderToStaticMarkup`](/reference/react-dom/server/renderToStaticMarkup) renders a non-interactive React tree to a string.

They have limited functionality compared to the streaming APIs.

***

## Deprecated server APIs[](#deprecated-server-apis "Link for Deprecated server APIs ")

### Deprecated

These APIs will be removed in a future major version of React.

* [`renderToNodeStream`](/reference/react-dom/server/renderToNodeStream) renders a React tree to a [Node.js Readable stream.](https://nodejs.org/api/stream.html#readable-streams) (Deprecated.)

[PrevioushydrateRoot](/reference/react-dom/client/hydrateRoot)

[NextrenderToNodeStream](/reference/react-dom/server/renderToNodeStream)

***

----
url: https://legacy.reactjs.org/blog/2016/01/12/discontinuing-ie8-support.html
----

January 12, 2016 by [Sophie Alpert](https://sophiebits.com/)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

Since its 2013 release, React has supported all popular browsers, including Internet Explorer 8 and above. We handle normalizing many quirks present in old browser versions, including event system differences, so that your app code doesn’t have to worry about most browser bugs.

Today, Microsoft [discontinued support for older versions of IE](https://www.microsoft.com/en-us/WindowsForBusiness/End-of-IE-support). Starting with React v15, we’re discontinuing React DOM’s support for IE 8. We’ve heard that most React DOM apps already don’t support old versions of Internet Explorer, so this shouldn’t affect many people. This change will help us develop faster and make React DOM even better. (We won’t actively remove IE 8–related code quite yet, but we will deprioritize new bugs that are reported. If you need to support IE 8 we recommend you stay on React v0.14.)

React DOM will continue to support IE 9 and above for the foreseeable future.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2016-01-12-discontinuing-ie8-support.md)

----
url: https://legacy.reactjs.org/blog/2013/10/29/react-v0-5-1.html
----

October 29, 2013 by [Paul O’Shannessy](https://twitter.com/zpao)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

This release focuses on fixing some small bugs that have been uncovered over the past two weeks. I would like to thank everybody involved, specifically members of the community who fixed half of the issues found. Thanks to [Sophie Alpert](https://github.com/sophiebits), [Andrey Popp](https://github.com/andreypopp), and [Laurence Rowe](https://github.com/lrowe) for their contributions!

## [](#changelog)Changelog

### [](#react)React

* Fixed bug with `<input type="range">` and selection events.
* Fixed bug with selection and focus.
* Made it possible to unmount components from the document root.
* Fixed bug for `disabled` attribute handling on non-`<input>` elements.

### [](#react-with-addons)React with Addons

* Fixed bug with transition and animation event detection.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2013-10-29-react-v0-5-1.md)

----
url: https://react.dev/learn/react-compiler/debugging
----

[Learn React](/learn)

[React Compiler](/learn/react-compiler)

# Debugging and Troubleshooting[](#undefined "Link for this heading")

This guide helps you identify and fix issues when using React Compiler. Learn how to debug compilation problems and resolve common issues.

### You will learn

* The difference between compiler errors and runtime issues
* Common patterns that break compilation
* Step-by-step debugging workflow

## Understanding Compiler Behavior[](#understanding-compiler-behavior "Link for Understanding Compiler Behavior ")

React Compiler is designed to handle code that follows the [Rules of React](/reference/rules). When it encounters code that might break these rules, it safely skips optimization rather than risk changing your app’s behavior.

### Compiler Errors vs Runtime Issues[](#compiler-errors-vs-runtime-issues "Link for Compiler Errors vs Runtime Issues ")

**Compiler errors** occur at build time and prevent your code from compiling. These are rare because the compiler is designed to skip problematic code rather than fail.

**Runtime issues** occur when compiled code behaves differently than expected. Most of the time, if you encounter an issue with React Compiler, it’s a runtime issue. This typically happens when your code violates the Rules of React in subtle ways that the compiler couldn’t detect, and the compiler mistakenly compiled a component it should have skipped.

When debugging runtime issues, focus your efforts on finding Rules of React violations in the affected components that were not detected by the ESLint rule. The compiler relies on your code following these rules, and when they’re broken in ways it can’t detect, that’s when runtime problems occur.

## Common Breaking Patterns[](#common-breaking-patterns "Link for Common Breaking Patterns ")

One of the main ways React Compiler can break your app is if your code was written to rely on memoization for correctness. This means your app depends on specific values being memoized to work properly. Since the compiler may memoize differently than your manual approach, this can lead to unexpected behavior like effects over-firing, infinite loops, or missing updates.

Common scenarios where this occurs:

* **Effects that rely on referential equality** - When effects depend on objects or arrays maintaining the same reference across renders
* **Dependency arrays that need stable references** - When unstable dependencies cause effects to fire too often or create infinite loops
* **Conditional logic based on reference checks** - When code uses referential equality checks for caching or optimization

## Debugging Workflow[](#debugging-workflow "Link for Debugging Workflow ")

Follow these steps when you encounter issues:

### Compiler Build Errors[](#compiler-build-errors "Link for Compiler Build Errors ")

If you encounter a compiler error that unexpectedly breaks your build, this is likely a bug in the compiler. Report it to the [facebook/react](https://github.com/facebook/react/issues) repository with:

* The error message
* The code that caused the error
* Your React and compiler versions

### Runtime Issues[](#runtime-issues "Link for Runtime Issues ")

For runtime behavior issues:

### 1. Temporarily Disable Compilation[](#temporarily-disable-compilation "Link for 1. Temporarily Disable Compilation ")

Use `"use no memo"` to isolate whether an issue is compiler-related:

```
function ProblematicComponent() {

  "use no memo"; // Skip compilation for this component

  // ... rest of component

}
```

If the issue disappears, it’s likely related to a Rules of React violation.

You can also try removing manual memoization (useMemo, useCallback, memo) from the problematic component to verify that your app works correctly without any memoization. If the bug still occurs when all memoization is removed, you have a Rules of React violation that needs to be fixed.

### 2. Fix Issues Step by Step[](#fix-issues-step-by-step "Link for 2. Fix Issues Step by Step ")

1. Identify the root cause (often memoization-for-correctness)
2. Test after each fix
3. Remove `"use no memo"` once fixed
4. Verify the component shows the ✨ badge in React DevTools

## Reporting Compiler Bugs[](#reporting-compiler-bugs "Link for Reporting Compiler Bugs ")

If you believe you’ve found a compiler bug:

1. **Verify it’s not a Rules of React violation** - Check with ESLint

2. **Create a minimal reproduction** - Isolate the issue in a small example

3. **Test without the compiler** - Confirm the issue only occurs with compilation

4. **File an [issue](https://github.com/facebook/react/issues/new?template=compiler_bug_report.yml)**:

   * React and compiler versions
   * Minimal reproduction code
   * Expected vs actual behavior
   * Any error messages

## Next Steps[](#next-steps "Link for Next Steps ")

* Review the [Rules of React](/reference/rules) to prevent issues
* Check the [incremental adoption guide](/learn/react-compiler/incremental-adoption) for gradual rollout strategies

[PreviousIncremental Adoption](/learn/react-compiler/incremental-adoption)

***

----
url: https://18.react.dev/learn/state-a-components-memory
----

```
import { sculptureList } from './data.js';

export default function Gallery() {
  let index = 0;

  function handleClick() {
    index = index + 1;
  }

  let sculpture = sculptureList[index];
  return (
    <>
      <button onClick={handleClick}>
        Next
      </button>
      <h2>
        <i>{sculpture.name} </i> 
        by {sculpture.artist}
      </h2>
      <h3>  
        ({index + 1} of {sculptureList.length})
      </h3>
      <img 
        src={sculpture.url} 
        alt={sculpture.alt}
      />
      <p>
        {sculpture.description}
      </p>
    </>
  );
}
```

```
import { useState } from 'react';
```

Then, replace this line:

```
let index = 0;
```

with

```
const [index, setIndex] = useState(0);
```

`index` is a state variable and `setIndex` is the setter function.

> The `[` and `]` syntax here is called [array destructuring](https://javascript.info/destructuring-assignment) and it lets you read values from an array. The array returned by `useState` always has exactly two items.

This is how they work together in `handleClick`:

```
function handleClick() {

  setIndex(index + 1);

}
```

Now clicking the “Next” button switches the current sculpture:

```
import { useState } from 'react';
import { sculptureList } from './data.js';

export default function Gallery() {
  const [index, setIndex] = useState(0);

  function handleClick() {
    setIndex(index + 1);
  }

  let sculpture = sculptureList[index];
  return (
    <>
      <button onClick={handleClick}>
        Next
      </button>
      <h2>
        <i>{sculpture.name} </i> 
        by {sculpture.artist}
      </h2>
      <h3>  
        ({index + 1} of {sculptureList.length})
      </h3>
      <img 
        src={sculpture.url} 
        alt={sculpture.alt}
      />
      <p>
        {sculpture.description}
      </p>
    </>
  );
}
```

```
const [index, setIndex] = useState(0);
```

```
const [index, setIndex] = useState(0);
```

1. **Your component renders the first time.** Because you passed `0` to `useState` as the initial value for `index`, it will return `[0, setIndex]`. React remembers `0` is the latest state value.
2. **You update the state.** When a user clicks the button, it calls `setIndex(index + 1)`. `index` is `0`, so it’s `setIndex(1)`. This tells React to remember `index` is `1` now and triggers another render.
3. **Your component’s second render.** React still sees `useState(0)`, but because React *remembers* that you set `index` to `1`, it returns `[1, setIndex]` instead.
4. And so on!

## Giving a component multiple state variables[](#giving-a-component-multiple-state-variables "Link for Giving a component multiple state variables ")

You can have as many state variables of as many types as you like in one component. This component has two state variables, a number `index` and a boolean `showMore` that’s toggled when you click “Show details”:

```
import { useState } from 'react';
import { sculptureList } from './data.js';

export default function Gallery() {
  const [index, setIndex] = useState(0);
  const [showMore, setShowMore] = useState(false);

  function handleNextClick() {
    setIndex(index + 1);
  }

  function handleMoreClick() {
    setShowMore(!showMore);
  }

  let sculpture = sculptureList[index];
  return (
    <>
      <button onClick={handleNextClick}>
        Next
      </button>
      <h2>
        <i>{sculpture.name} </i> 
        by {sculpture.artist}
      </h2>
      <h3>  
        ({index + 1} of {sculptureList.length})
      </h3>
      <button onClick={handleMoreClick}>
        {showMore ? 'Hide' : 'Show'} details
      </button>
      {showMore && <p>{sculpture.description}</p>}
      <img 
        src={sculpture.url} 
        alt={sculpture.alt}
      />
    </>
  );
}
```

It is a good idea to have multiple state variables if their state is unrelated, like `index` and `showMore` in this example. But if you find that you often change two state variables together, it might be easier to combine them into one. For example, if you have a form with many fields, it’s more convenient to have a single state variable that holds an object than state variable per field. Read [Choosing the State Structure](/learn/choosing-the-state-structure) for more tips.

##### Deep Dive#### How does React know which state to return?[](#how-does-react-know-which-state-to-return "Link for How does React know which state to return? ")

You might have noticed that the `useState` call does not receive any information about *which* state variable it refers to. There is no “identifier” that is passed to `useState`, so how does it know which of the state variables to return? Does it rely on some magic like parsing your functions? The answer is no.

Instead, to enable their concise syntax, Hooks **rely on a stable call order on every render of the same component.** This works well in practice because if you follow the rule above (“only call Hooks at the top level”), Hooks will always be called in the same order. Additionally, a [linter plugin](https://www.npmjs.com/package/eslint-plugin-react-hooks) catches most mistakes.

Internally, React holds an array of state pairs for every component. It also maintains the current pair index, which is set to `0` before rendering. Each time you call `useState`, React gives you the next state pair and increments the index. You can read more about this mechanism in [React Hooks: Not Magic, Just Arrays.](https://medium.com/@ryardley/react-hooks-not-magic-just-arrays-cd4f1857236e)

This example **doesn’t use React** but it gives you an idea of how `useState` works internally:

```
let componentHooks = [];
let currentHookIndex = 0;

// How useState works inside React (simplified).
function useState(initialState) {
  let pair = componentHooks[currentHookIndex];
  if (pair) {
    // This is not the first render,
    // so the state pair already exists.
    // Return it and prepare for next Hook call.
    currentHookIndex++;
    return pair;
  }

  // This is the first time we're rendering,
  // so create a state pair and store it.
  pair = [initialState, setState];

  function setState(nextState) {
    // When the user requests a state change,
    // put the new value into the pair.
    pair[0] = nextState;
    updateDOM();
  }

  // Store the pair for future renders
  // and prepare for the next Hook call.
  componentHooks[currentHookIndex] = pair;
  currentHookIndex++;
  return pair;
}

function Gallery() {
  // Each useState() call will get the next pair.
  const [index, setIndex] = useState(0);
  const [showMore, setShowMore] = useState(false);

  function handleNextClick() {
    setIndex(index + 1);
  }

  function handleMoreClick() {
    setShowMore(!showMore);
  }

  let sculpture = sculptureList[index];
  // This example doesn't use React, so
  // return an output object instead of JSX.
  return {
    onNextClick: handleNextClick,
    onMoreClick: handleMoreClick,
    header: `${sculpture.name} by ${sculpture.artist}`,
    counter: `${index + 1} of ${sculptureList.length}`,
    more: `${showMore ? 'Hide' : 'Show'} details`,
    description: showMore ? sculpture.description : null,
    imageSrc: sculpture.url,
    imageAlt: sculpture.alt
  };
}

function updateDOM() {
  // Reset the current Hook index
  // before rendering the component.
  currentHookIndex = 0;
  let output = Gallery();

  // Update the DOM to match the output.
  // This is the part React does for you.
  nextButton.onclick = output.onNextClick;
  header.textContent = output.header;
  moreButton.onclick = output.onMoreClick;
  moreButton.textContent = output.more;
  image.src = output.imageSrc;
  image.alt = output.imageAlt;
  if (output.description !== null) {
    description.textContent = output.description;
    description.style.display = '';
  } else {
    description.style.display = 'none';
  }
}

let nextButton = document.getElementById('nextButton');
let header = document.getElementById('header');
let moreButton = document.getElementById('moreButton');
let description = document.getElementById('description');
let image = document.getElementById('image');
let sculptureList = [{
  name: 'Homenaje a la Neurocirugía',
  artist: 'Marta Colvin Andrade',
  description: 'Although Colvin is predominantly known for abstract themes that allude to pre-Hispanic symbols, this gigantic sculpture, an homage to neurosurgery, is one of her most recognizable public art pieces.',
  url: 'https://i.imgur.com/Mx7dA2Y.jpg',
  alt: 'A bronze statue of two crossed hands delicately holding a human brain in their fingertips.'  
}, {
  name: 'Floralis Genérica',
  artist: 'Eduardo Catalano',
  description: 'This enormous (75 ft. or 23m) silver flower is located in Buenos Aires. It is designed to move, closing its petals in the evening or when strong winds blow and opening them in the morning.',
  url: 'https://i.imgur.com/ZF6s192m.jpg',
  alt: 'A gigantic metallic flower sculpture with reflective mirror-like petals and strong stamens.'
}, {
  name: 'Eternal Presence',
  artist: 'John Woodrow Wilson',
  description: 'Wilson was known for his preoccupation with equality, social justice, as well as the essential and spiritual qualities of humankind. This massive (7ft. or 2,13m) bronze represents what he described as "a symbolic Black presence infused with a sense of universal humanity."',
  url: 'https://i.imgur.com/aTtVpES.jpg',
  alt: 'The sculpture depicting a human head seems ever-present and solemn. It radiates calm and serenity.'
}, {
  name: 'Moai',
  artist: 'Unknown Artist',
  description: 'Located on the Easter Island, there are 1,000 moai, or extant monumental statues, created by the early Rapa Nui people, which some believe represented deified ancestors.',
  url: 'https://i.imgur.com/RCwLEoQm.jpg',
  alt: 'Three monumental stone busts with the heads that are disproportionately large with somber faces.'
}, {
  name: 'Blue Nana',
  artist: 'Niki de Saint Phalle',
  description: 'The Nanas are triumphant creatures, symbols of femininity and maternity. Initially, Saint Phalle used fabric and found objects for the Nanas, and later on introduced polyester to achieve a more vibrant effect.',
  url: 'https://i.imgur.com/Sd1AgUOm.jpg',
  alt: 'A large mosaic sculpture of a whimsical dancing female figure in a colorful costume emanating joy.'
}, {
  name: 'Ultimate Form',
  artist: 'Barbara Hepworth',
  description: 'This abstract bronze sculpture is a part of The Family of Man series located at Yorkshire Sculpture Park. Hepworth chose not to create literal representations of the world but developed abstract forms inspired by people and landscapes.',
  url: 'https://i.imgur.com/2heNQDcm.jpg',
  alt: 'A tall sculpture made of three elements stacked on each other reminding of a human figure.'
}, {
  name: 'Cavaliere',
  artist: 'Lamidi Olonade Fakeye',
  description: "Descended from four generations of woodcarvers, Fakeye's work blended traditional and contemporary Yoruba themes.",
  url: 'https://i.imgur.com/wIdGuZwm.png',
  alt: 'An intricate wood sculpture of a warrior with a focused face on a horse adorned with patterns.'
}, {
  name: 'Big Bellies',
  artist: 'Alina Szapocznikow',
  description: "Szapocznikow is known for her sculptures of the fragmented body as a metaphor for the fragility and impermanence of youth and beauty. This sculpture depicts two very realistic large bellies stacked on top of each other, each around five feet (1,5m) tall.",
  url: 'https://i.imgur.com/AlHTAdDm.jpg',
  alt: 'The sculpture reminds a cascade of folds, quite different from bellies in classical sculptures.'
}, {
  name: 'Terracotta Army',
  artist: 'Unknown Artist',
  description: 'The Terracotta Army is a collection of terracotta sculptures depicting the armies of Qin Shi Huang, the first Emperor of China. The army consisted of more than 8,000 soldiers, 130 chariots with 520 horses, and 150 cavalry horses.',
  url: 'https://i.imgur.com/HMFmH6m.jpg',
  alt: '12 terracotta sculptures of solemn warriors, each with a unique facial expression and armor.'
}, {
  name: 'Lunar Landscape',
  artist: 'Louise Nevelson',
  description: 'Nevelson was known for scavenging objects from New York City debris, which she would later assemble into monumental constructions. In this one, she used disparate parts like a bedpost, juggling pin, and seat fragment, nailing and gluing them into boxes that reflect the influence of Cubism’s geometric abstraction of space and form.',
  url: 'https://i.imgur.com/rN7hY6om.jpg',
  alt: 'A black matte sculpture where the individual elements are initially indistinguishable.'
}, {
  name: 'Aureole',
  artist: 'Ranjani Shettar',
  description: 'Shettar merges the traditional and the modern, the natural and the industrial. Her art focuses on the relationship between man and nature. Her work was described as compelling both abstractly and figuratively, gravity defying, and a "fine synthesis of unlikely materials."',
  url: 'https://i.imgur.com/okTpbHhm.jpg',
  alt: 'A pale wire-like sculpture mounted on concrete wall and descending on the floor. It appears light.'
}, {
  name: 'Hippos',
  artist: 'Taipei Zoo',
  description: 'The Taipei Zoo commissioned a Hippo Square featuring submerged hippos at play.',
  url: 'https://i.imgur.com/6o5Vuyu.jpg',
  alt: 'A group of bronze hippo sculptures emerging from the sett sidewalk as if they were swimming.'
}];

// Make UI match the initial state.
updateDOM();
```

You don’t have to understand it to use React, but you might find this a helpful mental model.

## State is isolated and private[](#state-is-isolated-and-private "Link for State is isolated and private ")

State is local to a component instance on the screen. In other words, **if you render the same component twice, each copy will have completely isolated state!** Changing one of them will not affect the other.

In this example, the `Gallery` component from earlier is rendered twice with no changes to its logic. Try clicking the buttons inside each of the galleries. Notice that their state is independent:

```
import Gallery from './Gallery.js';

export default function Page() {
  return (
    <div className="Page">
      <Gallery />
      <Gallery />
    </div>
  );
}
```

```
import { useState } from 'react';
import { sculptureList } from './data.js';

export default function Gallery() {
  const [index, setIndex] = useState(0);
  const [showMore, setShowMore] = useState(false);

  function handleNextClick() {
    setIndex(index + 1);
  }

  function handleMoreClick() {
    setShowMore(!showMore);
  }

  let sculpture = sculptureList[index];
  return (
    <>
      <button onClick={handleNextClick}>
        Next
      </button>
      <h2>
        <i>{sculpture.name} </i> 
        by {sculpture.artist}
      </h2>
      <h3>  
        ({index + 1} of {sculptureList.length})
      </h3>
      <button onClick={handleMoreClick}>
        {showMore ? 'Hide' : 'Show'} details
      </button>
      {showMore && <p>{sculpture.description}</p>}
      <img 
        src={sculpture.url} 
        alt={sculpture.alt}
      />
    </>
  );
}
```

[PreviousResponding to Events](/learn/responding-to-events)

[NextRender and Commit](/learn/render-and-commit)

***

----
url: https://legacy.reactjs.org/blog/2014/10/14/introducing-react-elements.html
----

October 14, 2014 by [Sebastian Markbåge](https://twitter.com/sebmarkbage)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

The upcoming React 0.12 tweaks some APIs to get us close to the final 1.0 API. This release is all about setting us up for making the `ReactElement` type really FAST, [jest unit testing](https://facebook.github.io/jest/) easier, making classes simpler (in preparation for ES6 classes) and better integration with third-party languages!

If you currently use JSX everywhere, you don’t really have to do anything to get these benefits! The updated transformer will do it for you.

If you can’t or don’t want to use JSX, then please insert some hints for us. Add a `React.createFactory` call around your imported class when you require it:

```
var MyComponent = React.createFactory(require('MyComponent'));
```

Everything is backwards compatible for now, and as always React will provide you with descriptive console messaging to help you upgrade.

`ReactElement` is the primary API of React. Making it faster has shown to give us several times faster renders on common benchmarks. The API tweaks in this release helps us get there.

Continue reading if you want all the nitty gritty details…

## [](#new-terminology)New Terminology

We wanted to make it easier for new users to see the parallel with the DOM (and why React is different). To align our terminology we now use the term `ReactElement` instead of *descriptor*. Likewise, we use the term `ReactNode` instead of *renderable*.

[See the full React terminology guide.](https://gist.github.com/sebmarkbage/fcb1b6ab493b0c77d589)

## [](#creating-a-reactelement)Creating a ReactElement

We now expose an external API for programmatically creating a `ReactElement` object.

```
var reactElement = React.createElement(type, props, children);
```

The `type` argument is either a string (HTML tag) or a class. It’s a description of what tag/class is going to be rendered and what props it will contain. You can also create factory functions for specific types. This basically just provides the type argument for you:

```
var div = React.createFactory('div');
var reactDivElement = div(props, children);
```

## [](#deprecated-auto-generated-factories)Deprecated: Auto-generated Factories

Imagine if `React.createClass` was just a plain JavaScript class. If you call a class as a plain function you would call the component’s constructor to create a Component instance, not a `ReactElement`:

```
new MyComponent(); // Component, not ReactElement
```

React 0.11 gave you a factory function for free when you called `React.createClass`. This wrapped your internal class and then returned a `ReactElement` factory function for you.

```
var MyComponent = React.createFactory(
  class {
    render() {
      ...
    }
  }
);
```

In future versions of React, we want to be able to support pure classes without any special React dependencies. To prepare for that we’re [deprecating the auto-generated factory](https://gist.github.com/sebmarkbage/d7bce729f38730399d28).

This is the biggest change to 0.12. Don’t worry though. This functionality continues to work the same for this release, it just warns you if you’re using a deprecated API. That way you can upgrade piece-by-piece instead of everything at once.

## [](#upgrading-to-012)Upgrading to 0.12

### [](#react-with-jsx)React With JSX

If you use the React specific [JSX](https://facebook.github.io/jsx/) transform, the upgrade path is simple. Just make sure you have React in scope.

```
// If you use node/browserify modules make sure
// that you require React into scope.
var React = require('react');
```

React’s JSX will create the `ReactElement` for you. You can continue to use JSX with regular classes:

```
var MyComponent = React.createClass(...);

var MyOtherComponent = React.createClass({
  render: function() {
    return <MyComponent prop="value" />;
  }
});
```

*NOTE: React’s JSX will not call arbitrary functions in future releases. This restriction is introduced so that it’s easier to reason about the output of JSX by both the reader of your code and optimizing compilers. The JSX syntax is not tied to React. Just the transpiler. You can still use [the JSX spec](https://facebook.github.io/jsx/) with a different transpiler for custom purposes.*

### [](#react-without-jsx)React Without JSX

If you don’t use JSX and just call components as functions, you will need to explicitly create a factory before calling it:

```
var MyComponentClass = React.createClass(...);

var MyComponent = React.createFactory(MyComponentClass); // New step

var MyOtherComponent = React.createClass({
  render: function() {
    return MyComponent({ prop: 'value' });
  }
});
```

If you’re using a module system, the recommended solution is to export the class and create the factory on the requiring side.

Your class creation is done just like before:

```
// MyComponent.js
var React = require('react');
var MyComponent = React.createClass(...);
module.exports = MyComponent;
```

The other side uses `React.createFactory` after `require`ing the component class:

```
// MyOtherComponent.js
var React = require('react');
// All you have to do to upgrade is wrap your requires like this:
var MyComponent = React.createFactory(require('MyComponent'));

var MyOtherComponent = React.createClass({
  render: function() {
    return MyComponent({ prop: 'value' });
  }
});

module.exports = MyOtherComponent;
```

You ONLY have to do this for custom classes. React still has built-in factories for common HTML elements.

```
var MyDOMComponent = React.createClass({
  render: function() {
    return React.DOM.div({ className: 'foo' }); // still ok
  }
});
```

We realize that this is noisy. At least it’s on the top of the file (out of sight, out of mind). This a tradeoff we had to make to get [the other benefits](https://gist.github.com/sebmarkbage/d7bce729f38730399d28) that this model unlocks.

### [](#anti-pattern-exporting-factories)Anti-Pattern: Exporting Factories

If you have an isolated project that only you use, then you could create a helper that creates both the class and the factory at once:

```
// Anti-pattern - Please, don't use
function createClass(spec) {
  return React.createFactory(React.createClass(spec));
}
```

This makes your components incompatible with jest testing, consumers using JSX, third-party languages that implement their own optimized `ReactElement` creation, etc.

It also encourages you to put more logic into these helper functions. Something that another language, a compiler or a reader of your code couldn’t reason about.

To fit into the React ecosystem we recommend that you always export pure classes from your shared modules and let the consumer decide the best strategy for generating `ReactElement`s.

## [](#third-party-languages)Third-party Languages

The signature of a `ReactElement` is something like this:

```
{
  type : string | class,
  props : { children, className, etc. },
  key : string | boolean | number | null,
  ref : string | null
}
```

Languages with static typing that don’t need validation (e.g. [Om in ClojureScript](https://github.com/swannodette/om)), and production level compilers will be able to generate these objects inline instead of going through the validation step. This optimization will allow significant performance improvements in React.

## [](#your-thoughts-and-ideas)Your Thoughts and Ideas

We’d love to hear your feedback on this API and your preferred style. A plausible alternative could be to directly inline objects instead of creating factory functions:

```
// MyOtherComponent.js
var React = require('react');
var MyComponent = require('MyComponent');

var MyOtherComponent = React.createClass({
  render: function() {
    return { type: MyComponent, props: { prop: 'value' } };
  }
});

module.exports = MyOtherComponent;
```

This moves the noise down into the render method though. It also doesn’t provide a hook for dynamic validation/type checking so you’ll need some other way to verify that it’s safe.

*NOTE: This won’t work in this version of React because it’s conflicting with other legacy APIs that we’re deprecating. (We temporarily add a `element._isReactElement = true` marker on the object.)*

## [](#the-next-step-es6-classes)The Next Step: ES6 Classes

After 0.12 we’ll begin work on moving to ES6 classes. We will still support `React.createClass` as a backwards compatible API. If you use an ES6 transpiler you will be able to declare your components like this:

```
export class MyComponent {
  render() {
    ...
  }
};
```

This upcoming release is a stepping stone to make it as easy as this. Thanks for your support.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2014-10-14-introducing-react-elements.md)

----
url: https://legacy.reactjs.org/blog/2016/03/16/react-v15-rc2.html
----

March 16, 2016 by [Paul O’Shannessy](https://twitter.com/zpao)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

Today we’re releasing a second release candidate for version 15. Primarily this is to address 2 issues, but we also picked up a few small changes from new contributors, including some improvements to some of our new warnings.

The most pressing change that was made is to fix a bug in our new code that removes `<span>`s, as discussed in the original RC1 post. Specifically we have some code that takes a different path in IE11 and Edge due to the speed of some DOM operations. There was a bug in this code which didn’t break out of the optimization for `DocumentFragment`s, resulting in text not appearing at all. Thanks to the several people who [reported this](https://github.com/facebook/react/issues/6246).

The other change is to our SVG code. In RC1 we had made the decision to pass through all attributes directly. This led to [some confusion with `class` vs `className`](https://github.com/facebook/react/issues/6211) and ultimately led us to reconsider our position on the approach. Passing through all attributes meant that we would have two different patterns for using React where things like hyphenated attributes would work for SVG but not HTML. In the future, we *might* change our approach to the problem for HTML as well but in the meantime, maintaining consistency is important. So we reverted the changes that allowed the attributes to be passed through and instead expanded the SVG property list to include all attributes that are in the spec. We believe we have everything now but definitely [let us know](https://github.com/facebook/react/issues/1657#issuecomment-197031403) if we missed anything. It was and still is our intent to support the full range of SVG tags and attributes in this release.

Thanks again to everybody who has tried the RC1 and reported issues. It has been extremely important and we wouldn’t be able to do this without your help!

## [](#installation)Installation

We recommend using React from `npm` and using a tool like browserify or webpack to build your code into a single bundle. To install the two packages:

* `npm install --save react@15.0.0-rc.2 react-dom@15.0.0-rc.2`

Remember that by default, React runs extra checks and provides helpful warnings in development mode. When deploying your app, set the `NODE_ENV` environment variable to `production` to use the production build of React which does not include the development warnings and runs significantly faster.

If you can’t use `npm` yet, we provide pre-built browser builds for your convenience, which are also available in the `react` package on bower.

* **React**\
  Dev build with warnings: <https://fb.me/react-15.0.0-rc.2.js>\
  Minified build for production: <https://fb.me/react-15.0.0-rc.2.min.js>
* **React with Add-Ons**\
  Dev build with warnings: <https://fb.me/react-with-addons-15.0.0-rc.2.js>\
  Minified build for production: <https://fb.me/react-with-addons-15.0.0-rc.2.min.js>
* **React DOM** (include React in the page before React DOM)\
  Dev build with warnings: <https://fb.me/react-dom-15.0.0-rc.2.js>\
  Minified build for production: <https://fb.me/react-dom-15.0.0-rc.2.min.js>

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2016-03-16-react-v15-rc2.md)

----
url: https://react.dev/blog/2026/02/24/the-react-foundation
----

[Blog](/blog)

# The React Foundation: A New Home for React Hosted by the Linux Foundation[](#undefined "Link for this heading")

February 24, 2026 by [Matt Carroll](https://x.com/mattcarrollcode)

***

The React Foundation has officially launched, hosted by the Linux Foundation.

***

[In October](/blog/2025/10/07/introducing-the-react-foundation), we announced our intent to form the React Foundation. Today, we’re excited to share that the React Foundation has officially launched.

React, React Native, and supporting projects like JSX are no longer owned by Meta — they are now owned by the React Foundation, an independent foundation hosted by the Linux Foundation. You can read more in the [Linux Foundation’s press release](https://www.linuxfoundation.org/press/linux-foundation-announces-the-formation-of-the-react-foundation).

### Founding Members[](#founding-members "Link for Founding Members ")

The React Foundation has eight Platinum founding members: **Amazon**, **Callstack**, **Expo**, **Huawei**, **Meta**, **Microsoft**, **Software Mansion**, and **Vercel**. **Huawei** has joined since [our announcement in October](/blog/2025/10/07/introducing-the-react-foundation). The React Foundation will be governed by a board of directors composed of representatives from each member, with [Seth Webster](https://sethwebster.com/) serving as executive director.

### New Provisional Leadership Council[](#new-provisional-leadership-council "Link for New Provisional Leadership Council ")

React’s technical governance will always be independent from the React Foundation board — React’s technical direction will continue to be set by the people who contribute to and maintain React. We have formed a provisional leadership council to determine this structure. We will share an update in the coming months.

### Next Steps[](#next-steps "Link for Next Steps ")

There is still work to do to complete the transition. In the coming months we will be:

* Finalizing the technical governance structure for React
* Transferring repositories, websites, and other infrastructure to the React Foundation
* Exploring programs to support the React ecosystem
* Kicking off planning for the next React Conf

We will share updates as this work progresses.

### Thank You[](#thank-you "Link for Thank You ")

None of this would be possible without the thousands of contributors who have shaped React over the past decade. Thank you to our founding members, to every contributor who has opened a pull request, filed an issue, or helped someone learn React, and to the millions of developers who build with React every day. The React Foundation exists because of this community, and we’re looking forward to building its future together.

[PreviousBlog](/blog)

[NextDenial of Service and Source Code Exposure in React Server Components](/blog/2025/12/11/denial-of-service-and-source-code-exposure-in-react-server-components)

***

----
url: https://18.react.dev/learn/managing-state
----

```
import { useState } from 'react';

export default function Form() {
  const [answer, setAnswer] = useState('');
  const [error, setError] = useState(null);
  const [status, setStatus] = useState('typing');

  if (status === 'success') {
    return <h1>That's right!</h1>
  }

  async function handleSubmit(e) {
    e.preventDefault();
    setStatus('submitting');
    try {
      await submitForm(answer);
      setStatus('success');
    } catch (err) {
      setStatus('typing');
      setError(err);
    }
  }

  function handleTextareaChange(e) {
    setAnswer(e.target.value);
  }

  return (
    <>
      <h2>City quiz</h2>
      <p>
        In which city is there a billboard that turns air into drinkable water?
      </p>
      <form onSubmit={handleSubmit}>
        <textarea
          value={answer}
          onChange={handleTextareaChange}
          disabled={status === 'submitting'}
        />
        <br />
        <button disabled={
          answer.length === 0 ||
          status === 'submitting'
        }>
          Submit
        </button>
        {error !== null &&
          <p className="Error">
            {error.message}
          </p>
        }
      </form>
    </>
  );
}

function submitForm(answer) {
  // Pretend it's hitting the network.
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      let shouldError = answer.toLowerCase() !== 'lima'
      if (shouldError) {
        reject(new Error('Good guess but a wrong answer. Try again!'));
      } else {
        resolve();
      }
    }, 1500);
  });
}
```

[Open Sandbox](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

## Ready to learn this topic?

Read **[Reacting to Input with State](/learn/reacting-to-input-with-state)** to learn how to approach interactions with a state-driven mindset.

[Read More](/learn/reacting-to-input-with-state)

***

## Choosing the state structure[](#choosing-the-state-structure "Link for Choosing the state structure ")

Structuring state well can make a difference between a component that is pleasant to modify and debug, and one that is a constant source of bugs. The most important principle is that state shouldn’t contain redundant or duplicated information. If there’s unnecessary state, it’s easy to forget to update it, and introduce bugs!

For example, this form has a **redundant** `fullName` state variable:

```
import { useState } from 'react';

export default function Form() {
  const [firstName, setFirstName] = useState('');
  const [lastName, setLastName] = useState('');
  const [fullName, setFullName] = useState('');

  function handleFirstNameChange(e) {
    setFirstName(e.target.value);
    setFullName(e.target.value + ' ' + lastName);
  }

  function handleLastNameChange(e) {
    setLastName(e.target.value);
    setFullName(firstName + ' ' + e.target.value);
  }

  return (
    <>
      <h2>Let’s check you in</h2>
      <label>
        First name:{' '}
        <input
          value={firstName}
          onChange={handleFirstNameChange}
        />
      </label>
      <label>
        Last name:{' '}
        <input
          value={lastName}
          onChange={handleLastNameChange}
        />
      </label>
      <p>
        Your ticket will be issued to: <b>{fullName}</b>
      </p>
    </>
  );
}
```

You can remove it and simplify the code by calculating `fullName` while the component is rendering:

```
import { useState } from 'react';

export default function Form() {
  const [firstName, setFirstName] = useState('');
  const [lastName, setLastName] = useState('');

  const fullName = firstName + ' ' + lastName;

  function handleFirstNameChange(e) {
    setFirstName(e.target.value);
  }

  function handleLastNameChange(e) {
    setLastName(e.target.value);
  }

  return (
    <>
      <h2>Let’s check you in</h2>
      <label>
        First name:{' '}
        <input
          value={firstName}
          onChange={handleFirstNameChange}
        />
      </label>
      <label>
        Last name:{' '}
        <input
          value={lastName}
          onChange={handleLastNameChange}
        />
      </label>
      <p>
        Your ticket will be issued to: <b>{fullName}</b>
      </p>
    </>
  );
}
```

This might seem like a small change, but many bugs in React apps are fixed this way.

## Ready to learn this topic?

Read **[Choosing the State Structure](/learn/choosing-the-state-structure)** to learn how to design the state shape to avoid bugs.

[Read More](/learn/choosing-the-state-structure)

***

## Sharing state between components[](#sharing-state-between-components "Link for Sharing state between components ")

Sometimes, you want the state of two components to always change together. To do it, remove state from both of them, move it to their closest common parent, and then pass it down to them via props. This is known as “lifting state up”, and it’s one of the most common things you will do writing React code.

In this example, only one panel should be active at a time. To achieve this, instead of keeping the active state inside each individual panel, the parent component holds the state and specifies the props for its children.

```
import { useState } from 'react';

export default function Accordion() {
  const [activeIndex, setActiveIndex] = useState(0);
  return (
    <>
      <h2>Almaty, Kazakhstan</h2>
      <Panel
        title="About"
        isActive={activeIndex === 0}
        onShow={() => setActiveIndex(0)}
      >
        With a population of about 2 million, Almaty is Kazakhstan's largest city. From 1929 to 1997, it was its capital city.
      </Panel>
      <Panel
        title="Etymology"
        isActive={activeIndex === 1}
        onShow={() => setActiveIndex(1)}
      >
        The name comes from <span lang="kk-KZ">алма</span>, the Kazakh word for "apple" and is often translated as "full of apples". In fact, the region surrounding Almaty is thought to be the ancestral home of the apple, and the wild <i lang="la">Malus sieversii</i> is considered a likely candidate for the ancestor of the modern domestic apple.
      </Panel>
    </>
  );
}

function Panel({
  title,
  children,
  isActive,
  onShow
}) {
  return (
    <section className="panel">
      <h3>{title}</h3>
      {isActive ? (
        <p>{children}</p>
      ) : (
        <button onClick={onShow}>
          Show
        </button>
      )}
    </section>
  );
}
```

## Ready to learn this topic?

Read **[Sharing State Between Components](/learn/sharing-state-between-components)** to learn how to lift state up and keep components in sync.

[Read More](/learn/sharing-state-between-components)

***

## Preserving and resetting state[](#preserving-and-resetting-state "Link for Preserving and resetting state ")

When you re-render a component, React needs to decide which parts of the tree to keep (and update), and which parts to discard or re-create from scratch. In most cases, React’s automatic behavior works well enough. By default, React preserves the parts of the tree that “match up” with the previously rendered component tree.

However, sometimes this is not what you want. In this chat app, typing a message and then switching the recipient does not reset the input. This can make the user accidentally send a message to the wrong person:

```
import { useState } from 'react';
import Chat from './Chat.js';
import ContactList from './ContactList.js';

export default function Messenger() {
  const [to, setTo] = useState(contacts[0]);
  return (
    <div>
      <ContactList
        contacts={contacts}
        selectedContact={to}
        onSelect={contact => setTo(contact)}
      />
      <Chat contact={to} />
    </div>
  )
}

const contacts = [
  { name: 'Taylor', email: 'taylor@mail.com' },
  { name: 'Alice', email: 'alice@mail.com' },
  { name: 'Bob', email: 'bob@mail.com' }
];
```

React lets you override the default behavior, and *force* a component to reset its state by passing it a different `key`, like `<Chat key={email} />`. This tells React that if the recipient is different, it should be considered a *different* `Chat` component that needs to be re-created from scratch with the new data (and UI like inputs). Now switching between the recipients resets the input field—even though you render the same component.

```
import { useState } from 'react';
import Chat from './Chat.js';
import ContactList from './ContactList.js';

export default function Messenger() {
  const [to, setTo] = useState(contacts[0]);
  return (
    <div>
      <ContactList
        contacts={contacts}
        selectedContact={to}
        onSelect={contact => setTo(contact)}
      />
      <Chat key={to.email} contact={to} />
    </div>
  )
}

const contacts = [
  { name: 'Taylor', email: 'taylor@mail.com' },
  { name: 'Alice', email: 'alice@mail.com' },
  { name: 'Bob', email: 'bob@mail.com' }
];
```

## Ready to learn this topic?

Read **[Preserving and Resetting State](/learn/preserving-and-resetting-state)** to learn the lifetime of state and how to control it.

[Read More](/learn/preserving-and-resetting-state)

***

## Extracting state logic into a reducer[](#extracting-state-logic-into-a-reducer "Link for Extracting state logic into a reducer ")

Components with many state updates spread across many event handlers can get overwhelming. For these cases, you can consolidate all the state update logic outside your component in a single function, called “reducer”. Your event handlers become concise because they only specify the user “actions”. At the bottom of the file, the reducer function specifies how the state should update in response to each action!

```
import { useReducer } from 'react';
import AddTask from './AddTask.js';
import TaskList from './TaskList.js';

export default function TaskApp() {
  const [tasks, dispatch] = useReducer(
    tasksReducer,
    initialTasks
  );

  function handleAddTask(text) {
    dispatch({
      type: 'added',
      id: nextId++,
      text: text,
    });
  }

  function handleChangeTask(task) {
    dispatch({
      type: 'changed',
      task: task
    });
  }

  function handleDeleteTask(taskId) {
    dispatch({
      type: 'deleted',
      id: taskId
    });
  }

  return (
    <>
      <h1>Prague itinerary</h1>
      <AddTask
        onAddTask={handleAddTask}
      />
      <TaskList
        tasks={tasks}
        onChangeTask={handleChangeTask}
        onDeleteTask={handleDeleteTask}
      />
    </>
  );
}

function tasksReducer(tasks, action) {
  switch (action.type) {
    case 'added': {
      return [...tasks, {
        id: action.id,
        text: action.text,
        done: false
      }];
    }
    case 'changed': {
      return tasks.map(t => {
        if (t.id === action.task.id) {
          return action.task;
        } else {
          return t;
        }
      });
    }
    case 'deleted': {
      return tasks.filter(t => t.id !== action.id);
    }
    default: {
      throw Error('Unknown action: ' + action.type);
    }
  }
}

let nextId = 3;
const initialTasks = [
  { id: 0, text: 'Visit Kafka Museum', done: true },
  { id: 1, text: 'Watch a puppet show', done: false },
  { id: 2, text: 'Lennon Wall pic', done: false }
];
```

## Ready to learn this topic?

Read **[Extracting State Logic into a Reducer](/learn/extracting-state-logic-into-a-reducer)** to learn how to consolidate logic in the reducer function.

[Read More](/learn/extracting-state-logic-into-a-reducer)

***

## Passing data deeply with context[](#passing-data-deeply-with-context "Link for Passing data deeply with context ")

Usually, you will pass information from a parent component to a child component via props. But passing props can become inconvenient if you need to pass some prop through many components, or if many components need the same information. Context lets the parent component make some information available to any component in the tree below it—no matter how deep it is—without passing it explicitly through props.

Here, the `Heading` component determines its heading level by “asking” the closest `Section` for its level. Each `Section` tracks its own level by asking the parent `Section` and adding one to it. Every `Section` provides information to all components below it without passing props—it does that through context.

```
import Heading from './Heading.js';
import Section from './Section.js';

export default function Page() {
  return (
    <Section>
      <Heading>Title</Heading>
      <Section>
        <Heading>Heading</Heading>
        <Heading>Heading</Heading>
        <Heading>Heading</Heading>
        <Section>
          <Heading>Sub-heading</Heading>
          <Heading>Sub-heading</Heading>
          <Heading>Sub-heading</Heading>
          <Section>
            <Heading>Sub-sub-heading</Heading>
            <Heading>Sub-sub-heading</Heading>
            <Heading>Sub-sub-heading</Heading>
          </Section>
        </Section>
      </Section>
    </Section>
  );
}
```

## Ready to learn this topic?

Read **[Passing Data Deeply with Context](/learn/passing-data-deeply-with-context)** to learn about using context as an alternative to passing props.

[Read More](/learn/passing-data-deeply-with-context)

***

## Scaling up with reducer and context[](#scaling-up-with-reducer-and-context "Link for Scaling up with reducer and context ")

Reducers let you consolidate a component’s state update logic. Context lets you pass information deep down to other components. You can combine reducers and context together to manage state of a complex screen.

With this approach, a parent component with complex state manages it with a reducer. Other components anywhere deep in the tree can read its state via context. They can also dispatch actions to update that state.

```
import AddTask from './AddTask.js';
import TaskList from './TaskList.js';
import { TasksProvider } from './TasksContext.js';

export default function TaskApp() {
  return (
    <TasksProvider>
      <h1>Day off in Kyoto</h1>
      <AddTask />
      <TaskList />
    </TasksProvider>
  );
}
```

## Ready to learn this topic?

Read **[Scaling Up with Reducer and Context](/learn/scaling-up-with-reducer-and-context)** to learn how state management scales in a growing app.

[Read More](/learn/scaling-up-with-reducer-and-context)

***

## What’s next?[](#whats-next "Link for What’s next? ")

Head over to [Reacting to Input with State](/learn/reacting-to-input-with-state) to start reading this chapter page by page!

Or, if you’re already familiar with these topics, why not read about [Escape Hatches](/learn/escape-hatches)?

[PreviousUpdating Arrays in State](/learn/updating-arrays-in-state)

[NextReacting to Input with State](/learn/reacting-to-input-with-state)

***

----
url: https://18.react.dev/reference/react-dom/components/style
----

[API Reference](/reference/react)

[Components](/reference/react-dom/components)

# \<style>[](#undefined "Link for this heading")

### Canary

React’s extensions to `<style>` are currently only available in React’s canary and experimental channels. In stable releases of React `<style>` works only as a [built-in browser HTML component](https://react.dev/reference/react-dom/components#all-html-components). Learn more about [React’s release channels here](/community/versioning-policy#all-release-channels).

The [built-in browser `<style>` component](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/style) lets you add inline CSS stylesheets to your document.

```
<style>{` p { color: red; } `}</style>
```

* [Reference](#reference)
  * [`<style>`](#style)
* [Usage](#usage)
  * [Rendering an inline CSS stylesheet](#rendering-an-inline-css-stylesheet)

***

## Reference[](#reference "Link for Reference ")

### `<style>`[](#style "Link for this heading")

To add inline styles to your document, render the [built-in browser `<style>` component](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/style). You can render `<style>` from any component and React will [in certain cases](#special-rendering-behavior) place the corresponding DOM element in the document head and de-duplicate identical styles.

```
<style>{` p { color: red; } `}</style>
```

[See more examples below.](#usage)

#### Props[](#props "Link for Props ")

`<style>` supports all [common element props.](/reference/react-dom/components/common#props)

This special treatment comes with two caveats:

* React will ignore changes to props after the style has been rendered. (React will issue a warning in development if this happens.)
* React may leave the style in the DOM even after the component that rendered it has been unmounted.

***

## Usage[](#usage "Link for Usage ")

### Rendering an inline CSS stylesheet[](#rendering-an-inline-css-stylesheet "Link for Rendering an inline CSS stylesheet ")

If a component depends on certain CSS styles in order to be displayed correctly, you can render an inline stylesheet within the component.

If you supply an `href` and `precedence` prop, your component will suspend while the stylesheet is loading. (Even with inline stylesheets, there may be a loading time due to fonts and images that the stylesheet refers to.) The `href` prop should uniquely identify the stylesheet, because React will de-duplicate stylesheets that have the same `href`.

```
import ShowRenderedHTML from './ShowRenderedHTML.js';
import { useId } from 'react';

function PieChart({data, colors}) {
  const id = useId();
  const stylesheet = colors.map((color, index) =>
    `#${id} .color-${index}: \{ color: "${color}"; \}`
  ).join();
  return (
    <>
      <style href={"PieChart-" + JSON.stringify(colors)} precedence="medium">
        {stylesheet}
      </style>
      <svg id={id}>
        …
      </svg>
    </>
  );
}

export default function App() {
  return (
    <ShowRenderedHTML>
      <PieChart data="..." colors={['red', 'green', 'blue']} />
    </ShowRenderedHTML>
  );
}
```

[Previous\<script>](/reference/react-dom/components/script)

[Next\<title>](/reference/react-dom/components/title)

***

----
url: https://18.react.dev/reference/react/useInsertionEffect
----

[API Reference](/reference/react)

[Hooks](/reference/react/hooks)

# useInsertionEffect[](#undefined "Link for this heading")

### Pitfall

`useInsertionEffect` is for CSS-in-JS library authors. Unless you are working on a CSS-in-JS library and need a place to inject the styles, you probably want [`useEffect`](/reference/react/useEffect) or [`useLayoutEffect`](/reference/react/useLayoutEffect) instead.

`useInsertionEffect` allows inserting elements into the DOM before any layout Effects fire.

```
useInsertionEffect(setup, dependencies?)
```

* [Reference](#reference)
  * [`useInsertionEffect(setup, dependencies?)`](#useinsertioneffect)
* [Usage](#usage)
  * [Injecting dynamic styles from CSS-in-JS libraries](#injecting-dynamic-styles-from-css-in-js-libraries)

***

## Reference[](#reference "Link for Reference ")

### `useInsertionEffect(setup, dependencies?)`[](#useinsertioneffect "Link for this heading")

Call `useInsertionEffect` to insert styles before any Effects fire that may need to read layout:

```
import { useInsertionEffect } from 'react';



// Inside your CSS-in-JS library

function useCSS(rule) {

  useInsertionEffect(() => {

    // ... inject <style> tags here ...

  });

  return rule;

}
```

***

## Usage[](#usage "Link for Usage ")

### Injecting dynamic styles from CSS-in-JS libraries[](#injecting-dynamic-styles-from-css-in-js-libraries "Link for Injecting dynamic styles from CSS-in-JS libraries ")

Traditionally, you would style React components using plain CSS.

```
// In your JS file:

<button className="success" />



// In your CSS file:

.success { color: green; }
```

```
// Inside your CSS-in-JS library

let isInserted = new Set();

function useCSS(rule) {

  useInsertionEffect(() => {

    // As explained earlier, we don't recommend runtime injection of <style> tags.

    // But if you have to do it, then it's important to do in useInsertionEffect.

    if (!isInserted.has(rule)) {

      isInserted.add(rule);

      document.head.appendChild(getStyleForRule(rule));

    }

  });

  return rule;

}



function Button() {

  const className = useCSS('...');

  return <div className={className} />;

}
```

Similarly to `useEffect`, `useInsertionEffect` does not run on the server. If you need to collect which CSS rules have been used on the server, you can do it during rendering:

```
let collectedRulesSet = new Set();



function useCSS(rule) {

  if (typeof window === 'undefined') {

    collectedRulesSet.add(rule);

  }

  useInsertionEffect(() => {

    // ...

  });

  return rule;

}
```

[Read more about upgrading CSS-in-JS libraries with runtime injection to `useInsertionEffect`.](https://github.com/reactwg/react-18/discussions/110)

##### Deep Dive#### How is this better than injecting styles during rendering or useLayoutEffect?[](#how-is-this-better-than-injecting-styles-during-rendering-or-uselayouteffect "Link for How is this better than injecting styles during rendering or useLayoutEffect? ")

If you insert styles during rendering and React is processing a [non-blocking update,](/reference/react/useTransition#marking-a-state-update-as-a-non-blocking-transition) the browser will recalculate the styles every single frame while rendering a component tree, which can be **extremely slow.**

`useInsertionEffect` is better than inserting styles during [`useLayoutEffect`](/reference/react/useLayoutEffect) or [`useEffect`](/reference/react/useEffect) because it ensures that by the time other Effects run in your components, the `<style>` tags have already been inserted. Otherwise, layout calculations in regular Effects would be wrong due to outdated styles.

[PrevioususeImperativeHandle](/reference/react/useImperativeHandle)

[NextuseLayoutEffect](/reference/react/useLayoutEffect)

***

----
url: https://18.react.dev/reference/react/memo
----

[API Reference](/reference/react)

[APIs](/reference/react/apis)

# memo[](#undefined "Link for this heading")

`memo` lets you skip re-rendering a component when its props are unchanged.

```
const MemoizedComponent = memo(SomeComponent, arePropsEqual?)
```


* [Troubleshooting](#troubleshooting)
  * [My component re-renders when a prop is an object, array, or function](#my-component-rerenders-when-a-prop-is-an-object-or-array)

***

## Reference[](#reference "Link for Reference ")

### `memo(Component, arePropsEqual?)`[](#memo "Link for this heading")

Wrap a component in `memo` to get a *memoized* version of that component. This memoized version of your component will usually not be re-rendered when its parent component is re-rendered as long as its props have not changed. But React may still re-render it: memoization is a performance optimization, not a guarantee.

```
import { memo } from 'react';



const SomeComponent = memo(function SomeComponent(props) {

  // ...

});
```

[See more examples below.](#usage)

#### Parameters[](#parameters "Link for Parameters ")

* `Component`: The component that you want to memoize. The `memo` does not modify this component, but returns a new, memoized component instead. Any valid React component, including functions and [`forwardRef`](/reference/react/forwardRef) components, is accepted.

* **optional** `arePropsEqual`: A function that accepts two arguments: the component’s previous props, and its new props. It should return `true` if the old and new props are equal: that is, if the component will render the same output and behave in the same way with the new props as with the old. Otherwise it should return `false`. Usually, you will not specify this function. By default, React will compare each prop with [`Object.is`.](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is)

#### Returns[](#returns "Link for Returns ")

`memo` returns a new React component. It behaves the same as the component provided to `memo` except that React will not always re-render it when its parent is being re-rendered unless its props have changed.

***

## Usage[](#usage "Link for Usage ")

### Skipping re-rendering when props are unchanged[](#skipping-re-rendering-when-props-are-unchanged "Link for Skipping re-rendering when props are unchanged ")

React normally re-renders a component whenever its parent re-renders. With `memo`, you can create a component that React will not re-render when its parent re-renders so long as its new props are the same as the old props. Such a component is said to be *memoized*.

To memoize a component, wrap it in `memo` and use the value that it returns in place of your original component:

```
const Greeting = memo(function Greeting({ name }) {

  return <h1>Hello, {name}!</h1>;

});



export default Greeting;
```

A React component should always have [pure rendering logic.](/learn/keeping-components-pure) This means that it must return the same output if its props, state, and context haven’t changed. By using `memo`, you are telling React that your component complies with this requirement, so React doesn’t need to re-render as long as its props haven’t changed. Even with `memo`, your component will re-render if its own state changes or if a context that it’s using changes.

In this example, notice that the `Greeting` component re-renders whenever `name` is changed (because that’s one of its props), but not when `address` is changed (because it’s not passed to `Greeting` as a prop):

```
import { memo, useState } from 'react';

export default function MyApp() {
  const [name, setName] = useState('');
  const [address, setAddress] = useState('');
  return (
    <>
      <label>
        Name{': '}
        <input value={name} onChange={e => setName(e.target.value)} />
      </label>
      <label>
        Address{': '}
        <input value={address} onChange={e => setAddress(e.target.value)} />
      </label>
      <Greeting name={name} />
    </>
  );
}

const Greeting = memo(function Greeting({ name }) {
  console.log("Greeting was rendered at", new Date().toLocaleTimeString());
  return <h3>Hello{name && ', '}{name}!</h3>;
});
```

***

### Updating a memoized component using state[](#updating-a-memoized-component-using-state "Link for Updating a memoized component using state ")

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

```
import { memo, useState } from 'react';

export default function MyApp() {
  const [name, setName] = useState('');
  const [address, setAddress] = useState('');
  return (
    <>
      <label>
        Name{': '}
        <input value={name} onChange={e => setName(e.target.value)} />
      </label>
      <label>
        Address{': '}
        <input value={address} onChange={e => setAddress(e.target.value)} />
      </label>
      <Greeting name={name} />
    </>
  );
}

const Greeting = memo(function Greeting({ name }) {
  console.log('Greeting was rendered at', new Date().toLocaleTimeString());
  const [greeting, setGreeting] = useState('Hello');
  return (
    <>
      <h3>{greeting}{name && ', '}{name}!</h3>
      <GreetingSelector value={greeting} onChange={setGreeting} />
    </>
  );
});

function GreetingSelector({ value, onChange }) {
  return (
    <>
      <label>
        <input
          type="radio"
          checked={value === 'Hello'}
          onChange={e => onChange('Hello')}
        />
        Regular greeting
      </label>
      <label>
        <input
          type="radio"
          checked={value === 'Hello and welcome'}
          onChange={e => onChange('Hello and welcome')}
        />
        Enthusiastic greeting
      </label>
    </>
  );
}
```

If you set a state variable to its current value, React will skip re-rendering your component even without `memo`. You may still see your component function being called an extra time, but the result will be discarded.

***

### Updating a memoized component using a context[](#updating-a-memoized-component-using-a-context "Link for Updating a memoized component using a context ")

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

```
import { createContext, memo, useContext, useState } from 'react';

const ThemeContext = createContext(null);

export default function MyApp() {
  const [theme, setTheme] = useState('dark');

  function handleClick() {
    setTheme(theme === 'dark' ? 'light' : 'dark'); 
  }

  return (
    <ThemeContext.Provider value={theme}>
      <button onClick={handleClick}>
        Switch theme
      </button>
      <Greeting name="Taylor" />
    </ThemeContext.Provider>
  );
}

const Greeting = memo(function Greeting({ name }) {
  console.log("Greeting was rendered at", new Date().toLocaleTimeString());
  const theme = useContext(ThemeContext);
  return (
    <h3 className={theme}>Hello, {name}!</h3>
  );
});
```

To make your component re-render only when a *part* of some context changes, split your component in two. Read what you need from the context in the outer component, and pass it down to a memoized child as a prop.

***

### Minimizing props changes[](#minimizing-props-changes "Link for Minimizing props changes ")

When you use `memo`, your component re-renders whenever any prop is not *shallowly equal* to what it was previously. This means that React compares every prop in your component with its previous value using the [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) comparison. Note that `Object.is(3, 3)` is `true`, but `Object.is({}, {})` is `false`.

To get the most out of `memo`, minimize the times that the props change. For example, if the prop is an object, prevent the parent component from re-creating that object every time by using [`useMemo`:](/reference/react/useMemo)

```
function Page() {

  const [name, setName] = useState('Taylor');

  const [age, setAge] = useState(42);



  const person = useMemo(

    () => ({ name, age }),

    [name, age]

  );



  return <Profile person={person} />;

}



const Profile = memo(function Profile({ person }) {

  // ...

});
```

A better way to minimize props changes is to make sure the component accepts the minimum necessary information in its props. For example, it could accept individual values instead of a whole object:

```
function Page() {

  const [name, setName] = useState('Taylor');

  const [age, setAge] = useState(42);

  return <Profile name={name} age={age} />;

}



const Profile = memo(function Profile({ name, age }) {

  // ...

});
```

Even individual values can sometimes be projected to ones that change less frequently. For example, here a component accepts a boolean indicating the presence of a value rather than the value itself:

```
function GroupsLanding({ person }) {

  const hasGroups = person.groups !== null;

  return <CallToAction hasGroups={hasGroups} />;

}



const CallToAction = memo(function CallToAction({ hasGroups }) {

  // ...

});
```

When you need to pass a function to memoized component, either declare it outside your component so that it never changes, or [`useCallback`](/reference/react/useCallback#skipping-re-rendering-of-components) to cache its definition between re-renders.

***

### Specifying a custom comparison function[](#specifying-a-custom-comparison-function "Link for Specifying a custom comparison function ")

In rare cases it may be infeasible to minimize the props changes of a memoized component. In that case, you can provide a custom comparison function, which React will use to compare the old and new props instead of using shallow equality. This function is passed as a second argument to `memo`. It should return `true` only if the new props would result in the same output as the old props; otherwise it should return `false`.

```
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;

    })

  );

}
```

If you do this, use the Performance panel in your browser developer tools to make sure that your comparison function is actually faster than re-rendering the component. You might be surprised.

When you do performance measurements, make sure that React is running in the production mode.

### Pitfall

If you provide a custom `arePropsEqual` implementation, **you must compare every prop, including functions.** Functions often [close over](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures) the props and state of parent components. If you return `true` when `oldProps.onClick !== newProps.onClick`, your component will keep “seeing” the props and state from a previous render inside its `onClick` handler, leading to very confusing bugs.

Avoid doing deep equality checks inside `arePropsEqual` unless you are 100% sure that the data structure you’re working with has a known limited depth. **Deep equality checks can become incredibly slow** and can freeze your app for many seconds if someone changes the data structure later.

***

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### My component re-renders when a prop is an object, array, or function[](#my-component-rerenders-when-a-prop-is-an-object-or-array "Link for My component re-renders when a prop is an object, array, or function ")

React compares old and new props by shallow equality: that is, it considers whether each new prop is reference-equal to the old prop. If you create a new object or array each time the parent is re-rendered, even if the individual elements are each the same, React will still consider it to be changed. Similarly, if you create a new function when rendering the parent component, React will consider it to have changed even if the function has the same definition. To avoid this, [simplify props or memoize props in the parent component](#minimizing-props-changes).

[Previouslazy](/reference/react/lazy)

[NextstartTransition](/reference/react/startTransition)

***

----
url: https://legacy.reactjs.org/tips/controlled-input-null-value.html
----

[API Reference](/reference/react)

[Components](/reference/react-dom/components)

# \<input>[](#undefined "Link for this heading")

The [built-in browser `<input>` component](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input) lets you render different kinds of form inputs.

```
<input />
```

***

## Reference[](#reference "Link for Reference ")

### `<input>`[](#input "Link for this heading")

To display an input, render the [built-in browser `<input>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input) component.

```
<input name="myInput" />
```

***

## Usage[](#usage "Link for Usage ")

### Displaying inputs of different types[](#displaying-inputs-of-different-types "Link for Displaying inputs of different types ")

To display an input, render an `<input>` component. By default, it will be a text input. You can pass `type="checkbox"` for a checkbox, `type="radio"` for a radio button, [or one of the other input types.](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#input_types)

```
export default function MyForm() {
  return (
    <>
      <label>
        Text input: <input name="myInput" />
      </label>
      <hr />
      <label>
        Checkbox: <input type="checkbox" name="myCheckbox" />
      </label>
      <hr />
      <p>
        Radio buttons:
        <label>
          <input type="radio" name="myRadio" value="option1" />
          Option 1
        </label>
        <label>
          <input type="radio" name="myRadio" value="option2" />
          Option 2
        </label>
        <label>
          <input type="radio" name="myRadio" value="option3" />
          Option 3
        </label>
      </p>
    </>
  );
}
```

***

### Providing a label for an input[](#providing-a-label-for-an-input "Link for Providing a label for an input ")

Typically, you will place every `<input>` inside a [`<label>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/label) tag. This tells the browser that this label is associated with that input. When the user clicks the label, the browser will automatically focus the input. It’s also essential for accessibility: a screen reader will announce the label caption when the user focuses the associated input.

If you can’t nest `<input>` into a `<label>`, associate them by passing the same ID to `<input id>` and [`<label htmlFor>`.](https://developer.mozilla.org/en-US/docs/Web/API/HTMLLabelElement/htmlFor) To avoid conflicts between multiple instances of one component, generate such an ID with [`useId`.](/reference/react/useId)

```
import { useId } from 'react';

export default function Form() {
  const ageInputId = useId();
  return (
    <>
      <label>
        Your first name:
        <input name="firstName" />
      </label>
      <hr />
      <label htmlFor={ageInputId}>Your age:</label>
      <input id={ageInputId} name="age" type="number" />
    </>
  );
}
```

***

### Providing an initial value for an input[](#providing-an-initial-value-for-an-input "Link for Providing an initial value for an input ")

You can optionally specify the initial value for any input. Pass it as the `defaultValue` string for text inputs. Checkboxes and radio buttons should specify the initial value with the `defaultChecked` boolean instead.

```
export default function MyForm() {
  return (
    <>
      <label>
        Text input: <input name="myInput" defaultValue="Some initial value" />
      </label>
      <hr />
      <label>
        Checkbox: <input type="checkbox" name="myCheckbox" defaultChecked={true} />
      </label>
      <hr />
      <p>
        Radio buttons:
        <label>
          <input type="radio" name="myRadio" value="option1" />
          Option 1
        </label>
        <label>
          <input
            type="radio"
            name="myRadio"
            value="option2"
            defaultChecked={true}
          />
          Option 2
        </label>
        <label>
          <input type="radio" name="myRadio" value="option3" />
          Option 3
        </label>
      </p>
    </>
  );
}
```

***

### Reading the input values when submitting a form[](#reading-the-input-values-when-submitting-a-form "Link for Reading the input values when submitting a form ")

Add a [`<form>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form) around your inputs with a [`<button type="submit">`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button) inside. It will call your `<form onSubmit>` event handler. By default, the browser will send the form data to the current URL and refresh the page. You can override that behavior by calling `e.preventDefault()`. Read the form data with [`new FormData(e.target)`](https://developer.mozilla.org/en-US/docs/Web/API/FormData).

```
export default function MyForm() {
  function handleSubmit(e) {
    // Prevent the browser from reloading the page
    e.preventDefault();

    // Read the form data
    const form = e.target;
    const formData = new FormData(form);

    // You can pass formData as a fetch body directly:
    fetch('/some-api', { method: form.method, body: formData });

    // Or you can work with it as a plain object:
    const formJson = Object.fromEntries(formData.entries());
    console.log(formJson);
  }

  return (
    <form method="post" onSubmit={handleSubmit}>
      <label>
        Text input: <input name="myInput" defaultValue="Some initial value" />
      </label>
      <hr />
      <label>
        Checkbox: <input type="checkbox" name="myCheckbox" defaultChecked={true} />
      </label>
      <hr />
      <p>
        Radio buttons:
        <label><input type="radio" name="myRadio" value="option1" /> Option 1</label>
        <label><input type="radio" name="myRadio" value="option2" defaultChecked={true} /> Option 2</label>
        <label><input type="radio" name="myRadio" value="option3" /> Option 3</label>
      </p>
      <hr />
      <button type="reset">Reset form</button>
      <button type="submit">Submit form</button>
    </form>
  );
}
```

### Note

Give a `name` to every `<input>`, for example `<input name="firstName" defaultValue="Taylor" />`. The `name` you specified will be used as a key in the form data, for example `{ firstName: "Taylor" }`.

### Pitfall

By default, a `<button>` inside a `<form>` without a `type` attribute will submit it. This can be surprising! If you have your own custom `Button` React component, consider using [`<button type="button">`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button) instead of `<button>` (with no type). Then, to be explicit, use `<button type="submit">` for buttons that *are* supposed to submit the form.

***

### Controlling an input with a state variable[](#controlling-an-input-with-a-state-variable "Link for Controlling an input with a state variable ")

An input like `<input />` is *uncontrolled.* Even if you [pass an initial value](#providing-an-initial-value-for-an-input) like `<input defaultValue="Initial text" />`, your JSX only specifies the initial value. It does not control what the value should be right now.

**To render a *controlled* input, pass the `value` prop to it (or `checked` for checkboxes and radios).** React will force the input to always have the `value` you passed. Usually, you would do this by declaring a [state variable:](/reference/react/useState)

```
function Form() {

  const [firstName, setFirstName] = useState(''); // Declare a state variable...

  // ...

  return (

    <input

      value={firstName} // ...force the input's value to match the state variable...

      onChange={e => setFirstName(e.target.value)} // ... and update the state variable on any edits!

    />

  );

}
```

A controlled input makes sense if you needed state anyway—for example, to re-render your UI on every edit:

```
function Form() {

  const [firstName, setFirstName] = useState('');

  return (

    <>

      <label>

        First name:

        <input value={firstName} onChange={e => setFirstName(e.target.value)} />

      </label>

      {firstName !== '' && <p>Your name is {firstName}.</p>}

      ...
```

It’s also useful if you want to offer multiple ways to adjust the input state (for example, by clicking a button):

```
function Form() {

  // ...

  const [age, setAge] = useState('');

  const ageAsNumber = Number(age);

  return (

    <>

      <label>

        Age:

        <input

          value={age}

          onChange={e => setAge(e.target.value)}

          type="number"

        />

        <button onClick={() => setAge(ageAsNumber + 10)}>

          Add 10 years

        </button>
```

The `value` you pass to controlled components should not be `undefined` or `null`. If you need the initial value to be empty (such as with the `firstName` field below), initialize your state variable to an empty string (`''`).

```
import { useState } from 'react';

export default function Form() {
  const [firstName, setFirstName] = useState('');
  const [age, setAge] = useState('20');
  const ageAsNumber = Number(age);
  return (
    <>
      <label>
        First name:
        <input
          value={firstName}
          onChange={e => setFirstName(e.target.value)}
        />
      </label>
      <label>
        Age:
        <input
          value={age}
          onChange={e => setAge(e.target.value)}
          type="number"
        />
        <button onClick={() => setAge(ageAsNumber + 10)}>
          Add 10 years
        </button>
      </label>
      {firstName !== '' &&
        <p>Your name is {firstName}.</p>
      }
      {ageAsNumber > 0 &&
        <p>Your age is {ageAsNumber}.</p>
      }
    </>
  );
}
```

### Pitfall

**If you pass `value` without `onChange`, it will be impossible to type into the input.** When you control an input by passing some `value` to it, you *force* it to always have the value you passed. So if you pass a state variable as a `value` but forget to update that state variable synchronously during the `onChange` event handler, React will revert the input after every keystroke back to the `value` that you specified.

***

### Optimizing re-rendering on every keystroke[](#optimizing-re-rendering-on-every-keystroke "Link for Optimizing re-rendering on every keystroke ")

When you use a controlled input, you set the state on every keystroke. If the component containing your state re-renders a large tree, this can get slow. There’s a few ways you can optimize re-rendering performance.

For example, suppose you start with a form that re-renders all page content on every keystroke:

```
function App() {

  const [firstName, setFirstName] = useState('');

  return (

    <>

      <form>

        <input value={firstName} onChange={e => setFirstName(e.target.value)} />

      </form>

      <PageContent />

    </>

  );

}
```

Since `<PageContent />` doesn’t rely on the input state, you can move the input state into its own component:

```
function App() {

  return (

    <>

      <SignupForm />

      <PageContent />

    </>

  );

}



function SignupForm() {

  const [firstName, setFirstName] = useState('');

  return (

    <form>

      <input value={firstName} onChange={e => setFirstName(e.target.value)} />

    </form>

  );

}
```

This significantly improves performance because now only `SignupForm` re-renders on every keystroke.

If there is no way to avoid re-rendering (for example, if `PageContent` depends on the search input’s value), [`useDeferredValue`](/reference/react/useDeferredValue#deferring-re-rendering-for-a-part-of-the-ui) lets you keep the controlled input responsive even in the middle of a large re-render.

***

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### My text input doesn’t update when I type into it[](#my-text-input-doesnt-update-when-i-type-into-it "Link for My text input doesn’t update when I type into it ")

If you render an input with `value` but no `onChange`, you will see an error in the console:

```
// 🔴 Bug: controlled text input with no onChange handler

<input value={something} />
```

Console

You provided a `value` prop to a form field without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultValue`. Otherwise, set either `onChange` or `readOnly`.

As the error message suggests, if you only wanted to [specify the *initial* value,](#providing-an-initial-value-for-an-input) pass `defaultValue` instead:

```
// ✅ Good: uncontrolled input with an initial value

<input defaultValue={something} />
```

If you want [to control this input with a state variable,](#controlling-an-input-with-a-state-variable) specify an `onChange` handler:

```
// ✅ Good: controlled input with onChange

<input value={something} onChange={e => setSomething(e.target.value)} />
```

If the value is intentionally read-only, add a `readOnly` prop to suppress the error:

```
// ✅ Good: readonly controlled input without on change

<input value={something} readOnly={true} />
```

***

### My checkbox doesn’t update when I click on it[](#my-checkbox-doesnt-update-when-i-click-on-it "Link for My checkbox doesn’t update when I click on it ")

If you render a checkbox with `checked` but no `onChange`, you will see an error in the console:

```
// 🔴 Bug: controlled checkbox with no onChange handler

<input type="checkbox" checked={something} />
```

Console

You provided a `checked` prop to a form field without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultChecked`. Otherwise, set either `onChange` or `readOnly`.

As the error message suggests, if you only wanted to [specify the *initial* value,](#providing-an-initial-value-for-an-input) pass `defaultChecked` instead:

```
// ✅ Good: uncontrolled checkbox with an initial value

<input type="checkbox" defaultChecked={something} />
```

If you want [to control this checkbox with a state variable,](#controlling-an-input-with-a-state-variable) specify an `onChange` handler:

```
// ✅ Good: controlled checkbox with onChange

<input type="checkbox" checked={something} onChange={e => setSomething(e.target.checked)} />
```

### Pitfall

You need to read `e.target.checked` rather than `e.target.value` for checkboxes.

If the checkbox is intentionally read-only, add a `readOnly` prop to suppress the error:

```
// ✅ Good: readonly controlled input without on change

<input type="checkbox" checked={something} readOnly={true} />
```

***

### My input caret jumps to the beginning on every keystroke[](#my-input-caret-jumps-to-the-beginning-on-every-keystroke "Link for My input caret jumps to the beginning on every keystroke ")

If you [control an input,](#controlling-an-input-with-a-state-variable) you must update its state variable to the input’s value from the DOM during `onChange`.

You can’t update it to something other than `e.target.value` (or `e.target.checked` for checkboxes):

```
function handleChange(e) {

  // 🔴 Bug: updating an input to something other than e.target.value

  setFirstName(e.target.value.toUpperCase());

}
```

You also can’t update it asynchronously:

```
function handleChange(e) {

  // 🔴 Bug: updating an input asynchronously

  setTimeout(() => {

    setFirstName(e.target.value);

  }, 100);

}
```

To fix your code, update it synchronously to `e.target.value`:

```
function handleChange(e) {

  // ✅ Updating a controlled input to e.target.value synchronously

  setFirstName(e.target.value);

}
```

If this doesn’t fix the problem, it’s possible that the input gets removed and re-added from the DOM on every keystroke. This can happen if you’re accidentally [resetting state](/learn/preserving-and-resetting-state) on every re-render, for example if the input or one of its parents always receives a different `key` attribute, or if you nest component function definitions (which is not supported and causes the “inner” component to always be considered a different tree).

***

***

----
url: https://18.react.dev/learn/add-react-to-an-existing-project
----

1. **Build the React part of your app** using one of the [React-based frameworks](/learn/start-a-new-react-project).
2. **Specify `/some-app` as the *base path*** in your framework’s configuration (here’s how: [Next.js](https://nextjs.org/docs/api-reference/next.config.js/basepath), [Gatsby](https://www.gatsbyjs.com/docs/how-to/previews-deploys-hosting/path-prefix/)).
3. **Configure your server or a proxy** so that all requests under `/some-app/` are handled by your React app.

This ensures the React part of your app can [benefit from the best practices](/learn/start-a-new-react-project#can-i-use-react-without-a-framework) baked into those frameworks.

* **If your app doesn’t have an existing setup for compiling JavaScript modules,** set it up with [Vite](https://vitejs.dev/). The Vite community maintains [many integrations with backend frameworks](https://github.com/vitejs/awesome-vite#integrations-with-backends), including Rails, Django, and Laravel. If your backend framework is not listed, [follow this guide](https://vitejs.dev/guide/backend-integration.html) to manually integrate Vite builds with your backend.

To check whether your setup works, run this command in your project folder:

Terminal

npm install react react-dom

Then add these lines of code at the top of your main JavaScript file (it might be called `index.js` or `main.js`):

[Fork](https://codesandbox.io/api/v1/sandboxes/define?parameters=N4IgZglgNgpgziAXKOAnAxgeggOwCYwAeAdAFYLIjoD2OALjPUiBALYAO1qdABMD-lQwAhgwBK1arwC-PMKmqseAciHD0dALR5FmdFAiM6ygNwAdHBcyYeAYVjDUPOgAsYPIhDh1cAcx4AEgAqALIAMgK0DPQWOugArqxGxABG1HgAnsS4ODCoweE8ALwqADx4EABuPBB4RWYgwuzsDQB8pZgVla2mFlY2YowEThnU8U6D6rw0HLRGNTjeIngWNIu8ClLFAmriknQAFHGJyb4wdACisEn0AEIZAJJ4B8pN7MoAlB_mOJt0xEJ8HkDqUXABGVoBGBQKDUAA0PAA7lwoHgOuDWt8LCA4Sw4LdcI4MkgwMIoHAYNJcex1ABrYRnMhwWhIUBraJ0ZjACw8HgNHDCJINRB8kBqDTEAiVBpwnmiyp5OAQWjC0UABmIGrVMrlDVYwlwqoamDQWFwBBI5B1OF5DTgggg7DocFV3JtvNF3kcdCNYpEGk09tQjudPC93GtHtFKXi0BWSFF4q0QZDcB4MbjkY9DQY3l9ScDDqdadzvE0mkYlSK5B0rCztpAMFIMA0-f9yaLoabLZ9IDlVN1IAI7CGjHQhhdCbdUYaSd9AD0wQAOTWa-uJ9vaRQL5er7U4uUNgsp4sLgCse4a_dl7oaUoAIjAR0CcOP4K7pBZpDi8QSBahiUQUlyUpal4hSAwzSBEgXDoVgoFZKgoiMZhSgAQnvAB5WwggATQABQuHhYPg1oLFBOCoB4KBhBwXx6kbSwQDInBQWWFjeVKJI6GEAQXEcCk6AYgBVIIADFNCXNo5S485eIFJIGMqQxEU4CMQEiegjAYxFalcIopQgdAYE0XS8FcBFcAgHwyULMkYCKME12YmSfDoWBWnvagEhuOgOjcjzyMwNxhDwFjSjSTIOJ4coqhqOpZ32NoOi6cLMEijI0pIqBWh_Lw_yJEkyQpKkWGg4hssQ9kUMQEB0KwnCCKI7LwpamSQrC0oApgVoQgyHg3n86yPPRdiZIy6LOLQ8seFwsYnE8bw_B4Gkzk0jkeAOXBnBcLwPEIQV2FgSzeDOUMhCO9QYDwD4eHLaKOgmoK2pwPL8UJACipA0rTRNOgMlgOBiHQOAKDZZCmFqgAqPg5TSQhAwgAAvPwRTSVBhk0eGfk_SwcAy2H3TAKJNFJVhoAyEU4FouBAzyCAwB-Xl9VQXxcBFAAmNV2EIJmVtCio6JFNUcb6HBwUJ5nHDZnBNDoah2GFvnifoRGkZgTmOZ50W8ZcDnJZ4FmZblhWlblFXk2RjWeC57WvzFlwAGYDaN3ATcVngRfNkmlXVkVlztnBcYsFwABYXelt35Y9r2iZ9q3_YANkD4PxbPCPWaj03PeV-O_Z4MFQ5Th3E4z43o7NuPVd962wS13n7bxmgCANi21dr4gOZgVgdYseIqOnfm8EF3xNFwAxckDHjuE57mG6DsW3oKz6gOKylSoYDgaIYZhBBEBhNALN4QGkIA\&query=file%3D%252Fsrc%252Findex.js%26utm_medium%3Dsandpack\&environment=create-react-app "Open in CodeSandbox")

```
import { createRoot } from 'react-dom/client';

// Clear the existing HTML content
document.body.innerHTML = '<div id="app"></div>';

// Render your React component instead
const root = createRoot(document.getElementById('app'));
root.render(<h1>Hello, world</h1>);
```

If the entire content of your page was replaced by a “Hello, world!”, everything worked! Keep reading.

### Note

Integrating a modular JavaScript environment into an existing project for the first time can feel intimidating, but it’s worth it! If you get stuck, try our [community resources](/community) or the [Vite Chat](https://chat.vitejs.dev/).

### Step 2: Render React components anywhere on the page[](#step-2-render-react-components-anywhere-on-the-page "Link for Step 2: Render React components anywhere on the page ")

In the previous step, you put this code at the top of your main file:

```
import { createRoot } from 'react-dom/client';



// Clear the existing HTML content

document.body.innerHTML = '<div id="app"></div>';



// Render your React component instead

const root = createRoot(document.getElementById('app'));

root.render(<h1>Hello, world</h1>);
```

Of course, you don’t actually want to clear the existing HTML content!

Delete this code.

Instead, you probably want to render your React components in specific places in your HTML. Open your HTML page (or the server templates that generate it) and add a unique [`id`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/id) attribute to any tag, for example:

```
<!-- ... somewhere in your html ... -->

<nav id="navigation"></nav>

<!-- ... more html ... -->
```

This lets you find that HTML element with [`document.getElementById`](https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementById) and pass it to [`createRoot`](/reference/react-dom/client/createRoot) so that you can render your own React component inside:

```
import { createRoot } from 'react-dom/client';

function NavigationBar() {
  // TODO: Actually implement a navigation bar
  return <h1>Hello from React!</h1>;
}

const domNode = document.getElementById('navigation');
const root = createRoot(domNode);
root.render(<NavigationBar />);
```

Notice how the original HTML content from `index.html` is preserved, but your own `NavigationBar` React component now appears inside the `<nav id="navigation">` from your HTML. Read the [`createRoot` usage documentation](/reference/react-dom/client/createRoot#rendering-a-page-partially-built-with-react) to learn more about rendering React components inside an existing HTML page.

When you adopt React in an existing project, it’s common to start with small interactive components (like buttons), and then gradually keep “moving upwards” until eventually your entire page is built with React. If you ever reach that point, we recommend migrating to [a React framework](/learn/start-a-new-react-project) right after to get the most out of React.

## Using React Native in an existing native mobile app[](#using-react-native-in-an-existing-native-mobile-app "Link for Using React Native in an existing native mobile app ")

[React Native](https://reactnative.dev/) can also be integrated into existing native apps incrementally. If you have an existing native app for Android (Java or Kotlin) or iOS (Objective-C or Swift), [follow this guide](https://reactnative.dev/docs/integration-with-existing-apps) to add a React Native screen to it.

[PreviousStart a New React Project](/learn/start-a-new-react-project)

[NextEditor Setup](/learn/editor-setup)

***

----
url: https://legacy.reactjs.org/docs/components-and-props.html
----

> These docs are old and won’t be updated. Go to [react.dev](https://react.dev/) for the new React docs.
>
> These new documentation pages teach modern React and include live examples:
>
> * [Your First Component](https://react.dev/learn/your-first-component)
> * [Passing Props to a Component](https://react.dev/learn/passing-props-to-a-component)

Components let you split the UI into independent, reusable pieces, and think about each piece in isolation. This page provides an introduction to the idea of components. You can find a [detailed component API reference here](/docs/react-component.html).

Conceptually, components are like JavaScript functions. They accept arbitrary inputs (called “props”) and return React elements describing what should appear on the screen.

## [](#function-and-class-components)Function and Class Components

The simplest way to define a component is to write a JavaScript function:

```
function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}
```

This function is a valid React component because it accepts a single “props” (which stands for properties) object argument with data and returns a React element. We call such components “function components” because they are literally JavaScript functions.

You can also use an [ES6 class](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Classes) to define a component:

```
class Welcome extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}
```

The above two components are equivalent from React’s point of view.

Function and Class components both have some additional features that we will discuss in the [next sections](/docs/state-and-lifecycle.html).

## [](#rendering-a-component)Rendering a Component

Previously, we only encountered React elements that represent DOM tags:

```
const element = <div />;
```

However, elements can also represent user-defined components:

```
const element = <Welcome name="Sara" />;
```

When React sees an element representing a user-defined component, it passes JSX attributes and children to this component as a single object. We call this object “props”.

For example, this code renders “Hello, Sara” on the page:

```
function Welcome(props) {  return <h1>Hello, {props.name}</h1>;
}

const root = ReactDOM.createRoot(document.getElementById('root'));
const element = <Welcome name="Sara" />;root.render(element);
```

**[Try it on CodePen](https://codepen.io/gaearon/pen/YGYmEG?editors=1010)**

Let’s recap what happens in this example:

1. We call `root.render()` with the `<Welcome name="Sara" />` element.
2. React calls the `Welcome` component with `{name: 'Sara'}` as the props.
3. Our `Welcome` component returns a `<h1>Hello, Sara</h1>` element as the result.
4. React DOM efficiently updates the DOM to match `<h1>Hello, Sara</h1>`.

> **Note:** Always start component names with a capital letter.
>
> React treats components starting with lowercase letters as DOM tags. For example, `<div />` represents an HTML div tag, but `<Welcome />` represents a component and requires `Welcome` to be in scope.
>
> To learn more about the reasoning behind this convention, please read [JSX In Depth](/docs/jsx-in-depth.html#user-defined-components-must-be-capitalized).

## [](#composing-components)Composing Components

Components can refer to other components in their output. This lets us use the same component abstraction for any level of detail. A button, a form, a dialog, a screen: in React apps, all those are commonly expressed as components.

For example, we can create an `App` component that renders `Welcome` many times:

```
function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

function App() {
  return (
    <div>
      <Welcome name="Sara" />      <Welcome name="Cahal" />      <Welcome name="Edite" />    </div>
  );
}
```

**[Try it on CodePen](https://codepen.io/gaearon/pen/KgQKPr?editors=1010)**

Typically, new React apps have a single `App` component at the very top. However, if you integrate React into an existing app, you might start bottom-up with a small component like `Button` and gradually work your way to the top of the view hierarchy.

## [](#extracting-components)Extracting Components

Don’t be afraid to split components into smaller components.

For example, consider this `Comment` component:

```
function Comment(props) {
  return (
    <div className="Comment">
      <div className="UserInfo">
        <img className="Avatar"
          src={props.author.avatarUrl}
          alt={props.author.name}
        />
        <div className="UserInfo-name">
          {props.author.name}
        </div>
      </div>
      <div className="Comment-text">
        {props.text}
      </div>
      <div className="Comment-date">
        {formatDate(props.date)}
      </div>
    </div>
  );
}
```

**[Try it on CodePen](https://codepen.io/gaearon/pen/VKQwEo?editors=1010)**

It accepts `author` (an object), `text` (a string), and `date` (a date) as props, and describes a comment on a social media website.

This component can be tricky to change because of all the nesting, and it is also hard to reuse individual parts of it. Let’s extract a few components from it.

First, we will extract `Avatar`:

```
function Avatar(props) {
  return (
    <img className="Avatar"      src={props.user.avatarUrl}      alt={props.user.name}    />  );
}
```

The `Avatar` doesn’t need to know that it is being rendered inside a `Comment`. This is why we have given its prop a more generic name: `user` rather than `author`.

We recommend naming props from the component’s own point of view rather than the context in which it is being used.

We can now simplify `Comment` a tiny bit:

```
function Comment(props) {
  return (
    <div className="Comment">
      <div className="UserInfo">
        <Avatar user={props.author} />        <div className="UserInfo-name">
          {props.author.name}
        </div>
      </div>
      <div className="Comment-text">
        {props.text}
      </div>
      <div className="Comment-date">
        {formatDate(props.date)}
      </div>
    </div>
  );
}
```

Next, we will extract a `UserInfo` component that renders an `Avatar` next to the user’s name:

```
function UserInfo(props) {
  return (
    <div className="UserInfo">      <Avatar user={props.user} />      <div className="UserInfo-name">        {props.user.name}      </div>    </div>  );
}
```

This lets us simplify `Comment` even further:

```
function Comment(props) {
  return (
    <div className="Comment">
      <UserInfo user={props.author} />      <div className="Comment-text">
        {props.text}
      </div>
      <div className="Comment-date">
        {formatDate(props.date)}
      </div>
    </div>
  );
}
```

**[Try it on CodePen](https://codepen.io/gaearon/pen/rrJNJY?editors=1010)**

Extracting components might seem like grunt work at first, but having a palette of reusable components pays off in larger apps. A good rule of thumb is that if a part of your UI is used several times (`Button`, `Panel`, `Avatar`), or is complex enough on its own (`App`, `FeedStory`, `Comment`), it is a good candidate to be extracted to a separate component.

## [](#props-are-read-only)Props are Read-Only

Whether you declare a component [as a function or a class](#function-and-class-components), it must never modify its own props. Consider this `sum` function:

```
function sum(a, b) {
  return a + b;
}
```

Such functions are called [“pure”](https://en.wikipedia.org/wiki/Pure_function) because they do not attempt to change their inputs, and always return the same result for the same inputs.

In contrast, this function is impure because it changes its own input:

```
function withdraw(account, amount) {
  account.total -= amount;
}
```

React is pretty flexible but it has a single strict rule:

**All React components must act like pure functions with respect to their props.**

Of course, application UIs are dynamic and change over time. In the [next section](/docs/state-and-lifecycle.html), we will introduce a new concept of “state”. State allows React components to change their output over time in response to user actions, network responses, and anything else, without violating this rule.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/components-and-props.md)

* Previous article

  [Rendering Elements](/docs/rendering-elements.html)

* Next article

  [State and Lifecycle](/docs/state-and-lifecycle.html)

----
url: https://legacy.reactjs.org/blog/2014/07/25/react-v0.11.1.html
----

July 25, 2014 by [Paul O’Shannessy](https://twitter.com/zpao)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

Today we’re releasing React v0.11.1 to address a few small issues. Thanks to everybody who has reported them as they’ve begun upgrading.

The first of these is the most major and resulted in a regression with the use of `setState` inside `componentWillMount` when using React on the server. These `setState` calls are batched into the initial render. A change we made to our batching code resulted in this path hitting DOM specific code when run server-side, in turn throwing an error as `document` is not defined.

There are several fixes we’re including in v0.11.1 that are focused around the newly supported `event.getModifierState()` function. We made some adjustments to improve this cross-browser standardization.

The final fix we’re including is to better support a workaround for some IE8 behavior. The edge-case bug we’re fixing was also present in v0.9 and v0.10, so while it wasn’t a short-term regression, we wanted to make sure we support IE8 to the best of our abilities.

We’d also like to call out a couple additional breaking changes that we failed to originally mention in the release notes for v0.11. We updated that blog post and the changelog, so we encourage you to go read about the changes around [Descriptors](/blog/2014/07/17/react-v0.11.html#descriptors) and [Prop Type Validation](/blog/2014/07/17/react-v0.11.html#prop-type-validation).

The release is available for download from the CDN:

* **React**\
  Dev build with warnings: <https://fb.me/react-0.11.1.js>\
  Minified build for production: <https://fb.me/react-0.11.1.min.js>
* **React with Add-Ons**\
  Dev build with warnings: <https://fb.me/react-with-addons-0.11.1.js>\
  Minified build for production: <https://fb.me/react-with-addons-0.11.1.min.js>
* **In-Browser JSX transformer**\
  <https://fb.me/JSXTransformer-0.11.1.js>

We’ve also published version `0.11.1` of the `react` and `react-tools` packages on npm and the `react` package on bower.

Please try these builds out and [file an issue on GitHub](https://github.com/facebook/react/issues/new) if you see anything awry.

## [](#changelog)Changelog

### [](#react-core)React Core

#### [](#bug-fixes)Bug Fixes

* `setState` can be called inside `componentWillMount` in non-DOM environments
* `SyntheticMouseEvent.getEventModifierState` correctly renamed to `getModifierState`
* `getModifierState` correctly returns a `boolean`
* `getModifierState` is now correctly case sensitive
* Empty Text node used in IE8 `innerHTML` workaround is now removed, fixing rerendering in certain cases

### [](#jsxtransformer)JSXTransformer

* Fix duplicate variable declaration (caused issues in some browsers)

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2014-07-25-react-v0.11.1.md)

----
url: https://18.react.dev/reference/react/useCallback
----

[API Reference](/reference/react)

[Hooks](/reference/react/hooks)

# useCallback[](#undefined "Link for this heading")

`useCallback` is a React Hook that lets you cache a function definition between re-renders.

```
const cachedFn = useCallback(fn, dependencies)
```

***

## Reference[](#reference "Link for Reference ")

### `useCallback(fn, dependencies)`[](#usecallback "Link for this heading")

Call `useCallback` at the top level of your component to cache a function definition between re-renders:

```
import { useCallback } from 'react';



export default function ProductPage({ productId, referrer, theme }) {

  const handleSubmit = useCallback((orderDetails) => {

    post('/product/' + productId + '/buy', {

      referrer,

      orderDetails,

    });

  }, [productId, referrer]);
```

***

## Usage[](#usage "Link for Usage ")

### Skipping re-rendering of components[](#skipping-re-rendering-of-components "Link for Skipping re-rendering of components ")

When you optimize rendering performance, you will sometimes need to cache the functions that you pass to child components. Let’s first look at the syntax for how to do this, and then see in which cases it’s useful.

To cache a function between re-renders of your component, wrap its definition into the `useCallback` Hook:

```
import { useCallback } from 'react';



function ProductPage({ productId, referrer, theme }) {

  const handleSubmit = useCallback((orderDetails) => {

    post('/product/' + productId + '/buy', {

      referrer,

      orderDetails,

    });

  }, [productId, referrer]);

  // ...
```

```
function ProductPage({ productId, referrer, theme }) {

  // ...

  return (

    <div className={theme}>

      <ShippingForm onSubmit={handleSubmit} />

    </div>

  );
```

You’ve noticed that toggling the `theme` prop freezes the app for a moment, but if you remove `<ShippingForm />` from your JSX, it feels fast. This tells you that it’s worth trying to optimize the `ShippingForm` component.

**By default, when a component re-renders, React re-renders all of its children recursively.** This is why, when `ProductPage` re-renders with a different `theme`, the `ShippingForm` component *also* re-renders. This is fine for components that don’t require much calculation to re-render. But if you verified a re-render is slow, you can tell `ShippingForm` to skip re-rendering when its props are the same as on last render by wrapping it in [`memo`:](/reference/react/memo)

```
import { memo } from 'react';



const ShippingForm = memo(function ShippingForm({ onSubmit }) {

  // ...

});
```

**With this change, `ShippingForm` will skip re-rendering if all of its props are the *same* as on the last render.** This is when caching a function becomes important! Let’s say you defined `handleSubmit` without `useCallback`:

```
function ProductPage({ productId, referrer, theme }) {

  // Every time the theme changes, this will be a different function...

  function handleSubmit(orderDetails) {

    post('/product/' + productId + '/buy', {

      referrer,

      orderDetails,

    });

  }

  

  return (

    <div className={theme}>

      {/* ... so ShippingForm's props will never be the same, and it will re-render every time */}

      <ShippingForm onSubmit={handleSubmit} />

    </div>

  );

}
```

**In JavaScript, a `function () {}` or `() => {}` always creates a *different* function,** similar to how the `{}` object literal always creates a new object. Normally, this wouldn’t be a problem, but it means that `ShippingForm` props will never be the same, and your [`memo`](/reference/react/memo) optimization won’t work. This is where `useCallback` comes in handy:

```
function ProductPage({ productId, referrer, theme }) {

  // Tell React to cache your function between re-renders...

  const handleSubmit = useCallback((orderDetails) => {

    post('/product/' + productId + '/buy', {

      referrer,

      orderDetails,

    });

  }, [productId, referrer]); // ...so as long as these dependencies don't change...



  return (

    <div className={theme}>

      {/* ...ShippingForm will receive the same props and can skip re-rendering */}

      <ShippingForm onSubmit={handleSubmit} />

    </div>

  );

}
```

**By wrapping `handleSubmit` in `useCallback`, you ensure that it’s the *same* function between the re-renders** (until dependencies change). You don’t *have to* wrap a function in `useCallback` unless you do it for some specific reason. In this example, the reason is that you pass it to a component wrapped in [`memo`,](/reference/react/memo) and this lets it skip re-rendering. There are other reasons you might need `useCallback` which are described further on this page.

### Note

**You should only rely on `useCallback` as a performance optimization.** If your code doesn’t work without it, find the underlying problem and fix it first. Then you may add `useCallback` back.

##### Deep Dive#### How is useCallback related to useMemo?[](#how-is-usecallback-related-to-usememo "Link for How is useCallback related to useMemo? ")

You will often see [`useMemo`](/reference/react/useMemo) alongside `useCallback`. They are both useful when you’re trying to optimize a child component. They let you [memoize](https://en.wikipedia.org/wiki/Memoization) (or, in other words, cache) something you’re passing down:

```
import { useMemo, useCallback } from 'react';



function ProductPage({ productId, referrer }) {

  const product = useData('/product/' + productId);



  const requirements = useMemo(() => { // Calls your function and caches its result

    return computeRequirements(product);

  }, [product]);



  const handleSubmit = useCallback((orderDetails) => { // Caches your function itself

    post('/product/' + productId + '/buy', {

      referrer,

      orderDetails,

    });

  }, [productId, referrer]);



  return (

    <div className={theme}>

      <ShippingForm requirements={requirements} onSubmit={handleSubmit} />

    </div>

  );

}
```

The difference is in *what* they’re letting you cache:

* **[`useMemo`](/reference/react/useMemo) caches the *result* of calling your function.** In this example, it caches the result of calling `computeRequirements(product)` so that it doesn’t change unless `product` has changed. This lets you pass the `requirements` object down without unnecessarily re-rendering `ShippingForm`. When necessary, React will call the function you’ve passed during rendering to calculate the result.
* **`useCallback` caches *the function itself.*** Unlike `useMemo`, it does not call the function you provide. Instead, it caches the function you provided so that `handleSubmit` *itself* doesn’t change unless `productId` or `referrer` has changed. This lets you pass the `handleSubmit` function down without unnecessarily re-rendering `ShippingForm`. Your code won’t run until the user submits the form.

If you’re already familiar with [`useMemo`,](/reference/react/useMemo) you might find it helpful to think of `useCallback` as this:

```
// Simplified implementation (inside React)

function useCallback(fn, dependencies) {

  return useMemo(() => fn, dependencies);

}
```

```
import { useCallback } from 'react';
import ShippingForm from './ShippingForm.js';

export default function ProductPage({ productId, referrer, theme }) {
  const handleSubmit = useCallback((orderDetails) => {
    post('/product/' + productId + '/buy', {
      referrer,
      orderDetails,
    });
  }, [productId, referrer]);

  return (
    <div className={theme}>
      <ShippingForm onSubmit={handleSubmit} />
    </div>
  );
}

function post(url, data) {
  // Imagine this sends a request...
  console.log('POST /' + url);
  console.log(data);
}
```

***

### Updating state from a memoized callback[](#updating-state-from-a-memoized-callback "Link for Updating state from a memoized callback ")

Sometimes, you might need to update state based on previous state from a memoized callback.

This `handleAddTodo` function specifies `todos` as a dependency because it computes the next todos from it:

```
function TodoList() {

  const [todos, setTodos] = useState([]);



  const handleAddTodo = useCallback((text) => {

    const newTodo = { id: nextId++, text };

    setTodos([...todos, newTodo]);

  }, [todos]);

  // ...
```

You’ll usually want memoized functions to have as few dependencies as possible. When you read some state only to calculate the next state, you can remove that dependency by passing an [updater function](/reference/react/useState#updating-state-based-on-the-previous-state) instead:

```
function TodoList() {

  const [todos, setTodos] = useState([]);



  const handleAddTodo = useCallback((text) => {

    const newTodo = { id: nextId++, text };

    setTodos(todos => [...todos, newTodo]);

  }, []); // ✅ No need for the todos dependency

  // ...
```

Here, instead of making `todos` a dependency and reading it inside, you pass an instruction about *how* to update the state (`todos => [...todos, newTodo]`) to React. [Read more about updater functions.](/reference/react/useState#updating-state-based-on-the-previous-state)

***

### Preventing an Effect from firing too often[](#preventing-an-effect-from-firing-too-often "Link for Preventing an Effect from firing too often ")

Sometimes, you might want to call a function from inside an [Effect:](/learn/synchronizing-with-effects)

```
function ChatRoom({ roomId }) {

  const [message, setMessage] = useState('');



  function createOptions() {

    return {

      serverUrl: 'https://localhost:1234',

      roomId: roomId

    };

  }



  useEffect(() => {

    const options = createOptions();

    const connection = createConnection(options);

    connection.connect();

    // ...
```

This creates a problem. [Every reactive value must be declared as a dependency of your Effect.](/learn/lifecycle-of-reactive-effects#react-verifies-that-you-specified-every-reactive-value-as-a-dependency) However, if you declare `createOptions` as a dependency, it will cause your Effect to constantly reconnect to the chat room:

```
  useEffect(() => {

    const options = createOptions();

    const connection = createConnection(options);

    connection.connect();

    return () => connection.disconnect();

  }, [createOptions]); // 🔴 Problem: This dependency changes on every render

  // ...
```

To solve this, you can wrap the function you need to call from an Effect into `useCallback`:

```
function ChatRoom({ roomId }) {

  const [message, setMessage] = useState('');



  const createOptions = useCallback(() => {

    return {

      serverUrl: 'https://localhost:1234',

      roomId: roomId

    };

  }, [roomId]); // ✅ Only changes when roomId changes



  useEffect(() => {

    const options = createOptions();

    const connection = createConnection(options);

    connection.connect();

    return () => connection.disconnect();

  }, [createOptions]); // ✅ Only changes when createOptions changes

  // ...
```

This ensures that the `createOptions` function is the same between re-renders if the `roomId` is the same. **However, it’s even better to remove the need for a function dependency.** Move your function *inside* the Effect:

```
function ChatRoom({ roomId }) {

  const [message, setMessage] = useState('');



  useEffect(() => {

    function createOptions() { // ✅ No need for useCallback or function dependencies!

      return {

        serverUrl: 'https://localhost:1234',

        roomId: roomId

      };

    }



    const options = createOptions();

    const connection = createConnection(options);

    connection.connect();

    return () => connection.disconnect();

  }, [roomId]); // ✅ Only changes when roomId changes

  // ...
```

Now your code is simpler and doesn’t need `useCallback`. [Learn more about removing Effect dependencies.](/learn/removing-effect-dependencies#move-dynamic-objects-and-functions-inside-your-effect)

***

### Optimizing a custom Hook[](#optimizing-a-custom-hook "Link for Optimizing a custom Hook ")

If you’re writing a [custom Hook,](/learn/reusing-logic-with-custom-hooks) it’s recommended to wrap any functions that it returns into `useCallback`:

```
function useRouter() {

  const { dispatch } = useContext(RouterStateContext);



  const navigate = useCallback((url) => {

    dispatch({ type: 'navigate', url });

  }, [dispatch]);



  const goBack = useCallback(() => {

    dispatch({ type: 'back' });

  }, [dispatch]);



  return {

    navigate,

    goBack,

  };

}
```

This ensures that the consumers of your Hook can optimize their own code when needed.

***

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### Every time my component renders, `useCallback` returns a different function[](#every-time-my-component-renders-usecallback-returns-a-different-function "Link for this heading")

Make sure you’ve specified the dependency array as a second argument!

If you forget the dependency array, `useCallback` will return a new function every time:

```
function ProductPage({ productId, referrer }) {

  const handleSubmit = useCallback((orderDetails) => {

    post('/product/' + productId + '/buy', {

      referrer,

      orderDetails,

    });

  }); // 🔴 Returns a new function every time: no dependency array

  // ...
```

This is the corrected version passing the dependency array as a second argument:

```
function ProductPage({ productId, referrer }) {

  const handleSubmit = useCallback((orderDetails) => {

    post('/product/' + productId + '/buy', {

      referrer,

      orderDetails,

    });

  }, [productId, referrer]); // ✅ Does not return a new function unnecessarily

  // ...
```

If this doesn’t help, then the problem is that at least one of your dependencies is different from the previous render. You can debug this problem by manually logging your dependencies to the console:

```
  const handleSubmit = useCallback((orderDetails) => {

    // ..

  }, [productId, referrer]);



  console.log([productId, referrer]);
```

You can then right-click on the arrays from different re-renders in the console and select “Store as a global variable” for both of them. Assuming the first one got saved as `temp1` and the second one got saved as `temp2`, you can then use the browser console to check whether each dependency in both arrays is the same:

```
Object.is(temp1[0], temp2[0]); // Is the first dependency the same between the arrays?

Object.is(temp1[1], temp2[1]); // Is the second dependency the same between the arrays?

Object.is(temp1[2], temp2[2]); // ... and so on for every dependency ...
```

When you find which dependency is breaking memoization, either find a way to remove it, or [memoize it as well.](/reference/react/useMemo#memoizing-a-dependency-of-another-hook)

***

### I need to call `useCallback` for each list item in a loop, but it’s not allowed[](#i-need-to-call-usememo-for-each-list-item-in-a-loop-but-its-not-allowed "Link for this heading")

Suppose the `Chart` component is wrapped in [`memo`](/reference/react/memo). You want to skip re-rendering every `Chart` in the list when the `ReportList` component re-renders. However, you can’t call `useCallback` in a loop:

```
function ReportList({ items }) {

  return (

    <article>

      {items.map(item => {

        // 🔴 You can't call useCallback in a loop like this:

        const handleClick = useCallback(() => {

          sendReport(item)

        }, [item]);



        return (

          <figure key={item.id}>

            <Chart onClick={handleClick} />

          </figure>

        );

      })}

    </article>

  );

}
```

Instead, extract a component for an individual item, and put `useCallback` there:

```
function ReportList({ items }) {

  return (

    <article>

      {items.map(item =>

        <Report key={item.id} item={item} />

      )}

    </article>

  );

}



function Report({ item }) {

  // ✅ Call useCallback at the top level:

  const handleClick = useCallback(() => {

    sendReport(item)

  }, [item]);



  return (

    <figure>

      <Chart onClick={handleClick} />

    </figure>

  );

}
```

Alternatively, you could remove `useCallback` in the last snippet and instead wrap `Report` itself in [`memo`.](/reference/react/memo) If the `item` prop does not change, `Report` will skip re-rendering, so `Chart` will skip re-rendering too:

```
function ReportList({ items }) {

  // ...

}



const Report = memo(function Report({ item }) {

  function handleClick() {

    sendReport(item);

  }



  return (

    <figure>

      <Chart onClick={handleClick} />

    </figure>

  );

});
```

[PrevioususeActionState](/reference/react/useActionState)

[NextuseContext](/reference/react/useContext)

***

----
url: https://18.react.dev/reference/react/legacy
----

[API Reference](/reference/react)

# Legacy React APIs[](#undefined "Link for this heading")

These APIs are exported from the `react` package, but they are not recommended for use in newly written code. See the linked individual API pages for the suggested alternatives.

***

## Legacy APIs[](#legacy-apis "Link for Legacy APIs ")

* [`Children`](/reference/react/Children) lets you manipulate and transform the JSX received as the `children` prop. [See alternatives.](/reference/react/Children#alternatives)
* [`cloneElement`](/reference/react/cloneElement) lets you create a React element using another element as a starting point. [See alternatives.](/reference/react/cloneElement#alternatives)
* [`Component`](/reference/react/Component) lets you define a React component as a JavaScript class. [See alternatives.](/reference/react/Component#alternatives)
* [`createElement`](/reference/react/createElement) lets you create a React element. Typically, you’ll use JSX instead.
* [`createRef`](/reference/react/createRef) creates a ref object which can contain arbitrary value. [See alternatives.](/reference/react/createRef#alternatives)
* [`isValidElement`](/reference/react/isValidElement) checks whether a value is a React element. Typically used with [`cloneElement`.](/reference/react/cloneElement)
* [`PureComponent`](/reference/react/PureComponent) is similar to [`Component`,](/reference/react/Component) but it skip re-renders with same props. [See alternatives.](/reference/react/PureComponent#alternatives)

***

## Deprecated APIs[](#deprecated-apis "Link for Deprecated APIs ")

### Deprecated

These APIs will be removed in a future major version of React.

* [`createFactory`](/reference/react/createFactory) lets you create a function that produces React elements of a certain type.

[NextChildren](/reference/react/Children)

***

----
url: https://legacy.reactjs.org/docs/accessibility.html
----

## [](#why-accessibility)Why Accessibility?

Web accessibility (also referred to as [**a11y**](https://en.wiktionary.org/wiki/a11y)) is the design and creation of websites that can be used by everyone. Accessibility support is necessary to allow assistive technology to interpret web pages.

React fully supports building accessible websites, often by using standard HTML techniques.

## [](#standards-and-guidelines)Standards and Guidelines

### [](#wcag)WCAG

The [Web Content Accessibility Guidelines](https://www.w3.org/WAI/intro/wcag) provides guidelines for creating accessible web sites.

The following WCAG checklists provide an overview:

* [WCAG checklist from Wuhcag](https://www.wuhcag.com/wcag-checklist/)
* [WCAG checklist from WebAIM](https://webaim.org/standards/wcag/checklist)
* [Checklist from The A11Y Project](https://a11yproject.com/checklist.html)

### [](#wai-aria)WAI-ARIA

The [Web Accessibility Initiative - Accessible Rich Internet Applications](https://www.w3.org/WAI/intro/aria) document contains techniques for building fully accessible JavaScript widgets.

Note that all `aria-*` HTML attributes are fully supported in JSX. Whereas most DOM properties and attributes in React are camelCased, these attributes should be hyphen-cased (also known as kebab-case, lisp-case, etc) as they are in plain HTML:

```
<input
  type="text"
  aria-label={labelText}  aria-required="true"  onChange={onchangeHandler}
  value={inputValue}
  name="name"
/>
```

## [](#semantic-html)Semantic HTML

Semantic HTML is the foundation of accessibility in a web application. Using the various HTML elements to reinforce the meaning of information in our websites will often give us accessibility for free.

* [MDN HTML elements reference](https://developer.mozilla.org/en-US/docs/Web/HTML/Element)

Sometimes we break HTML semantics when we add `<div>` elements to our JSX to make our React code work, especially when working with lists (`<ol>`, `<ul>` and `<dl>`) and the HTML `<table>`. In these cases we should rather use [React Fragments](/docs/fragments.html) to group together multiple elements.

For example,

```
import React, { Fragment } from 'react';
function ListItem({ item }) {
  return (
    <Fragment>      <dt>{item.term}</dt>
      <dd>{item.description}</dd>
    </Fragment>  );
}

function Glossary(props) {
  return (
    <dl>
      {props.items.map(item => (
        <ListItem item={item} key={item.id} />
      ))}
    </dl>
  );
}
```

You can map a collection of items to an array of fragments as you would any other type of element as well:

```
function Glossary(props) {
  return (
    <dl>
      {props.items.map(item => (
        // Fragments should also have a `key` prop when mapping collections
        <Fragment key={item.id}>          <dt>{item.term}</dt>
          <dd>{item.description}</dd>
        </Fragment>      ))}
    </dl>
  );
}
```

When you don’t need any props on the Fragment tag you can use the [short syntax](/docs/fragments.html#short-syntax), if your tooling supports it:

```
function ListItem({ item }) {
  return (
    <>      <dt>{item.term}</dt>
      <dd>{item.description}</dd>
    </>  );
}
```

For more info, see [the Fragments documentation](/docs/fragments.html).

## [](#accessible-forms)Accessible Forms

### [](#labeling)Labeling

Every HTML form control, such as `<input>` and `<textarea>`, needs to be labeled accessibly. We need to provide descriptive labels that are also exposed to screen readers.

The following resources show us how to do this:

* [The W3C shows us how to label elements](https://www.w3.org/WAI/tutorials/forms/labels/)
* [WebAIM shows us how to label elements](https://webaim.org/techniques/forms/controls)
* [The Paciello Group explains accessible names](https://www.paciellogroup.com/blog/2017/04/what-is-an-accessible-name/)

Although these standard HTML practices can be directly used in React, note that the `for` attribute is written as `htmlFor` in JSX:

```
<label htmlFor="namedInput">Name:</label><input id="namedInput" type="text" name="name"/>
```

### [](#notifying-the-user-of-errors)Notifying the user of errors

Error situations need to be understood by all users. The following link shows us how to expose error texts to screen readers as well:

* [The W3C demonstrates user notifications](https://www.w3.org/WAI/tutorials/forms/notifications/)
* [WebAIM looks at form validation](https://webaim.org/techniques/formvalidation/)

## [](#focus-control)Focus Control

Ensure that your web application can be fully operated with the keyboard only:

* [WebAIM talks about keyboard accessibility](https://webaim.org/techniques/keyboard/)

### [](#keyboard-focus-and-focus-outline)Keyboard focus and focus outline

Keyboard focus refers to the current element in the DOM that is selected to accept input from the keyboard. We see it everywhere as a focus outline similar to that shown in the following image:

[](/static/dec0e6bcc1f882baf76ebc860d4f04e5/4fcfe/keyboard-focus.png)

Only ever use CSS that removes this outline, for example by setting `outline: 0`, if you are replacing it with another focus outline implementation.

### [](#mechanisms-to-skip-to-desired-content)Mechanisms to skip to desired content

Provide a mechanism to allow users to skip past navigation sections in your application as this assists and speeds up keyboard navigation.

Skiplinks or Skip Navigation Links are hidden navigation links that only become visible when keyboard users interact with the page. They are very easy to implement with internal page anchors and some styling:

* [WebAIM - Skip Navigation Links](https://webaim.org/techniques/skipnav/)

Also use landmark elements and roles, such as `<main>` and `<aside>`, to demarcate page regions as assistive technology allow the user to quickly navigate to these sections.

Read more about the use of these elements to enhance accessibility here:

* [Accessible Landmarks](https://www.scottohara.me/blog/2018/03/03/landmarks.html)

### [](#programmatically-managing-focus)Programmatically managing focus

Our React applications continuously modify the HTML DOM during runtime, sometimes leading to keyboard focus being lost or set to an unexpected element. In order to repair this, we need to programmatically nudge the keyboard focus in the right direction. For example, by resetting keyboard focus to a button that opened a modal window after that modal window is closed.

MDN Web Docs takes a look at this and describes how we can build [keyboard-navigable JavaScript widgets](https://developer.mozilla.org/en-US/docs/Web/Accessibility/Keyboard-navigable_JavaScript_widgets).

To set focus in React, we can use [Refs to DOM elements](/docs/refs-and-the-dom.html).

Using this, we first create a ref to an element in the JSX of a component class:

```
class CustomTextInput extends React.Component {
  constructor(props) {
    super(props);
    // Create a ref to store the textInput DOM element    this.textInput = React.createRef();  }
  render() {
  // Use the `ref` callback to store a reference to the text input DOM  // element in an instance field (for example, this.textInput).    return (
      <input
        type="text"
        ref={this.textInput}      />
    );
  }
}
```

Then we can focus it elsewhere in our component when needed:

```
focus() {
  // Explicitly focus the text input using the raw DOM API
  // Note: we're accessing "current" to get the DOM node
  this.textInput.current.focus();
}
```

Sometimes a parent component needs to set focus to an element in a child component. We can do this by [exposing DOM refs to parent components](/docs/refs-and-the-dom.html#exposing-dom-refs-to-parent-components) through a special prop on the child component that forwards the parent’s ref to the child’s DOM node.

```
function CustomTextInput(props) {
  return (
    <div>
      <input ref={props.inputRef} />    </div>
  );
}

class Parent extends React.Component {
  constructor(props) {
    super(props);
    this.inputElement = React.createRef();  }
  render() {
    return (
      <CustomTextInput inputRef={this.inputElement} />    );
  }
}

// Now you can set focus when required.
this.inputElement.current.focus();
```

When using a [HOC](/docs/higher-order-components.html) to extend components, it is recommended to [forward the ref](/docs/forwarding-refs.html) to the wrapped component using the `forwardRef` function of React. If a third party HOC does not implement ref forwarding, the above pattern can still be used as a fallback.

A great focus management example is the [react-aria-modal](https://github.com/davidtheclark/react-aria-modal). This is a relatively rare example of a fully accessible modal window. Not only does it set initial focus on the cancel button (preventing the keyboard user from accidentally activating the success action) and trap keyboard focus inside the modal, it also resets focus back to the element that initially triggered the modal.

> Note:
>
> While this is a very important accessibility feature, it is also a technique that should be used judiciously. Use it to repair the keyboard focus flow when it is disturbed, not to try and anticipate how users want to use applications.

## [](#mouse-and-pointer-events)Mouse and pointer events

Ensure that all functionality exposed through a mouse or pointer event can also be accessed using the keyboard alone. Depending only on the pointer device will lead to many cases where keyboard users cannot use your application.

To illustrate this, let’s look at a prolific example of broken accessibility caused by click events. This is the outside click pattern, where a user can disable an opened popover by clicking outside the element.

This is typically implemented by attaching a `click` event to the `window` object that closes the popover:

```
class OuterClickExample extends React.Component {
  constructor(props) {
    super(props);

    this.state = { isOpen: false };
    this.toggleContainer = React.createRef();

    this.onClickHandler = this.onClickHandler.bind(this);
    this.onClickOutsideHandler = this.onClickOutsideHandler.bind(this);
  }

  componentDidMount() {    window.addEventListener('click', this.onClickOutsideHandler);  }
  componentWillUnmount() {
    window.removeEventListener('click', this.onClickOutsideHandler);
  }

  onClickHandler() {
    this.setState(currentState => ({
      isOpen: !currentState.isOpen
    }));
  }

  onClickOutsideHandler(event) {    if (this.state.isOpen && !this.toggleContainer.current.contains(event.target)) {      this.setState({ isOpen: false });    }  }
  render() {
    return (
      <div ref={this.toggleContainer}>
        <button onClick={this.onClickHandler}>Select an option</button>
        {this.state.isOpen && (
          <ul>
            <li>Option 1</li>
            <li>Option 2</li>
            <li>Option 3</li>
          </ul>
        )}
      </div>
    );
  }
}
```

This may work fine for users with pointer devices, such as a mouse, but operating this with the keyboard alone leads to broken functionality when tabbing to the next element as the `window` object never receives a `click` event. This can lead to obscured functionality which blocks users from using your application.

The same functionality can be achieved by using appropriate event handlers instead, such as `onBlur` and `onFocus`:

```
class BlurExample extends React.Component {
  constructor(props) {
    super(props);

    this.state = { isOpen: false };
    this.timeOutId = null;

    this.onClickHandler = this.onClickHandler.bind(this);
    this.onBlurHandler = this.onBlurHandler.bind(this);
    this.onFocusHandler = this.onFocusHandler.bind(this);
  }

  onClickHandler() {
    this.setState(currentState => ({
      isOpen: !currentState.isOpen
    }));
  }

  // We close the popover on the next tick by using setTimeout.  // This is necessary because we need to first check if  // another child of the element has received focus as  // the blur event fires prior to the new focus event.  onBlurHandler() {    this.timeOutId = setTimeout(() => {      this.setState({        isOpen: false      });    });  }
  // If a child receives focus, do not close the popover.  onFocusHandler() {    clearTimeout(this.timeOutId);  }
  render() {
    // React assists us by bubbling the blur and    // focus events to the parent.    return (
      <div onBlur={this.onBlurHandler}           onFocus={this.onFocusHandler}>        <button onClick={this.onClickHandler}
                aria-haspopup="true"
                aria-expanded={this.state.isOpen}>
          Select an option
        </button>
        {this.state.isOpen && (
          <ul>
            <li>Option 1</li>
            <li>Option 2</li>
            <li>Option 3</li>
          </ul>
        )}
      </div>
    );
  }
}
```

This code exposes the functionality to both pointer device and keyboard users. Also note the added `aria-*` props to support screen-reader users. For simplicity’s sake the keyboard events to enable `arrow key` interaction of the popover options have not been implemented.

This is one example of many cases where depending on only pointer and mouse events will break functionality for keyboard users. Always testing with the keyboard will immediately highlight the problem areas which can then be fixed by using keyboard aware event handlers.

## [](#more-complex-widgets)More Complex Widgets

A more complex user experience should not mean a less accessible one. Whereas accessibility is most easily achieved by coding as close to HTML as possible, even the most complex widget can be coded accessibly.

Here we require knowledge of [ARIA Roles](https://www.w3.org/TR/wai-aria/#roles) as well as [ARIA States and Properties](https://www.w3.org/TR/wai-aria/#states_and_properties). These are toolboxes filled with HTML attributes that are fully supported in JSX and enable us to construct fully accessible, highly functional React components.

Each type of widget has a specific design pattern and is expected to function in a certain way by users and user agents alike:

* [ARIA Authoring Practices Guide (APG) - Design Patterns and Examples](https://www.w3.org/WAI/ARIA/apg/patterns/)
* [Heydon Pickering - ARIA Examples](https://heydonworks.com/article/practical-aria-examples/)
* [Inclusive Components](https://inclusive-components.design/)

## [](#other-points-for-consideration)Other Points for Consideration

### [](#setting-the-language)Setting the language

Indicate the human language of page texts as screen reader software uses this to select the correct voice settings:

* [WebAIM - Document Language](https://webaim.org/techniques/screenreader/#language)

### [](#setting-the-document-title)Setting the document title

Set the document `<title>` to correctly describe the current page content as this ensures that the user remains aware of the current page context:

* [WCAG - Understanding the Document Title Requirement](https://www.w3.org/TR/UNDERSTANDING-WCAG20/navigation-mechanisms-title.html)

We can set this in React using the [React Document Title Component](https://github.com/gaearon/react-document-title).

### [](#color-contrast)Color contrast

Ensure that all readable text on your website has sufficient color contrast to remain maximally readable by users with low vision:

* [WCAG - Understanding the Color Contrast Requirement](https://www.w3.org/TR/UNDERSTANDING-WCAG20/visual-audio-contrast-contrast.html)
* [Everything About Color Contrast And Why You Should Rethink It](https://www.smashingmagazine.com/2014/10/color-contrast-tips-and-tools-for-accessibility/)
* [A11yProject - What is Color Contrast](https://a11yproject.com/posts/what-is-color-contrast/)

It can be tedious to manually calculate the proper color combinations for all cases in your website so instead, you can [calculate an entire accessible color palette with Colorable](https://colorable.jxnblk.com/).

Both the aXe and WAVE tools mentioned below also include color contrast tests and will report on contrast errors.

If you want to extend your contrast testing abilities you can use these tools:

* [WebAIM - Color Contrast Checker](https://webaim.org/resources/contrastchecker/)
* [The Paciello Group - Color Contrast Analyzer](https://www.paciellogroup.com/resources/contrastanalyser/)

## [](#development-and-testing-tools)Development and Testing Tools

There are a number of tools we can use to assist in the creation of accessible web applications.

### [](#the-keyboard)The keyboard

By far the easiest and also one of the most important checks is to test if your entire website can be reached and used with the keyboard alone. Do this by:

1. Disconnecting your mouse.
2. Using `Tab` and `Shift+Tab` to browse.
3. Using `Enter` to activate elements.
4. Where required, using your keyboard arrow keys to interact with some elements, such as menus and dropdowns.

### [](#development-assistance)Development assistance

We can check some accessibility features directly in our JSX code. Often intellisense checks are already provided in JSX aware IDE’s for the ARIA roles, states and properties. We also have access to the following tool:

#### [](#eslint-plugin-jsx-a11y)eslint-plugin-jsx-a11y

The [eslint-plugin-jsx-a11y](https://github.com/evcohen/eslint-plugin-jsx-a11y) plugin for ESLint provides AST linting feedback regarding accessibility issues in your JSX. Many IDE’s allow you to integrate these findings directly into code analysis and source code windows.

[Create React App](https://github.com/facebookincubator/create-react-app) has this plugin with a subset of rules activated. If you want to enable even more accessibility rules, you can create an `.eslintrc` file in the root of your project with this content:

```
{
  "extends": ["react-app", "plugin:jsx-a11y/recommended"],
  "plugins": ["jsx-a11y"]
}
```

### [](#testing-accessibility-in-the-browser)Testing accessibility in the browser

A number of tools exist that can run accessibility audits on web pages in your browser. Please use them in combination with other accessibility checks mentioned here as they can only test the technical accessibility of your HTML.

#### [](#axe-axe-core-and-react-axe)aXe, aXe-core and react-axe

Deque Systems offers [aXe-core](https://github.com/dequelabs/axe-core) for automated and end-to-end accessibility tests of your applications. This module includes integrations for Selenium.

[The Accessibility Engine](https://www.deque.com/products/axe/) or aXe, is an accessibility inspector browser extension built on `aXe-core`.

You can also use the [@axe-core/react](https://github.com/dequelabs/axe-core-npm/tree/develop/packages/react) module to report these accessibility findings directly to the console while developing and debugging.

#### [](#webaim-wave)WebAIM WAVE

The [Web Accessibility Evaluation Tool](https://wave.webaim.org/extension/) is another accessibility browser extension.

#### [](#accessibility-inspectors-and-the-accessibility-tree)Accessibility inspectors and the Accessibility Tree

[The Accessibility Tree](https://www.paciellogroup.com/blog/2015/01/the-browser-accessibility-tree/) is a subset of the DOM tree that contains accessible objects for every DOM element that should be exposed to assistive technology, such as screen readers.

In some browsers we can easily view the accessibility information for each element in the accessibility tree:

* [Using the Accessibility Inspector in Firefox](https://developer.mozilla.org/en-US/docs/Tools/Accessibility_inspector)
* [Using the Accessibility Inspector in Chrome](https://developers.google.com/web/tools/chrome-devtools/accessibility/reference#pane)
* [Using the Accessibility Inspector in OS X Safari](https://developer.apple.com/library/content/documentation/Accessibility/Conceptual/AccessibilityMacOSX/OSXAXTestingApps.html)

### [](#screen-readers)Screen readers

Testing with a screen reader should form part of your accessibility tests.

Please note that browser / screen reader combinations matter. It is recommended that you test your application in the browser best suited to your screen reader of choice.

### [](#commonly-used-screen-readers)Commonly Used Screen Readers

#### [](#nvda-in-firefox)NVDA in Firefox

[NonVisual Desktop Access](https://www.nvaccess.org/) or NVDA is an open source Windows screen reader that is widely used.

Refer to the following guides on how to best use NVDA:

* [WebAIM - Using NVDA to Evaluate Web Accessibility](https://webaim.org/articles/nvda/)
* [Deque - NVDA Keyboard Shortcuts](https://dequeuniversity.com/screenreaders/nvda-keyboard-shortcuts)

#### [](#voiceover-in-safari)VoiceOver in Safari

VoiceOver is an integrated screen reader on Apple devices.

Refer to the following guides on how to activate and use VoiceOver:

* [WebAIM - Using VoiceOver to Evaluate Web Accessibility](https://webaim.org/articles/voiceover/)
* [Deque - VoiceOver for OS X Keyboard Shortcuts](https://dequeuniversity.com/screenreaders/voiceover-keyboard-shortcuts)
* [Deque - VoiceOver for iOS Shortcuts](https://dequeuniversity.com/screenreaders/voiceover-ios-shortcuts)

#### [](#jaws-in-internet-explorer)JAWS in Internet Explorer

[Job Access With Speech](https://www.freedomscientific.com/Products/software/JAWS/) or JAWS, is a prolifically used screen reader on Windows.

Refer to the following guides on how to best use JAWS:

* [WebAIM - Using JAWS to Evaluate Web Accessibility](https://webaim.org/articles/jaws/)
* [Deque - JAWS Keyboard Shortcuts](https://dequeuniversity.com/screenreaders/jaws-keyboard-shortcuts)

### [](#other-screen-readers)Other Screen Readers

#### [](#chromevox-in-google-chrome)ChromeVox in Google Chrome

[ChromeVox](https://www.chromevox.com/) is an integrated screen reader on Chromebooks and is available [as an extension](https://chrome.google.com/webstore/detail/chromevox/kgejglhpjiefppelpmljglcjbhoiplfn?hl=en) for Google Chrome.

Refer to the following guides on how best to use ChromeVox:

* [Google Chromebook Help - Use the Built-in Screen Reader](https://support.google.com/chromebook/answer/7031755?hl=en)
* [ChromeVox Classic Keyboard Shortcuts Reference](https://www.chromevox.com/keyboard_shortcuts.html)

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/accessibility.md)

----
url: https://18.react.dev/reference/react/cache
----

[API Reference](/reference/react)

[APIs](/reference/react/apis)

# cache[](#undefined "Link for this heading")

### Canary

* `cache` is only for use with [React Server Components](/blog/2023/03/22/react-labs-what-we-have-been-working-on-march-2023#react-server-components). See [frameworks](/learn/start-a-new-react-project#bleeding-edge-react-frameworks) that support React Server Components.

* `cache` is only available in React’s [Canary](/community/versioning-policy#canary-channel) and [experimental](/community/versioning-policy#experimental-channel) channels. Please ensure you understand the limitations before using `cache` in production. Learn more about [React’s release channels here](/community/versioning-policy#all-release-channels).

`cache` lets you cache the result of a data fetch or computation.

```
const cachedFn = cache(fn);
```

***

## Reference[](#reference "Link for Reference ")

### `cache(fn)`[](#cache "Link for this heading")

Call `cache` outside of any components to create a version of the function with caching.

```
import {cache} from 'react';

import calculateMetrics from 'lib/metrics';



const getMetrics = cache(calculateMetrics);



function Chart({data}) {

  const report = getMetrics(data);

  // ...

}
```

* `cache` is for use in [Server Components](/blog/2023/03/22/react-labs-what-we-have-been-working-on-march-2023#react-server-components) only.

***

## Usage[](#usage "Link for Usage ")

### Cache an expensive computation[](#cache-expensive-computation "Link for Cache an expensive computation ")

Use `cache` to skip duplicate work.

```
import {cache} from 'react';

import calculateUserMetrics from 'lib/user';



const getUserMetrics = cache(calculateUserMetrics);



function Profile({user}) {

  const metrics = getUserMetrics(user);

  // ...

}



function TeamReport({users}) {

  for (let user in users) {

    const metrics = getUserMetrics(user);

    // ...

  }

  // ...

}
```

If the same `user` object is rendered in both `Profile` and `TeamReport`, the two components can share work and only call `calculateUserMetrics` once for that `user`.

Assume `Profile` is rendered first. It will call `getUserMetrics`, and check if there is a cached result. Since it is the first time `getUserMetrics` is called with that `user`, there will be a cache miss. `getUserMetrics` will then call `calculateUserMetrics` with that `user` and write the result to cache.

When `TeamReport` renders its list of `users` and reaches the same `user` object, it will call `getUserMetrics` and read the result from cache.

### Pitfall

##### Calling different memoized functions will read from different caches.[](#pitfall-different-memoized-functions "Link for Calling different memoized functions will read from different caches. ")

To access the same cache, components must call the same memoized function.

```
// Temperature.js

import {cache} from 'react';

import {calculateWeekReport} from './report';



export function Temperature({cityData}) {

  // 🚩 Wrong: Calling `cache` in component creates new `getWeekReport` for each render

  const getWeekReport = cache(calculateWeekReport);

  const report = getWeekReport(cityData);

  // ...

}
```

```
// Precipitation.js

import {cache} from 'react';

import {calculateWeekReport} from './report';



// 🚩 Wrong: `getWeekReport` is only accessible for `Precipitation` component.

const getWeekReport = cache(calculateWeekReport);



export function Precipitation({cityData}) {

  const report = getWeekReport(cityData);

  // ...

}
```

In the above example, `Precipitation` and `Temperature` each call `cache` to create a new memoized function with their own cache look-up. If both components render for the same `cityData`, they will do duplicate work to call `calculateWeekReport`.

In addition, `Temperature` creates a new memoized function each time the component is rendered which doesn’t allow for any cache sharing.

To maximize cache hits and reduce work, the two components should call the same memoized function to access the same cache. Instead, define the memoized function in a dedicated module that can be [`import`-ed](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import) across components.

```
// getWeekReport.js

import {cache} from 'react';

import {calculateWeekReport} from './report';



export default cache(calculateWeekReport);
```

```
// Temperature.js

import getWeekReport from './getWeekReport';



export default function Temperature({cityData}) {

	const report = getWeekReport(cityData);

  // ...

}
```

```
// Precipitation.js

import getWeekReport from './getWeekReport';



export default function Precipitation({cityData}) {

  const report = getWeekReport(cityData);

  // ...

}
```

Here, both components call the same memoized function exported from `./getWeekReport.js` to read and write to the same cache.

### Share a snapshot of data[](#take-and-share-snapshot-of-data "Link for Share a snapshot of data ")

To share a snapshot of data between components, call `cache` with a data-fetching function like `fetch`. When multiple components make the same data fetch, only one request is made and the data returned is cached and shared across components. All components refer to the same snapshot of data across the server render.

```
import {cache} from 'react';

import {fetchTemperature} from './api.js';



const getTemperature = cache(async (city) => {

	return await fetchTemperature(city);

});



async function AnimatedWeatherCard({city}) {

	const temperature = await getTemperature(city);

	// ...

}



async function MinimalWeatherCard({city}) {

	const temperature = await getTemperature(city);

	// ...

}
```

If `AnimatedWeatherCard` and `MinimalWeatherCard` both render for the same city, they will receive the same snapshot of data from the memoized function.

If `AnimatedWeatherCard` and `MinimalWeatherCard` supply different city arguments to `getTemperature`, then `fetchTemperature` will be called twice and each call site will receive different data.

The city acts as a cache key.

### Note

Asynchronous rendering is only supported for Server Components.

```
async function AnimatedWeatherCard({city}) {

	const temperature = await getTemperature(city);

	// ...

}
```

### Preload data[](#preload-data "Link for Preload data ")

By caching a long-running data fetch, you can kick off asynchronous work prior to rendering the component.

```
const getUser = cache(async (id) => {

  return await db.user.query(id);

});



async function Profile({id}) {

  const user = await getUser(id);

  return (

    <section>

      <img src={user.profilePic} />

      <h2>{user.name}</h2>

    </section>

  );

}



function Page({id}) {

  // ✅ Good: start fetching the user data

  getUser(id);

  // ... some computational work

  return (

    <>

      <Profile id={id} />

    </>

  );

}
```

When rendering `Page`, the component calls `getUser` but note that it doesn’t use the returned data. This early `getUser` call kicks off the asynchronous database query that occurs while `Page` is doing other computational work and rendering children.

When rendering `Profile`, we call `getUser` again. If the initial `getUser` call has already returned and cached the user data, when `Profile` asks and waits for this data, it can simply read from the cache without requiring another remote procedure call. If the initial data request hasn’t been completed, preloading data in this pattern reduces delay in data-fetching.

##### Deep Dive#### Caching asynchronous work[](#caching-asynchronous-work "Link for Caching asynchronous work ")

When evaluating an [asynchronous function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function), you will receive a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) for that work. The promise holds the state of that work (*pending*, *fulfilled*, *failed*) and its eventual settled result.

In this example, the asynchronous function `fetchData` returns a promise that is awaiting the `fetch`.

```
async function fetchData() {

  return await fetch(`https://...`);

}



const getData = cache(fetchData);



async function MyComponent() {

  getData();

  // ... some computational work  

  await getData();

  // ...

}
```

In calling `getData` the first time, the promise returned from `fetchData` is cached. Subsequent look-ups will then return the same promise.

Notice that the first `getData` call does not `await` whereas the second does. [`await`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await) is a JavaScript operator that will wait and return the settled result of the promise. The first `getData` call simply initiates the `fetch` to cache the promise for the second `getData` to look-up.

If by the second call the promise is still *pending*, then `await` will pause for the result. The optimization is that while we wait on the `fetch`, React can continue with computational work, thus reducing the wait time for the second call.

If the promise is already settled, either to an error or the *fulfilled* result, `await` will return that value immediately. In both outcomes, there is a performance benefit.

### Pitfall

##### Calling a memoized function outside of a component will not use the cache.[](#pitfall-memoized-call-outside-component "Link for Calling a memoized function outside of a component will not use the cache. ")

```
import {cache} from 'react';



const getUser = cache(async (userId) => {

  return await db.user.query(userId);

});



// 🚩 Wrong: Calling memoized function outside of component will not memoize.

getUser('demo-id');



async function DemoProfile() {

  // ✅ Good: `getUser` will memoize.

  const user = await getUser('demo-id');

  return <Profile user={user} />;

}
```

React only provides cache access to the memoized function in a component. When calling `getUser` outside of a component, it will still evaluate the function but not read or update the cache.

This is because cache access is provided through a [context](/learn/passing-data-deeply-with-context) which is only accessible from a component.

##### Deep Dive#### When should I use `cache`, [`memo`](/reference/react/memo), or [`useMemo`](/reference/react/useMemo)?[](#cache-memo-usememo "Link for this heading")

All mentioned APIs offer memoization but the difference is what they’re intended to memoize, who can access the cache, and when their cache is invalidated.

#### `useMemo`[](#deep-dive-use-memo "Link for this heading")

In general, you should use [`useMemo`](/reference/react/useMemo) for caching a expensive computation in a Client Component across renders. As an example, to memoize a transformation of data within a component.

```
'use client';



function WeatherReport({record}) {

  const avgTemp = useMemo(() => calculateAvg(record), record);

  // ...

}



function App() {

  const record = getRecord();

  return (

    <>

      <WeatherReport record={record} />

      <WeatherReport record={record} />

    </>

  );

}
```

In this example, `App` renders two `WeatherReport`s with the same record. Even though both components do the same work, they cannot share work. `useMemo`’s cache is only local to the component.

However, `useMemo` does ensure that if `App` re-renders and the `record` object doesn’t change, each component instance would skip work and use the memoized value of `avgTemp`. `useMemo` will only cache the last computation of `avgTemp` with the given dependencies.

#### `cache`[](#deep-dive-cache "Link for this heading")

In general, you should use `cache` in Server Components to memoize work that can be shared across components.

```
const cachedFetchReport = cache(fetchReport);



function WeatherReport({city}) {

  const report = cachedFetchReport(city);

  // ...

}



function App() {

  const city = "Los Angeles";

  return (

    <>

      <WeatherReport city={city} />

      <WeatherReport city={city} />

    </>

  );

}
```

Re-writing the previous example to use `cache`, in this case the second instance of `WeatherReport` will be able to skip duplicate work and read from the same cache as the first `WeatherReport`. Another difference from the previous example is that `cache` is also recommended for memoizing data fetches, unlike `useMemo` which should only be used for computations.

At this time, `cache` should only be used in Server Components and the cache will be invalidated across server requests.

#### `memo`[](#deep-dive-memo "Link for this heading")

You should use [`memo`](/reference/react/memo) to prevent a component re-rendering if its props are unchanged.

```
'use client';



function WeatherReport({record}) {

  const avgTemp = calculateAvg(record); 

  // ...

}



const MemoWeatherReport = memo(WeatherReport);



function App() {

  const record = getRecord();

  return (

    <>

      <MemoWeatherReport record={record} />

      <MemoWeatherReport record={record} />

    </>

  );

}
```

In this example, both `MemoWeatherReport` components will call `calculateAvg` when first rendered. However, if `App` re-renders, with no changes to `record`, none of the props have changed and `MemoWeatherReport` will not re-render.

Compared to `useMemo`, `memo` memoizes the component render based on props vs. specific computations. Similar to `useMemo`, the memoized component only caches the last render with the last prop values. Once the props change, the cache invalidates and the component re-renders.

***

```
import {cache} from 'react';



const calculateNorm = cache((vector) => {

  // ...

});



function MapMarker(props) {

  // 🚩 Wrong: props is an object that changes every render.

  const length = calculateNorm(props);

  // ...

}



function App() {

  return (

    <>

      <MapMarker x={10} y={10} z={10} />

      <MapMarker x={10} y={10} z={10} />

    </>

  );

}
```

In this case the two `MapMarker`s look like they’re doing the same work and calling `calculateNorm` with the same value of `{x: 10, y: 10, z:10}`. Even though the objects contain the same values, they are not the same object reference as each component creates its own `props` object.

React will call [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) on the input to verify if there is a cache hit.

```
import {cache} from 'react';



const calculateNorm = cache((x, y, z) => {

  // ...

});



function MapMarker(props) {

  // ✅ Good: Pass primitives to memoized function

  const length = calculateNorm(props.x, props.y, props.z);

  // ...

}



function App() {

  return (

    <>

      <MapMarker x={10} y={10} z={10} />

      <MapMarker x={10} y={10} z={10} />

    </>

  );

}
```

One way to address this could be to pass the vector dimensions to `calculateNorm`. This works because the dimensions themselves are primitives.

Another solution may be to pass the vector object itself as a prop to the component. We’ll need to pass the same object to both component instances.

```
import {cache} from 'react';



const calculateNorm = cache((vector) => {

  // ...

});



function MapMarker(props) {

  // ✅ Good: Pass the same `vector` object

  const length = calculateNorm(props.vector);

  // ...

}



function App() {

  const vector = [10, 10, 10];

  return (

    <>

      <MapMarker vector={vector} />

      <MapMarker vector={vector} />

    </>

  );

}
```

[Previousact](/reference/react/act)

[NextcreateContext](/reference/react/createContext)

***

----
url: https://legacy.reactjs.org/blog/2018/10/23/react-v-16-6.html
----

October 23, 2018 by [Sebastian Markbåge](https://twitter.com/sebmarkbage)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

Today we’re releasing React 16.6 with a few new convenient features. A form of PureComponent/shouldComponentUpdate for function components, a way to do code splitting using Suspense and an easier way to consume Context from class components.

Check out the full [changelog](#changelog) below.

## [](#reactmemo)[`React.memo`](/docs/react-api.html#reactmemo)

Class components can bail out from rendering when their input props are the same using [`PureComponent`](/docs/react-api.html#reactpurecomponent) or [`shouldComponentUpdate`](/docs/react-component.html#shouldcomponentupdate). Now you can do the same with function components by wrapping them in [`React.memo`](/docs/react-api.html#reactmemo).

```
const MyComponent = React.memo(function MyComponent(props) {
  /* only rerenders if props change */
});
```

## [](#reactlazy-code-splitting-with-suspense)[`React.lazy`](/docs/code-splitting.html#reactlazy): Code-Splitting with `Suspense`

You may have seen [Dan’s talk about React Suspense at JSConf Iceland](/blog/2018/03/01/sneak-peek-beyond-react-16.html). Now you can use the Suspense component to do [code-splitting](/docs/code-splitting.html#reactlazy) by wrapping a dynamic import in a call to `React.lazy()`.

```
import React, {lazy, Suspense} from 'react';
const OtherComponent = lazy(() => import('./OtherComponent'));

function MyComponent() {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <OtherComponent />
    </Suspense>
  );
}
```

The Suspense component will also allow library authors to start building data fetching with Suspense support in the future.

> Note: This feature is not yet available for server-side rendering. Suspense support will be added in a later release.

## [](#static-contexttype)[`static contextType`](/docs/context.html#classcontexttype)

In [React 16.3](/blog/2018/03/29/react-v-16-3.html) we introduced the official Context API as a replacement to the previous [Legacy Context](/docs/legacy-context.html) API.

```
const MyContext = React.createContext();
```

We’ve heard feedback that adopting the new render prop API can be difficult in class components. So we’ve added a convenience API to [consume a context value from within a class component](/docs/context.html#classcontexttype).

```
class MyClass extends React.Component {
  static contextType = MyContext;
  componentDidMount() {
    let value = this.context;
    /* perform a side-effect at mount using the value of MyContext */
  }
  componentDidUpdate() {
    let value = this.context;
    /* ... */
  }
  componentWillUnmount() {
    let value = this.context;
    /* ... */
  }
  render() {
    let value = this.context;
    /* render something based on the value of MyContext */
  }
}
```

## [](#static-getderivedstatefromerror)[`static getDerivedStateFromError()`](/docs/react-component.html#static-getderivedstatefromerror)

React 16 introduced [Error Boundaries](/blog/2017/07/26/error-handling-in-react-16.html) for handling errors thrown in React renders. We already had the `componentDidCatch` lifecycle method which gets fired after an error has already happened. It’s great for logging errors to the server. It also lets you show a different UI to the user by calling `setState`.

Before that is fired, we render `null` in place of the tree that threw an error. This sometimes breaks parent components that don’t expect their refs to be empty. It also doesn’t work to recover from errors on the server since the `Did` lifecycle methods don’t fire during server-side rendering.

We’re adding another error method that lets you render the fallback UI before the render completes. See the docs for [`getDerivedStateFromError()`](/docs/react-component.html#static-getderivedstatefromerror).

> Note: `getDerivedStateFromError()` is not yet available for server-side rendering. It is designed to work with server-side rendering in a future release. We’re releasing it early so that you can start preparing to use it.

## [](#deprecations-in-strictmode)Deprecations in StrictMode

In [16.3](/blog/2018/03/29/react-v-16-3.html#strictmode-component) we introduced the [`StrictMode`](/docs/strict-mode.html) component. It lets you opt-in to early warnings for patterns that might cause problems in the future.

We’ve added two more APIs to the list of deprecated APIs in `StrictMode`. If you don’t use `StrictMode` you don’t have to worry; these warning won’t fire for you.

* **ReactDOM.findDOMNode()** - This API is often misunderstood and most uses of it are unnecessary. It can also be surprisingly slow in React 16. [See the docs](/docs/strict-mode.html#warning-about-deprecated-finddomnode-usage) for possible upgrade paths.
* **Legacy Context** using contextTypes and getChildContext - Legacy context makes React slightly slower and bigger than it needs to be. That’s why we strongly want to encourage upgrading to the [new context API](/docs/context.html). Hopefully the addition of the [`contextType`](/docs/context.html#classcontexttype) API makes this a bit easier.

If you’re having trouble upgrading, we’d like to hear your feedback.

## [](#installation)Installation

React v16.6.0 is available on the npm registry.

To install React 16 with Yarn, run:

```
yarn add react@^16.6.0 react-dom@^16.6.0
```

To install React 16 with npm, run:

```
npm install --save react@^16.6.0 react-dom@^16.6.0
```

We also provide UMD builds of React via a CDN:

```
<script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
```

Refer to the documentation for [detailed installation instructions](/docs/installation.html).

## [](#changelog)Changelog

### [](#react)React

* Add `React.memo()` as an alternative to `PureComponent` for functions. ([@acdlite](https://github.com/acdlite) in [#13748](https://github.com/facebook/react/pull/13748))
* Add `React.lazy()` for code splitting components. ([@acdlite](https://github.com/acdlite) in [#13885](https://github.com/facebook/react/pull/13885))
* `React.StrictMode` now warns about legacy context API. ([@bvaughn](https://github.com/bvaughn) in [#13760](https://github.com/facebook/react/pull/13760))
* `React.StrictMode` now warns about `findDOMNode`. ([@sebmarkbage](https://github.com/sebmarkbage) in [#13841](https://github.com/facebook/react/pull/13841))
* Rename `unstable_AsyncMode` to `unstable_ConcurrentMode`. ([@trueadm](https://github.com/trueadm) in [#13732](https://github.com/facebook/react/pull/13732))
* Rename `unstable_Placeholder` to `Suspense`, and `delayMs` to `maxDuration`. ([@gaearon](https://github.com/gaearon) in [#13799](https://github.com/facebook/react/pull/13799) and [@sebmarkbage](https://github.com/sebmarkbage) in [#13922](https://github.com/facebook/react/pull/13922))

### [](#react-dom)React DOM

* Add `contextType` as a more ergonomic way to subscribe to context from a class. ([@bvaughn](https://github.com/bvaughn) in [#13728](https://github.com/facebook/react/pull/13728))
* Add `getDerivedStateFromError` lifecycle method for catching errors in a future asynchronous server-side renderer. ([@bvaughn](https://github.com/bvaughn) in [#13746](https://github.com/facebook/react/pull/13746))
* Warn when `<Context>` is used instead of `<Context.Consumer>`. ([@trueadm](https://github.com/trueadm) in [#13829](https://github.com/facebook/react/pull/13829))
* Fix gray overlay on iOS Safari. ([@philipp-spiess](https://github.com/philipp-spiess) in [#13778](https://github.com/facebook/react/pull/13778))
* Fix a bug caused by overwriting `window.event` in development. ([@sergei-startsev](https://github.com/sergei-startsev) in [#13697](https://github.com/facebook/react/pull/13697))

### [](#react-dom-server)React DOM Server

* Add support for `React.memo()`. ([@alexmckenley](https://github.com/alexmckenley) in [#13855](https://github.com/facebook/react/pull/13855))
* Add support for `contextType`. ([@alexmckenley](https://github.com/alexmckenley) and [@sebmarkbage](https://github.com/sebmarkbage) in [#13889](https://github.com/facebook/react/pull/13889))

### [](#scheduler-experimental)Scheduler (Experimental)

* Rename the package to `scheduler`. ([@gaearon](https://github.com/gaearon) in [#13683](https://github.com/facebook/react/pull/13683))
* Support priority levels, continuations, and wrapped callbacks. ([@acdlite](https://github.com/acdlite) in [#13720](https://github.com/facebook/react/pull/13720) and [#13842](https://github.com/facebook/react/pull/13842))
* Improve the fallback mechanism in non-DOM environments. ([@acdlite](https://github.com/acdlite) in [#13740](https://github.com/facebook/react/pull/13740))
* Schedule `requestAnimationFrame` earlier. ([@acdlite](https://github.com/acdlite) in [#13785](https://github.com/facebook/react/pull/13785))
* Fix the DOM detection to be more thorough. ([@trueadm](https://github.com/trueadm) in [#13731](https://github.com/facebook/react/pull/13731))
* Fix bugs with interaction tracing. ([@bvaughn](https://github.com/bvaughn) in [#13590](https://github.com/facebook/react/pull/13590))
* Add the `envify` transform to the package. ([@mridgway](https://github.com/mridgway) in [#13766](https://github.com/facebook/react/pull/13766))

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2018-10-23-react-v-16-6.md)

----
url: https://legacy.reactjs.org/blog/2017/12/15/improving-the-repository-infrastructure.html
----

December 15, 2017 by [Dan Abramov](https://twitter.com/dan_abramov) and [Brian Vaughn](https://github.com/bvaughn)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

As we worked on [React 16](/blog/2017/09/26/react-v16.0.html), we revamped the folder structure and much of the build tooling in the React repository. Among other things, we introduced projects such as [Rollup](https://rollupjs.org/), [Prettier](https://prettier.io/), and [Google Closure Compiler](https://developers.google.com/closure/compiler/) into our workflow. People often ask us questions about how we use those tools. In this post, we would like to share some of the changes that we’ve made to our build and test infrastructure in 2017, and what motivated them.

While these changes helped us make React better, they don’t affect most React users directly. However, we hope that blogging about them might help other library authors solve similar problems. Our contributors might also find these notes helpful!

## [](#formatting-code-with-prettier)Formatting Code with Prettier

React was one of the first large repositories to [fully embrace](https://github.com/facebook/react/pull/9101) opinionated automatic code formatting with [Prettier](https://prettier.io/). Our current Prettier setup consists of:

* A local [`yarn prettier`](https://github.com/facebook/react/blob/cc52e06b490e0dc2482b345aa5d0d65fae931095/package.json#L115) script that [uses the Prettier Node API](https://github.com/facebook/react/blob/cc52e06b490e0dc2482b345aa5d0d65fae931095/scripts/prettier/index.js#L71-L77) to format files in place. We typically run it before committing changes. It is fast because it only checks the [files changed since diverging from remote master](https://github.com/facebook/react/blob/cc52e06b490e0dc2482b345aa5d0d65fae931095/scripts/shared/listChangedFiles.js#L29-L33).
* A script that [runs Prettier](https://github.com/facebook/react/blob/cc52e06b490e0dc2482b345aa5d0d65fae931095/scripts/prettier/index.js#L79-L90) as part of our [continuous integration checks](https://github.com/facebook/react/blob/d906de7f602df810c38aa622c83023228b047db6/scripts/circleci/test_entry_point.sh#L10). It won’t attempt to overwrite the files, but instead will fail the build if any file differs from the Prettier output for that file. This ensures that we can’t merge a pull request unless it has been fully formatted.

Some team members have also set up the [editor integrations](https://prettier.io/docs/en/editors.html). Our experience with Prettier has been fantastic, and we recommend it to any team that writes JavaScript.

## [](#restructuring-the-monorepo)Restructuring the Monorepo

Ever since React was split into packages, it has been a [monorepo](https://danluu.com/monorepo/): a set of packages under the umbrella of a single repository. This made it easier to coordinate changes and share the tooling, but our folder structure was deeply nested and difficult to understand. It was not clear which files belonged to which package. After releasing React 16, we’ve decided to completely reorganize the repository structure. Here is how we did it.

### [](#migrating-to-yarn-workspaces)Migrating to Yarn Workspaces

The Yarn package manager [introduced a feature called Workspaces](https://yarnpkg.com/blog/2017/08/02/introducing-workspaces/) a few months ago. This feature lets you tell Yarn where your monorepo’s packages are located in the source tree. Every time you run `yarn`, in addition to installing your dependencies it also sets up the symlinks that point from your project’s `node_modules` to the source folders of your packages.

Thanks to Workspaces, absolute imports between our own packages (such as importing `react` from `react-dom`) “just work” with any tools that support the Node resolution mechanism. The only problem we encountered was Jest not running the transforms inside the linked packages, but we [found a fix](https://github.com/facebook/jest/pull/4761), and it was merged into Jest.

To enable Yarn Workspaces, we added `"workspaces": ["packages/*"]` to our [`package.json`](https://github.com/facebook/react/blob/cc52e06b490e0dc2482b345aa5d0d65fae931095/package.json#L4-L6), and moved all the code into [top-level `packages/*` folders](https://github.com/facebook/react/tree/cc52e06b490e0dc2482b345aa5d0d65fae931095/packages), each with its own `package.json` file.

Each package is structured in a similar way. For every public API entry point such as `react-dom` or `react-dom/server`, there is a [file](https://github.com/facebook/react/blob/cc52e06b490e0dc2482b345aa5d0d65fae931095/packages/react-dom/index.js) in the package root folder that re-exports the implementation from the [`/src/`](https://github.com/facebook/react/tree/cc52e06b490e0dc2482b345aa5d0d65fae931095/packages/react-dom/src) subfolder. The decision to point entry points to the source rather than to the built versions was intentional. Typically, we re-run a subset of tests after every change during development. Having to build the project to run a test would have been prohibitively slow. When we publish packages to npm, we replace these entry points with files in the [`/npm/`](https://github.com/facebook/react/tree/cc52e06b490e0dc2482b345aa5d0d65fae931095/packages/react-dom/npm) folder that point to the build artifacts.

Not all packages have to be published on npm. For example, we keep some utilities that are tiny enough and can be safely duplicated in a [pseudo-package called `shared`](https://github.com/facebook/react/tree/cc52e06b490e0dc2482b345aa5d0d65fae931095/packages/shared). Our bundler is configured to [only treat `dependencies` declared from `package.json` as externals](https://github.com/facebook/react/blob/cc52e06b490e0dc2482b345aa5d0d65fae931095/scripts/rollup/build.js#L326-L329) so it happily bundles the `shared` code into `react` and `react-dom` without leaving any references to `shared/` in the build artifacts. So you can use Yarn Workspaces even if you don’t plan to publish actual npm packages!

### [](#removing-the-custom-module-system)Removing the Custom Module System

In the past, we used a non-standard module system called “Haste” that lets you import any file from any other file by its unique `@providesModule` directive no matter where it is in the tree. It neatly avoids the problem of deep relative imports with paths like `../../../../` and is great for the product code. However, this makes it hard to understand the dependencies between packages. We also had to resort to hacks to make it work with different tools.

We decided to [remove Haste](https://github.com/facebook/react/pull/11303) and use the Node resolution with relative imports instead. To avoid the problem of deep relative paths, we have [flattened our repository structure](https://github.com/facebook/react/pull/11304) so that it goes at most one level deep inside each package:

```
|-react
|  |-npm
|  |-src
|-react-dom
|  |-npm
|  |-src
|  |  |-client
|  |  |-events
|  |  |-server
|  |  |-shared
```

This way, the relative paths can only contain one `./` or `../` followed by the filename. If one package needs to import something from another package, it can do so with an absolute import from a top-level entry point.

In practice, we still have [some cross-package “internal” imports](https://github.com/facebook/react/blob/cc52e06b490e0dc2482b345aa5d0d65fae931095/packages/react-dom/src/client/ReactDOMFiberComponent.js#L10-L11) that violate this principle, but they’re explicit, and we plan to gradually get rid of them.

## [](#compiling-flat-bundles)Compiling Flat Bundles

Historically, React was distributed in two different formats: as a single-file build that you can add as a `<script>` tag in the browser, and as a collection of CommonJS modules that you can bundle with a tool like webpack or Browserify.

Before React 16, each React source file had a corresponding CommonJS module that was published as part of the npm packages. Importing `react` or `react-dom` led bundlers to the package [entry point](https://unpkg.com/react@15/index.js) from which they would build a dependency tree with the CommonJS modules in the [internal `lib` folder](https://unpkg.com/react@15/lib/).

However, this approach had multiple disadvantages:

* **It was inconsistent.** Different tools produce bundles of different sizes for identical code importing React, with the difference going as far as 30 kB (before gzip).
* **It was inefficient for bundler users.** The code produced by most bundlers today contains a lot of “glue code” at the module boundaries. It keeps the modules isolated from each other, but increases the parse time, the bundle size, and the build time.
* **It was inefficient for Node users.** When running in Node, performing `process.env.NODE_ENV` checks before development-only code incurs the overhead of actually looking up environment variables. This slowed down React server rendering. We couldn’t cache it in a variable either because it prevented dead code elimination with Uglify.
* **It broke encapsulation.** React internals were exposed both in the open source (as `react-dom/lib/*` imports) and internally at Facebook. It was convenient at first as a way to share utilities between projects, but with time it became a maintenance burden because renaming or changing argument types of internal functions would break unrelated projects.
* **It prevented experimentation.** There was no way for the React team to experiment with any advanced compilation techniques. For example, in theory, we might want to apply [Google Closure Compiler Advanced](https://developers.google.com/closure/compiler/docs/api-tutorial3) optimizations or [Prepack](https://prepack.io/) to some of our code, but they are designed to work on complete bundles rather than small individual modules that we used to ship to npm.

Due to these and other issues, we’ve changed the strategy in React 16. We still ship CommonJS modules for Node.js and bundlers, but instead of publishing many individual files in the npm package, we publish just two CommonJS bundles per entry point.

For example, when you import `react` with React 16, the bundler [finds the entry point](https://unpkg.com/react@16/index.js) that just re-exports one of the two files:

```
'use strict';

if (process.env.NODE_ENV === 'production') {
  module.exports = require('./cjs/react.production.min.js');
} else {
  module.exports = require('./cjs/react.development.js');
}
```

In every package provided by React, the [`cjs` folder](https://unpkg.com/react@16/cjs/) (short for “CommonJS”) contains a development and a production pre-built bundle for each entry point.

For example, [`react.development.js`](https://unpkg.com/react@16/cjs/react.development.js) is the version intended for development. It is readable and includes comments. On the other hand, [`react.production.min.js`](https://unpkg.com/react@16/cjs/react.production.min.js) was minified and optimized before it was published to npm.

Note how this is essentially the same strategy that we’ve been using for the single-file browser builds (which now reside in the [`umd` directory](https://unpkg.com/react@16/umd/), short for [Universal Module Definition](https://www.davidbcalhoun.com/2014/what-is-amd-commonjs-and-umd/)). Now we just apply the same strategy to the CommonJS builds as well.

### [](#migrating-to-rollup)Migrating to Rollup

Just compiling CommonJS modules into single-file bundles doesn’t solve all of the above problems. The really significant wins came from [migrating our build system](https://github.com/facebook/react/pull/9327) from Browserify to [Rollup](https://rollupjs.org/).

[Rollup was designed with libraries rather than apps in mind](https://medium.com/webpack/webpack-and-rollup-the-same-but-different-a41ad427058c), and it is a perfect fit for React’s use case. It solves one problem well: how to combine multiple modules into a flat file with minimal junk code in between. To achieve this, instead of turning modules into functions like many other bundlers, it puts all the code in the same scope, and renames variables so that they don’t conflict. This produces code that is easier for the JavaScript engine to parse, for a human to read, and for a minifier to optimize.

Rollup currently doesn’t support some features that are important to application builders, such as code splitting. However, it does not aim to replace tools like webpack that do a great job at this. Rollup is a perfect fit for *libraries* like React that can be pre-built and then integrated into apps.

You can find our Rollup build configuration [here](https://github.com/facebook/react/blob/8ec146c38ee4f4c84b6ecf59f52de3371224e8bd/scripts/rollup/build.js#L336-L362), with a [list of plugins we currently use](https://github.com/facebook/react/blob/8ec146c38ee4f4c84b6ecf59f52de3371224e8bd/scripts/rollup/build.js#L196-L273).

### [](#migrating-to-google-closure-compiler)Migrating to Google Closure Compiler

After migrating to flat bundles, we [started](https://github.com/facebook/react/pull/10236) using [the JavaScript version of the Google Closure Compiler](https://github.com/google/closure-compiler-js) in its “simple” mode. In our experience, even with the advanced optimizations disabled, it still provided a significant advantage over Uglify, as it was able to better eliminate dead code and automatically inline small functions when appropriate.

At first, we could only use Google Closure Compiler for the React bundles we shipped in the open source. At Facebook, we still needed the checked-in bundles to be unminified so we could symbolicate React production crashes with our error reporting tools. We ended up contributing [a flag](https://github.com/google/closure-compiler/pull/2707) that completely disables the renaming compiler pass. This lets us apply other optimizations like function inlining, but keep the code fully readable for the Facebook-specific builds of React. To improve the output readability, we [also format that custom build using Prettier](https://github.com/facebook/react/blob/cc52e06b490e0dc2482b345aa5d0d65fae931095/scripts/rollup/build.js#L249-L250). Interestingly, running Prettier on production bundles while debugging the build process is a great way to find unnecessary code in the bundles!

Currently, all production React bundles [run through Google Closure Compiler in simple mode](https://github.com/facebook/react/blob/cc52e06b490e0dc2482b345aa5d0d65fae931095/scripts/rollup/build.js#L235-L248), and we may look into enabling advanced optimizations in the future.

### [](#protecting-against-weak-dead-code-elimination)Protecting Against Weak Dead Code Elimination

While we use an efficient [dead code elimination](https://en.wikipedia.org/wiki/Dead_code_elimination) solution in React itself, we can’t make a lot of assumptions about the tools used by the React consumers.

Typically, when you [configure a bundler for production](/docs/optimizing-performance.html#use-the-production-build), you need to tell it to substitute `process.env.NODE_ENV` with the `"production"` string literal. This process is sometimes called “envification”. Consider this code:

```
if (process.env.NODE_ENV !== "production") {
  // development-only code
}
```

After envification, this condition will always be `false`, and can be completely eliminated by most minifiers:

```
if ("production" !== "production") {
  // development-only code
}
```

However, if the bundler is misconfigured, you can accidentally ship development code into production. We can’t completely prevent this, but we took a few steps to mitigate the common cases when it happens.

#### [](#protecting-against-late-envification)Protecting Against Late Envification

As mentioned above, our entry points now look like this:

```
'use strict';

if (process.env.NODE_ENV === 'production') {
  module.exports = require('./cjs/react.production.min.js');
} else {
  module.exports = require('./cjs/react.development.js');
}
```

However, some bundlers process `require`s before envification. In this case, even if the `else` block never executes, the `cjs/react.development.js` file still gets bundled.

To prevent this, we also [wrap the whole content](https://github.com/facebook/react/blob/d906de7f602df810c38aa622c83023228b047db6/scripts/rollup/wrappers.js#L65-L69) of the development bundle into another `process.env.NODE_ENV` check inside the `cjs/react.development.js` bundle itself:

```
'use strict';

if (process.env.NODE_ENV !== "production") {
  (function() {
    // bundle code
  })();
}
```

This way, even if the application bundle includes both the development and the production versions of the file, the development version will be empty after envification.

The additional [IIFE](https://en.wikipedia.org/wiki/Immediately-invoked_function_expression) wrapper is necessary because some declarations (e.g. functions) can’t be placed inside an `if` statement in JavaScript.

#### [](#detecting-misconfigured-dead-code-elimination)Detecting Misconfigured Dead Code Elimination

Even though [the situation is changing](https://twitter.com/iamakulov/status/941336777188696066), many popular bundlers don’t yet force the users to specify the development or production mode. In this case `process.env.NODE_ENV` is typically provided by a runtime polyfill, but the dead code elimination doesn’t work.

We can’t completely prevent React users from misconfiguring their bundlers, but we introduced a few additional checks for this in [React DevTools](https://github.com/facebook/react-devtools).

If the development bundle executes, [React DOM reports this to React DevTools](https://github.com/facebook/react/blob/d906de7f602df810c38aa622c83023228b047db6/packages/react-dom/src/client/ReactDOM.js#L1333-L1335):



There is also one more bad scenario. Sometimes, `process.env.NODE_ENV` is set to `"production"` at runtime rather than at the build time. This is how it should work in Node.js, but it is bad for the client-side builds because the unnecessary development code is bundled even though it never executes. This is harder to detect but we found a heuristic that works well in most cases and doesn’t seem to produce false positives.

We can write a function that contains a [development-only branch](https://github.com/facebook/react/blob/d906de7f602df810c38aa622c83023228b047db6/packages/react-dom/npm/index.js#L11-L20) with an arbitrary string literal. Then, if `process.env.NODE_ENV` is set to `"production"`, we can [call `toString()` on that function](https://github.com/facebook/react-devtools/blob/b370497ba6e873c63479408f11d784095523a630/backend/installGlobalHook.js#L143) and verify that the string literal in the development-only has been stripped out. If it is still there, the dead code elimination didn’t work, and we need to warn the developer. Since developers might not notice the React DevTools warnings on a production website, we also [throw an error inside `setTimeout`](https://github.com/facebook/react-devtools/blob/b370497ba6e873c63479408f11d784095523a630/backend/installGlobalHook.js#L153-L160) from React DevTools in the hope that it will be picked up by the error analytics.

We recognize this approach is somewhat fragile. The `toString()` method is not reliable and may change its behavior in future browser versions. This is why we put that logic into React DevTools itself rather than into React. This allows us to remove it later if it becomes problematic. We also warn only if we *found* the special string literal rather than if we *didn’t* find it. This way, if the `toString()` output becomes opaque, or is overridden, the warning just won’t fire.

## [](#catching-mistakes-early)Catching Mistakes Early

We want to catch bugs as early as possible. However, even with our extensive test coverage, occasionally we make a blunder. We made several changes to our build and test infrastructure this year to make it harder to mess up.

### [](#migrating-to-es-modules)Migrating to ES Modules

With the CommonJS `require()` and `module.exports`, it is easy to import a function that doesn’t really exist, and not realize that until you call it. However, tools like Rollup that natively support [`import`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import) and [`export`](https://developer.mozilla.org/en-US/docs/web/javascript/reference/statements/export) syntax fail the build if you mistype a named import. After releasing React 16, [we have converted the entire React source code](https://github.com/facebook/react/pull/11389) to the ES Modules syntax.

Not only did this provide some extra protection, but it also helped improve the build size. Many React modules only export utility functions, but CommonJS forced us to wrap them into an object. By turning those utility functions into named exports and eliminating the objects that contained them, we let Rollup place them into the top-level scope, and thus let the minifier mangle their names in the production builds.

For now, have decided to only convert the source code to ES Modules, but not the tests. We use powerful utilities like `jest.resetModules()` and want to retain tighter control over when the modules get initialized in tests. In order to consume ES Modules from our tests, we enabled the [Babel CommonJS transform](https://github.com/facebook/react/blob/cc52e06b490e0dc2482b345aa5d0d65fae931095/scripts/jest/preprocessor.js#L28-L29), but only for the test environment.

### [](#running-tests-in-production-mode)Running Tests in Production Mode

Historically, we’ve been running all tests in a development environment. This let us assert on the warning messages produced by React, and seemed to make general sense. However, even though we try to keep the differences between the development and production code paths minimal, occasionally we would make a mistake in production-only code branches that weren’t covered by tests, and cause an issue at Facebook.

To solve this problem, we have added a new [`yarn test-prod`](https://github.com/facebook/react/blob/cc52e06b490e0dc2482b345aa5d0d65fae931095/package.json#L110) command that runs on CI for every pull request, and [executes all React test cases in the production mode](https://github.com/facebook/react/pull/11616). We wrapped any assertions about warning messages into development-only conditional blocks in all tests so that they can still check the rest of the expected behavior in both environments. Since we have a custom Babel transform that replaces production error messages with the [error codes](/blog/2016/07/11/introducing-reacts-error-code-system.html), we also added a [reverse transformation](https://github.com/facebook/react/blob/cc52e06b490e0dc2482b345aa5d0d65fae931095/scripts/jest/setupTests.js#L91-L126) as part of the production test run.

### [](#using-public-api-in-tests)Using Public API in Tests

When we were [rewriting the React reconciler](https://code.facebook.com/posts/1716776591680069/react-16-a-look-inside-an-api-compatible-rewrite-of-our-frontend-ui-library/), we recognized the importance of writing tests against the public API instead of internal modules. If the test is written against the public API, it is clear what is being tested from the user’s perspective, and you can run it even if you rewrite the implementation from scratch.

We reached out to the wonderful React community [asking for help](https://github.com/facebook/react/issues/11299) converting the remaining tests to use the public API. Almost all of the tests are converted now! The process wasn’t easy. Sometimes a unit test just calls an internal method, and it’s hard to figure out what the observable behavior from user’s point of view was supposed to be tested. We found a few strategies that helped with this. The first thing we would try is to find the git history for when the test was added, and find clues in the issue and pull request description. Often they would contain reproducing cases that ended up being more valuable than the original unit tests! A good way to verify the guess is to try commenting out individual lines in the source code being tested. If the test fails, we know for sure that it stresses the given code path.

We would like to give our deepest thanks to [everyone who contributed to this effort](https://github.com/facebook/react/issues?q=is%3Apr+11299+is%3Aclosed).

### [](#running-tests-on-compiled-bundles)Running Tests on Compiled Bundles

There is also one more benefit to writing tests against the public API: now we can [run them against the compiled bundles](https://github.com/facebook/react/pull/11633).

This helps us ensure that tools like Babel, Rollup, and Google Closure Compiler don’t introduce any regressions. This also opens the door for future more aggressive optimizations, as we can be confident that React still behaves exactly as expected after them.

To implement this, we have created a [second Jest config](https://github.com/facebook/react/blob/cc52e06b490e0dc2482b345aa5d0d65fae931095/scripts/jest/config.build.js). It overrides our default config but points `react`, `react-dom`, and other entry points to the `/build/packages/` folder. This folder doesn’t contain any React source code, and reflects what gets published to npm. It is populated after you run `yarn build`.

This lets us run the same exact tests that we normally run against the source, but execute them using both development and production pre-built React bundles produced with Rollup and Google Closure Compiler.

Unlike the normal test run, the bundle test run depends on the build products so it is not great for quick iteration. However, it still runs on the CI server so if something breaks, the test will display as failed, and we will know it’s not safe to merge into main.

There are still some test files that we intentionally don’t run against the bundles. Sometimes we want to mock an internal module or override a feature flag that isn’t exposed to the public yet. For those cases, we blacklist a test file by renaming it from `MyModule-test.js` to `MyModule-test.internal.js`.

Currently, over 93% out of 2,650 React tests run against the compiled bundles.

### [](#linting-compiled-bundles)Linting Compiled Bundles

In addition to linting our source code, we run a much more limited set of lint rules (really, [just two of them](https://github.com/facebook/react/blob/cc52e06b490e0dc2482b345aa5d0d65fae931095/scripts/rollup/validate/eslintrc.cjs.js#L26-L27)) on the compiled bundles. This gives us an extra layer of protection against regressions in the underlying tools and [ensures](https://github.com/facebook/react/blob/cc52e06b490e0dc2482b345aa5d0d65fae931095/scripts/rollup/validate/eslintrc.cjs.js#L22) that the bundles don’t use any language features that aren’t supported by older browsers.

### [](#simulating-package-publishing)Simulating Package Publishing

Even running the tests on the built packages is not enough to avoid shipping a broken update. For example, we use the `files` field in our `package.json` files to specify a whitelist of folders and files that should be published on npm. However, it is easy to add a new entry point to a package but forget to add it to the whitelist. Even the bundle tests would pass, but after publishing the new entry point would be missing.

To avoid situations like this, we are now simulating the npm publish by [running `npm pack` and then immediately unpacking the archive](https://github.com/facebook/react/blob/cc52e06b490e0dc2482b345aa5d0d65fae931095/scripts/rollup/packaging.js#L129-L134) after the build. Just like `npm publish`, this command filters out anything that isn’t in the `files` whitelist. With this approach, if we were to forget adding an entry point to the list, it would be missing in the build folder, and the bundle tests relying on it would fail.

### [](#creating-manual-test-fixtures)Creating Manual Test Fixtures

Our unit tests run only in the Node environment, but not in the browsers. This was an intentional decision because browser-based testing tools were flaky in our experience, and didn’t catch many issues anyway.

We could get away with this because the code that touches the DOM is consolidated in a few files, and doesn’t change that often. Every week, we update the Facebook.com codebase to the latest React commit on master. At Facebook, we use a set of internal [WebDriver](http://www.seleniumhq.org/projects/webdriver/) tests for critical product workflows, and these catch some regressions. React updates are first delivered to employees, so severe bugs get reported immediately before they reach two billion users.

Still, it was hard to review DOM-related changes, and occasionally we would make mistakes. In particular, it was hard to remember all the edge cases that the code had to handle, why they were added, and when it was safe to remove them. We considered adding some automatic tests that run in the browser but we didn’t want to slow down the development cycle and deal with a fragile CI. Additionally, automatic tests don’t always catch DOM issues. For example, an input value displayed by the browser may not match what it reports as a DOM property.

We’ve chatted about this with [Brandon Dail](https://github.com/aweary), [Jason Quense](https://github.com/jquense), and [Nathan Hunzaker](https://github.com/nhunzaker). They were sending substantial patches to React DOM but were frustrated that we failed to review them timely. We decided to give them commit access, but asked them to [create a set of manual tests](https://github.com/facebook/react/pull/8589) for DOM-related areas like input management. The initial set of manual fixtures [kept growing](https://github.com/facebook/react/commits/main/fixtures/dom) over the year.

These fixtures are implemented as a React app located in [`fixtures/dom`](https://github.com/facebook/react/tree/d906de7f602df810c38aa622c83023228b047db6/fixtures/dom). Adding a fixture involves writing a React component with a description of the expected behavior, and links to the appropriate issues and browser quirks, like [in this example](https://github.com/facebook/react/pull/11760):

The fixture app lets you choose a version of React (local or one of the published versions) which is handy for comparing the behavior before and after the changes. When we change the behavior related to how we interact with the DOM, we can verify that it didn’t regress by going through the related fixtures in different browsers.

In some cases, a change proved to be so complex that it necessitated a standalone purpose-built fixture to verify it. For example, the [DOM attribute handling in React 16](/blog/2017/09/08/dom-attributes-in-react-16.html) was very hard to pull off with confidence at first. We kept discovering different edge cases, and almost gave up on doing it in time for the React 16 release. However, then we’ve built an [“attribute table” fixture](https://github.com/facebook/react/tree/d906de7f602df810c38aa622c83023228b047db6/fixtures/attribute-behavior) that renders all supported attributes and their misspellings with previous and next version of React, and displays the differences. It took a few iterations (the key insight was to group attributes with similar behavior together) but it ultimately allowed us to fix all major issues in just a few days.



> We went through the table to vet the new behavior for every case (and discovered some old bugs too) [pic.twitter.com/cmF2qnK9Q9](https://t.co/cmF2qnK9Q9)
>
> — Dan Abramov (@dan\_abramov) [September 8, 2017](https://twitter.com/dan_abramov/status/906244378066345984?ref_src=twsrc%5Etfw)

Going through the fixtures is still a lot of work, and we are considering automating some of it. Still, the fixture app is invaluable even as documentation for the existing behavior and all the edge cases and browser bugs that React currently handles. Having it gives us confidence in making significant changes to the logic without breaking important use cases. Another improvement we’re considering is to have a GitHub bot build and deploy the fixtures automatically for every pull request that touches the relevant files so anyone can help with browser testing.

### [](#preventing-infinite-loops)Preventing Infinite Loops

The React 16 codebase contains many `while` loops. They let us avoid the dreaded deep stack traces that occurred with earlier versions of React, but can make development of React really difficult. Every time there is a mistake in an exit condition our tests would just hang, and it took a while to figure out which of the loops is causing the issue.

Inspired by the [strategy adopted by Repl.it](https://repl.it/site/blog/infinite-loops), we have added a [Babel plugin that prevents infinite loops](https://github.com/facebook/react/blob/d906de7f602df810c38aa622c83023228b047db6/scripts/babel/transform-prevent-infinite-loops.js) in the test environment. If some loop continues for more than the maximum allowed number of iterations, we throw an error and immediately fail it so that Jest can display where exactly this happened.

This approach has a pitfall. If an error thrown from the Babel plugin gets caught and ignored up the call stack, the test will pass even though it has an infinite loop. This is really, really bad. To solve this problem, we [set a global field](https://github.com/facebook/react/blob/d906de7f602df810c38aa622c83023228b047db6/scripts/babel/transform-prevent-infinite-loops.js#L26-L30) before throwing the error. Then, after every test run, we [rethrow that error if the global field has been set](https://github.com/facebook/react/blob/d906de7f602df810c38aa622c83023228b047db6/scripts/jest/setupTests.js#L42-L56). This way any infinite loop will cause a test failure, no matter whether the error from the Babel plugin was caught or not.

## [](#customizing-the-build)Customizing the Build

There were a few things that we had to fine-tune after introducing our new build process. It took us a while to figure them out, but we’re moderately happy with the solutions that we arrived at.

### [](#dead-code-elimination)Dead Code Elimination

The combination of Rollup and Google Closure Compiler already gets us pretty far in terms of stripping development-only code in production bundles. We [replace](https://github.com/facebook/react/blob/cc52e06b490e0dc2482b345aa5d0d65fae931095/scripts/rollup/build.js#L223-L226) the `__DEV__` literal with a boolean constant during the build, and both Rollup together and Google Closure Compiler can strip out the `if (false) {}` code branches and even some more sophisticated patterns. However, there is one particularly nasty case:

```
import warning from 'fbjs/lib/warning';

if (__DEV__) {
  warning(false, 'Blimey!');
}
```

This pattern is very common in the React source code. However `fbjs/lib/warning` is an external import that isn’t being bundled by Rollup for the CommonJS bundle. Therefore, even if `warning()` call ends up being removed, Rollup doesn’t know whether it’s safe to remove to the import itself. What if the module performs a side effect during initialization? Then removing it would not be safe.

To solve this problem, we use the [`treeshake.pureExternalModules` Rollup option](https://github.com/facebook/react/blob/cc52e06b490e0dc2482b345aa5d0d65fae931095/scripts/rollup/build.js#L338-L340) which takes an array of modules that we can guarantee don’t have side effects. This lets Rollup know that an import to `fbjs/lib/warning` is safe to completely strip out if its value is not being used. However, if it *is* being used (e.g. if we decide to add warnings in production), the import will be preserved. That’s why this approach is safer than replacing modules with empty shims.

When we optimize something, we need to ensure it doesn’t regress in the future. What if somebody introduces a new development-only import of an external module, and not realize they also need to add it to `pureExternalModules`? Rollup prints a warning in such cases but we’ve [decided to fail the build completely](https://github.com/facebook/react/blob/cc52e06b490e0dc2482b345aa5d0d65fae931095/scripts/rollup/build.js#L395-L412) instead. This forces the person adding a new external development-only import to [explicitly specify whether it has side effects or not](https://github.com/facebook/react/blob/cc52e06b490e0dc2482b345aa5d0d65fae931095/scripts/rollup/modules.js#L10-L22) every time.

### [](#forking-modules)Forking Modules

In some cases, different bundles need to contain slightly different code. For example, React Native bundles have a different error handling mechanism that shows a redbox instead of printing a message to the console. However, it can be very inconvenient to thread these differences all the way through the calling modules.

Problems like this are often solved with runtime configuration. However, sometimes it is impossible: for example, the React DOM bundles shouldn’t even attempt to import the React Native redbox helpers. It is also unfortunate to bundle the code that never gets used in a particular environment.

Another solution is to use dynamic dependency injection. However, it often produces code that is hard to understand, and may cause cyclical dependencies. It also defies some optimization opportunities.

From the code point of view, ideally we just want to “redirect” a module to its different “forks” for specific bundles. The “forks” have the exact same API as the original modules, but do something different. We found this mental model very intuitive, and [created a fork configuration file](https://github.com/facebook/react/blob/cc52e06b490e0dc2482b345aa5d0d65fae931095/scripts/rollup/forks.js) that specifies how the original modules map to their forks, and the conditions under which this should happen.

For example, this fork config entry specifies different [feature flags](https://github.com/facebook/react/blob/cc52e06b490e0dc2482b345aa5d0d65fae931095/packages/shared/ReactFeatureFlags.js) for different bundles:

```
'shared/ReactFeatureFlags': (bundleType, entry) => {
  switch (entry) {
    case 'react-native-renderer':
      return 'shared/forks/ReactFeatureFlags.native.js';
    case 'react-cs-renderer':
      return 'shared/forks/ReactFeatureFlags.native-cs.js';
    default:
      switch (bundleType) {
        case FB_DEV:
        case FB_PROD:
          return 'shared/forks/ReactFeatureFlags.www.js';
      }
  }
  return null;
},
```

During the build, [our custom Rollup plugin](https://github.com/facebook/react/blob/cc52e06b490e0dc2482b345aa5d0d65fae931095/scripts/rollup/plugins/use-forks-plugin.js#L40) replaces modules with their forks if the conditions have matched. Since both the original modules and the forks are written as ES Modules, Rollup and Google Closure Compiler can inline constants like numbers or booleans, and thus efficiently eliminate dead code for disabled feature flags. In tests, when necessary, we [use `jest.mock()`](https://github.com/facebook/react/blob/cc52e06b490e0dc2482b345aa5d0d65fae931095/packages/react-cs-renderer/src/__tests__/ReactNativeCS-test.internal.js#L15-L17) to point the module to the appropriate forked version.

As a bonus, we might want to verify that the export types of the original modules match the export types of the forks exactly. We can use a [slightly odd but totally working Flow trick](https://github.com/facebook/react/blob/cc52e06b490e0dc2482b345aa5d0d65fae931095/packages/shared/forks/ReactFeatureFlags.native.js#L32-L36) to accomplish this:

```
import typeof * as FeatureFlagsType from 'shared/ReactFeatureFlags';
import typeof * as FeatureFlagsShimType from './ReactFeatureFlags.native';
type Check<_X, Y: _X, X: Y = _X> = null;
(null: Check<FeatureFlagsShimType, FeatureFlagsType>);
```

This works by essentially forcing Flow to verify that two types are assignable to each other (and thus are equivalent). Now if we modify the exports of either the original module or the fork without changing the other file, the type check will fail. This might be a little goofy but we found this helpful in practice.

To conclude this section, it is important to note that you can’t specify your own module forks if you consume React from npm. This is intentional because none of these files are public API, and they are not covered by the [semver](https://semver.org/) guarantees. However, you are always welcome to build React from master or even fork it if you don’t mind the instability and the risk of divergence. We hope that this writeup was still helpful in documenting one possible approach to targeting different environments from a single JavaScript library.

### [](#tracking-bundle-size)Tracking Bundle Size

As a final build step, we now [record build sizes for all bundles](https://github.com/facebook/react/blob/d906de7f602df810c38aa622c83023228b047db6/scripts/rollup/build.js#L264-L272) and write them to a file that [looks like this](https://github.com/facebook/react/blob/d906de7f602df810c38aa622c83023228b047db6/scripts/rollup/results.json). When you run `yarn build`, it prints a table with the results:



*(It doesn’t always look as good as this. This was the commit that migrated React from Uglify to Google Closure Compiler.)*

Keeping the file sizes committed for everyone to see was helpful for tracking size changes and motivating people to find optimization opportunities.

We haven’t been entirely happy with this strategy because the JSON file often causes merge conflicts on larger branches. Updating it is also not currently enforced so it gets out of date. In the future, we’re considering integrating a bot that would comment on pull requests with the size changes.

## [](#simplifying-the-release-process)Simplifying the Release Process

We like to release updates to the open source community often. Unfortunately, the old process of creating a release was slow and would typically take an entire day. After some changes to this process, we’re now able to do a full release in less than an hour. Here’s what we changed.

### [](#branching-strategy)Branching Strategy

Most of the time spent in the old release process was due to our branching strategy. The `main` branch was assumed to be unstable and would often contain breaking changes. Releases were done from a `stable` branch, and changes were manually cherry-picked into this branch prior to a release. We had [tooling to help automate](https://github.com/facebook/react/pull/7330) some of this process, but it was still [pretty complicated to use](https://github.com/facebook/react/blob/b5a2a1349d6e804d534f673612357c0be7e1d701/scripts/release-manager/Readme.md).

As of version 16, we now release from the `main` branch. Experimental features and breaking changes are allowed, but must be hidden behind [feature flags](https://github.com/facebook/react/blob/cc52e06b490e0dc2482b345aa5d0d65fae931095/packages/shared/ReactFeatureFlags.js) so they can be removed during the build process. The new flat bundles and dead code elimination make it possible for us to do this without fear of leaking unwanted code into open source builds.

### [](#automated-scripts)Automated Scripts

After changing to a stable `main`, we created a new [release process checklist](https://github.com/facebook/react/issues/10620). Although much simpler than the previous process, this still involved dozens of steps and forgetting one could result in a broken release.

To address this, we created a new [automated release process](https://github.com/facebook/react/pull/11223) that is [much easier to use](https://github.com/facebook/react/tree/main/scripts/release#react-release-script) and has several built-in checks to ensure that we release a working build. The new process is split into two steps: *build* and *publish*. Here’s what it looks like the first time you run it:

The *build* step does most of the work- verifying permissions, running tests, and checking CI status. Once it finishes, it prints a reminder to update the CHANGELOG and to verify the bundle using the [manual fixtures](#creating-manual-test-fixtures) described above.

All that’s left is to tag and publish the release to NPM using the *publish* script.

(You may have noticed a `--dry` flag in the screenshots above. This flag allows us to run a release, end-to-end, without actually publishing to NPM. This is useful when working on the release script itself.)

## [](#in-conclusion)In Conclusion

Did this post inspire you to try some of these ideas in your own projects? We certainly hope so! If you have other ideas about how React build, test, or contribution workflow could be improved, please let us know on [our issue tracker](https://github.com/facebook/react/issues).

You can find the related issues by the [build infrastructure label](https://github.com/facebook/react/labels/Component%3A%20Build%20Infrastructure). These are often great first contribution opportunities!

## [](#acknowledgements)Acknowledgements

We would like to thank:

* [Rich Harris](https://github.com/Rich-Harris) and [Lukas Taegert](https://github.com/lukastaegert) for maintaining Rollup and helping us integrate it.
* [Dimitris Vardoulakis](https://github.com/dimvar), [Chad Killingsworth](https://github.com/ChadKillingsworth), and [Tyler Breisacher](https://github.com/MatrixFrog) for their work on Google Closure Compiler and timely advice.
* [Adrian Carolli](https://github.com/watadarkstar), [Adams Au](https://github.com/rivenhk), [Alex Cordeiro](https://github.com/accordeiro), [Jordan Tepper](https://github.com/HeroProtagonist), [Johnson Shi](https://github.com/sjy), [Soo Jae Hwang](https://github.com/misoguy), [Joe Lim](https://github.com/xjlim), [Yu Tian](https://github.com/yu-tian113), and others for helping prototype and implement some of these and other improvements.
* [Anushree Subramani](https://github.com/anushreesubramani), [Abid Uzair](https://github.com/abiduzz420), [Sotiris Kiritsis](https://github.com/skiritsis), [Tim Jacobi](https://github.com/timjacobi), [Anton Arboleda](https://github.com/aarboleda1), [Jeremias Menichelli](https://github.com/jeremenichelli), [Audy Tanudjaja](https://github.com/audyodi), [Gordon Dent](https://github.com/gordyd), [Iacami Gevaerd ](https://github.com/enapupe), [Lucas Lentz](https://github.com/sadpandabear), [Jonathan Silvestri](https://github.com/silvestrijonathan), [Mike Wilcox](https://github.com/mjw56), [Bernardo Smaniotto](https://github.com/smaniotto), [Douglas Gimli](https://github.com/douglasgimli), [Ethan Arrowood](https://github.com/ethan-arrowood), and others for their help porting the React test suite to use the public API.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2017-12-15-improving-the-repository-infrastructure.md)

----
url: https://legacy.reactjs.org/docs/web-components.html
----

> These docs are old and won’t be updated. Go to [react.dev](https://react.dev/) for the new React docs.
>
> See [Custom HTML elements](https://react.dev/reference/react-dom/components#custom-html-elements) in the new docs.

React and [Web Components](https://developer.mozilla.org/en-US/docs/Web/Web_Components) are built to solve different problems. Web Components provide strong encapsulation for reusable components, while React provides a declarative library that keeps the DOM in sync with your data. The two goals are complementary. As a developer, you are free to use React in your Web Components, or to use Web Components in React, or both.

Most people who use React don’t use Web Components, but you may want to, especially if you are using third-party UI components that are written using Web Components.

## [](#using-web-components-in-react)Using Web Components in React

```
class HelloMessage extends React.Component {
  render() {
    return <div>Hello <x-search>{this.props.name}</x-search>!</div>;
  }
}
```

> Note:
>
> Web Components often expose an imperative API. For instance, a `video` Web Component might expose `play()` and `pause()` functions. To access the imperative APIs of a Web Component, you will need to use a ref to interact with the DOM node directly. If you are using third-party Web Components, the best solution is to write a React component that behaves as a wrapper for your Web Component.
>
> Events emitted by a Web Component may not properly propagate through a React render tree. You will need to manually attach event handlers to handle these events within your React components.

One common confusion is that Web Components use “class” instead of “className”.

```
function BrickFlipbox() {
  return (
    <brick-flipbox class="demo">
      <div>front</div>
      <div>back</div>
    </brick-flipbox>
  );
}
```

## [](#using-react-in-your-web-components)Using React in your Web Components

```
class XSearch extends HTMLElement {
  connectedCallback() {
    const mountPoint = document.createElement('span');
    this.attachShadow({ mode: 'open' }).appendChild(mountPoint);

    const name = this.getAttribute('name');
    const url = 'https://www.google.com/search?q=' + encodeURIComponent(name);
    const root = ReactDOM.createRoot(mountPoint);
    root.render(<a href={url}>{name}</a>);
  }
}
customElements.define('x-search', XSearch);
```

> Note:
>
> This code **will not** work if you transform classes with Babel. See [this issue](https://github.com/w3c/webcomponents/issues/587) for the discussion. Include the [custom-elements-es5-adapter](https://github.com/webcomponents/polyfills/tree/master/packages/webcomponentsjs#custom-elements-es5-adapterjs) before you load your web components to fix this issue.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/web-components.md)

----
url: https://legacy.reactjs.org/docs/uncontrolled-components.html
----

> These docs are old and won’t be updated. Go to [react.dev](https://react.dev/) for the new React docs.
>
> These new documentation pages teach modern React and include live examples:
>
> * [`<input>`](https://react.dev/reference/react-dom/components/input)
> * [`<select>`](https://react.dev/reference/react-dom/components/select)
> * [`<textarea>`](https://react.dev/reference/react-dom/components/textarea)

In most cases, we recommend using [controlled components](/docs/forms.html#controlled-components) to implement forms. In a controlled component, form data is handled by a React component. The alternative is uncontrolled components, where form data is handled by the DOM itself.

To write an uncontrolled component, instead of writing an event handler for every state update, you can [use a ref](/docs/refs-and-the-dom.html) to get form values from the DOM.

For example, this code accepts a single name in an uncontrolled component:

```
class NameForm extends React.Component {
  constructor(props) {
    super(props);
    this.handleSubmit = this.handleSubmit.bind(this);
    this.input = React.createRef();  }

  handleSubmit(event) {
    alert('A name was submitted: ' + this.input.current.value);    event.preventDefault();
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Name:
          <input type="text" ref={this.input} />        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}
```

[**Try it on CodePen**](https://codepen.io/gaearon/pen/WooRWa?editors=0010)

Since an uncontrolled component keeps the source of truth in the DOM, it is sometimes easier to integrate React and non-React code when using uncontrolled components. It can also be slightly less code if you want to be quick and dirty. Otherwise, you should usually use controlled components.

If it’s still not clear which type of component you should use for a particular situation, you might find [this article on controlled versus uncontrolled inputs](https://goshakkk.name/controlled-vs-uncontrolled-inputs-react/) to be helpful.

### [](#default-values)Default Values

In the React rendering lifecycle, the `value` attribute on form elements will override the value in the DOM. With an uncontrolled component, you often want React to specify the initial value, but leave subsequent updates uncontrolled. To handle this case, you can specify a `defaultValue` attribute instead of `value`. Changing the value of `defaultValue` attribute after a component has mounted will not cause any update of the value in the DOM.

```
render() {
  return (
    <form onSubmit={this.handleSubmit}>
      <label>
        Name:
        <input
          defaultValue="Bob"          type="text"
          ref={this.input} />
      </label>
      <input type="submit" value="Submit" />
    </form>
  );
}
```

Likewise, `<input type="checkbox">` and `<input type="radio">` support `defaultChecked`, and `<select>` and `<textarea>` supports `defaultValue`.

## [](#the-file-input-tag)The file input Tag

In HTML, an `<input type="file">` lets the user choose one or more files from their device storage to be uploaded to a server or manipulated by JavaScript via the [File API](https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications).

```
<input type="file" />
```

In React, an `<input type="file" />` is always an uncontrolled component because its value can only be set by a user, and not programmatically.

You should use the File API to interact with the files. The following example shows how to create a [ref to the DOM node](/docs/refs-and-the-dom.html) to access file(s) in a submit handler:

```
class FileInput extends React.Component {
  constructor(props) {
    super(props);
    this.handleSubmit = this.handleSubmit.bind(this);
    this.fileInput = React.createRef();  }
  handleSubmit(event) {
    event.preventDefault();
    alert(
      `Selected file - ${this.fileInput.current.files[0].name}`    );
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Upload file:
          <input type="file" ref={this.fileInput} />        </label>
        <br />
        <button type="submit">Submit</button>
      </form>
    );
  }
}

const root = ReactDOM.createRoot(
  document.getElementById('root')
);
root.render(<FileInput />);
```

[**Try it on CodePen**](/redirect-to-codepen/uncontrolled-components/input-type-file)

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/uncontrolled-components.md)

----
url: https://react.dev/learn/setup
----

[Learn React](/learn)

# Setup[](#undefined "Link for this heading")

React integrates with tools like editors, TypeScript, browser extensions, and compilers. This section will help you get your environment set up.

## Editor Setup[](#editor-setup "Link for Editor Setup ")

See our [recommended editors](/learn/editor-setup) and learn how to set them up to work with React.

## Using TypeScript[](#using-typescript "Link for Using TypeScript ")

TypeScript is a popular way to add type definitions to JavaScript codebases. [Learn how to integrate TypeScript into your React projects](/learn/typescript).

## React Developer Tools[](#react-developer-tools "Link for React Developer Tools ")

React Developer Tools is a browser extension that can inspect React components, edit props and state, and identify performance problems. Learn how to install it [here](/learn/react-developer-tools).

## React Compiler[](#react-compiler "Link for React Compiler ")

React Compiler is a tool that automatically optimizes your React app. [Learn more](/learn/react-compiler).

## Next steps[](#next-steps "Link for Next steps ")

Head to the [Quick Start](/learn) guide for a tour of the most important React concepts you will encounter every day.

[PreviousAdd React to an Existing Project](/learn/add-react-to-an-existing-project)

[NextEditor Setup](/learn/editor-setup)

***

----
url: https://react.dev/learn/synchronizing-with-effects
----

```
import { useEffect } from 'react';
```

Then, call it at the top level of your component and put some code inside your Effect:

```
function MyComponent() {

  useEffect(() => {

    // Code here will run after *every* render

  });

  return <div />;

}
```

Every time your component renders, React will update the screen *and then* run the code inside `useEffect`. In other words, **`useEffect` “delays” a piece of code from running until that render is reflected on the screen.**

Let’s see how you can use an Effect to synchronize with an external system. Consider a `<VideoPlayer>` React component. It would be nice to control whether it’s playing or paused by passing an `isPlaying` prop to it:

```
<VideoPlayer isPlaying={isPlaying} />;
```

Your custom `VideoPlayer` component renders the built-in browser [`<video>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video) tag:

```
function VideoPlayer({ src, isPlaying }) {

  // TODO: do something with isPlaying

  return <video src={src} />;

}
```

However, the browser `<video>` tag does not have an `isPlaying` prop. The only way to control it is to manually call the [`play()`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/play) and [`pause()`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/pause) methods on the DOM element. **You need to synchronize the value of `isPlaying` prop, which tells whether the video *should* currently be playing, with calls like `play()` and `pause()`.**

We’ll need to first [get a ref](/learn/manipulating-the-dom-with-refs) to the `<video>` DOM node.

You might be tempted to try to call `play()` or `pause()` during rendering, but that isn’t correct:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useRef, useEffect } from 'react';

function VideoPlayer({ src, isPlaying }) {
  const ref = useRef(null);

  if (isPlaying) {
    ref.current.play();  // Calling these while rendering isn't allowed.
  } else {
    ref.current.pause(); // Also, this crashes.
  }

  return <video ref={ref} src={src} loop playsInline />;
}

export default function App() {
  const [isPlaying, setIsPlaying] = useState(false);
  return (
    <>
      <button onClick={() => setIsPlaying(!isPlaying)}>
        {isPlaying ? 'Pause' : 'Play'}
      </button>
      <VideoPlayer
        isPlaying={isPlaying}
        src="https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4"
      />
    </>
  );
}
```

The reason this code isn’t correct is that it tries to do something with the DOM node during rendering. In React, [rendering should be a pure calculation](/learn/keeping-components-pure) of JSX and should not contain side effects like modifying the DOM.

Moreover, when `VideoPlayer` is called for the first time, its DOM does not exist yet! There isn’t a DOM node yet to call `play()` or `pause()` on, because React doesn’t know what DOM to create until you return the JSX.

The solution here is to **wrap the side effect with `useEffect` to move it out of the rendering calculation:**

```
import { useEffect, useRef } from 'react';



function VideoPlayer({ src, isPlaying }) {

  const ref = useRef(null);



  useEffect(() => {

    if (isPlaying) {

      ref.current.play();

    } else {

      ref.current.pause();

    }

  });



  return <video ref={ref} src={src} loop playsInline />;

}
```

By wrapping the DOM update in an Effect, you let React update the screen first. Then your Effect runs.

When your `VideoPlayer` component renders (either the first time or if it re-renders), a few things will happen. First, React will update the screen, ensuring the `<video>` tag is in the DOM with the right props. Then React will run your Effect. Finally, your Effect will call `play()` or `pause()` depending on the value of `isPlaying`.

Press Play/Pause multiple times and see how the video player stays synchronized to the `isPlaying` value:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useRef, useEffect } from 'react';

function VideoPlayer({ src, isPlaying }) {
  const ref = useRef(null);

  useEffect(() => {
    if (isPlaying) {
      ref.current.play();
    } else {
      ref.current.pause();
    }
  });

  return <video ref={ref} src={src} loop playsInline />;
}

export default function App() {
  const [isPlaying, setIsPlaying] = useState(false);
  return (
    <>
      <button onClick={() => setIsPlaying(!isPlaying)}>
        {isPlaying ? 'Pause' : 'Play'}
      </button>
      <VideoPlayer
        isPlaying={isPlaying}
        src="https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4"
      />
    </>
  );
}
```

In this example, the “external system” you synchronized to React state was the browser media API. You can use a similar approach to wrap legacy non-React code (like jQuery plugins) into declarative React components.

Note that controlling a video player is much more complex in practice. Calling `play()` may fail, the user might play or pause using the built-in browser controls, and so on. This example is very simplified and incomplete.

### Pitfall

By default, Effects run after *every* render. This is why code like this will **produce an infinite loop:**

```
const [count, setCount] = useState(0);

useEffect(() => {

  setCount(count + 1);

});
```

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useRef, useEffect } from 'react';

function VideoPlayer({ src, isPlaying }) {
  const ref = useRef(null);

  useEffect(() => {
    if (isPlaying) {
      console.log('Calling video.play()');
      ref.current.play();
    } else {
      console.log('Calling video.pause()');
      ref.current.pause();
    }
  });

  return <video ref={ref} src={src} loop playsInline />;
}

export default function App() {
  const [isPlaying, setIsPlaying] = useState(false);
  const [text, setText] = useState('');
  return (
    <>
      <input value={text} onChange={e => setText(e.target.value)} />
      <button onClick={() => setIsPlaying(!isPlaying)}>
        {isPlaying ? 'Pause' : 'Play'}
      </button>
      <VideoPlayer
        isPlaying={isPlaying}
        src="https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4"
      />
    </>
  );
}
```

You can tell React to **skip unnecessarily re-running the Effect** by specifying an array of *dependencies* as the second argument to the `useEffect` call. Start by adding an empty `[]` array to the above example on line 14:

```
  useEffect(() => {

    // ...

  }, []);
```

You should see an error saying `React Hook useEffect has a missing dependency: 'isPlaying'`:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useRef, useEffect } from 'react';

function VideoPlayer({ src, isPlaying }) {
  const ref = useRef(null);

  useEffect(() => {
    if (isPlaying) {
      console.log('Calling video.play()');
      ref.current.play();
    } else {
      console.log('Calling video.pause()');
      ref.current.pause();
    }
  }, []); // This causes an error

  return <video ref={ref} src={src} loop playsInline />;
}

export default function App() {
  const [isPlaying, setIsPlaying] = useState(false);
  const [text, setText] = useState('');
  return (
    <>
      <input value={text} onChange={e => setText(e.target.value)} />
      <button onClick={() => setIsPlaying(!isPlaying)}>
        {isPlaying ? 'Pause' : 'Play'}
      </button>
      <VideoPlayer
        isPlaying={isPlaying}
        src="https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4"
      />
    </>
  );
}
```

The problem is that the code inside of your Effect *depends on* the `isPlaying` prop to decide what to do, but this dependency was not explicitly declared. To fix this issue, add `isPlaying` to the dependency array:

```
  useEffect(() => {

    if (isPlaying) { // It's used here...

      // ...

    } else {

      // ...

    }

  }, [isPlaying]); // ...so it must be declared here!
```

Now all dependencies are declared, so there is no error. Specifying `[isPlaying]` as the dependency array tells React that it should skip re-running your Effect if `isPlaying` is the same as it was during the previous render. With this change, typing into the input doesn’t cause the Effect to re-run, but pressing Play/Pause does:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useRef, useEffect } from 'react';

function VideoPlayer({ src, isPlaying }) {
  const ref = useRef(null);

  useEffect(() => {
    if (isPlaying) {
      console.log('Calling video.play()');
      ref.current.play();
    } else {
      console.log('Calling video.pause()');
      ref.current.pause();
    }
  }, [isPlaying]);

  return <video ref={ref} src={src} loop playsInline />;
}

export default function App() {
  const [isPlaying, setIsPlaying] = useState(false);
  const [text, setText] = useState('');
  return (
    <>
      <input value={text} onChange={e => setText(e.target.value)} />
      <button onClick={() => setIsPlaying(!isPlaying)}>
        {isPlaying ? 'Pause' : 'Play'}
      </button>
      <VideoPlayer
        isPlaying={isPlaying}
        src="https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4"
      />
    </>
  );
}
```

The dependency array can contain multiple dependencies. React will only skip re-running the Effect if *all* of the dependencies you specify have exactly the same values as they had during the previous render. React compares the dependency values using the [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) comparison. See the [`useEffect` reference](/reference/react/useEffect#reference) for details.

**Notice that you can’t “choose” your dependencies.** You will get a lint error if the dependencies you specified don’t match what React expects based on the code inside your Effect. This helps catch many bugs in your code. If you don’t want some code to re-run, [*edit the Effect code itself* to not “need” that dependency.](/learn/lifecycle-of-reactive-effects#what-to-do-when-you-dont-want-to-re-synchronize)

### Pitfall

The behaviors without the dependency array and with an *empty* `[]` dependency array are different:

```
useEffect(() => {

  // This runs after every render

});



useEffect(() => {

  // This runs only on mount (when the component appears)

}, []);



useEffect(() => {

  // This runs on mount *and also* if either a or b have changed since the last render

}, [a, b]);
```

We’ll take a close look at what “mount” means in the next step.

##### Deep Dive#### Why was the ref omitted from the dependency array?[](#why-was-the-ref-omitted-from-the-dependency-array "Link for Why was the ref omitted from the dependency array? ")

This Effect uses *both* `ref` and `isPlaying`, but only `isPlaying` is declared as a dependency:

```
function VideoPlayer({ src, isPlaying }) {

  const ref = useRef(null);

  useEffect(() => {

    if (isPlaying) {

      ref.current.play();

    } else {

      ref.current.pause();

    }

  }, [isPlaying]);
```

This is because the `ref` object has a *stable identity:* React guarantees [you’ll always get the same object](/reference/react/useRef#returns) from the same `useRef` call on every render. It never changes, so it will never by itself cause the Effect to re-run. Therefore, it does not matter whether you include it or not. Including it is fine too:

```
function VideoPlayer({ src, isPlaying }) {

  const ref = useRef(null);

  useEffect(() => {

    if (isPlaying) {

      ref.current.play();

    } else {

      ref.current.pause();

    }

  }, [isPlaying, ref]);
```

The [`set` functions](/reference/react/useState#setstate) returned by `useState` also have stable identity, so you will often see them omitted from the dependencies too. If the linter lets you omit a dependency without errors, it is safe to do.

Omitting always-stable dependencies only works when the linter can “see” that the object is stable. For example, if `ref` was passed from a parent component, you would have to specify it in the dependency array. However, this is good because you can’t know whether the parent component always passes the same ref, or passes one of several refs conditionally. So your Effect *would* depend on which ref is passed.

### Step 3: Add cleanup if needed[](#step-3-add-cleanup-if-needed "Link for Step 3: Add cleanup if needed ")

Consider a different example. You’re writing a `ChatRoom` component that needs to connect to the chat server when it appears. You are given a `createConnection()` API that returns an object with `connect()` and `disconnect()` methods. How do you keep the component connected while it is displayed to the user?

Start by writing the Effect logic:

```
useEffect(() => {

  const connection = createConnection();

  connection.connect();

});
```

It would be slow to connect to the chat after every re-render, so you add the dependency array:

```
useEffect(() => {

  const connection = createConnection();

  connection.connect();

}, []);
```

**The code inside the Effect does not use any props or state, so your dependency array is `[]` (empty). This tells React to only run this code when the component “mounts”, i.e. appears on the screen for the first time.**

Let’s try running this code:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useEffect } from 'react';
import { createConnection } from './chat.js';

export default function ChatRoom() {
  useEffect(() => {
    const connection = createConnection();
    connection.connect();
  }, []);
  return <h1>Welcome to the chat!</h1>;
}
```

This Effect only runs on mount, so you might expect `"✅ Connecting..."` to be printed once in the console. **However, if you check the console, `"✅ Connecting..."` gets printed twice. Why does it happen?**

Imagine the `ChatRoom` component is a part of a larger app with many different screens. The user starts their journey on the `ChatRoom` page. The component mounts and calls `connection.connect()`. Then imagine the user navigates to another screen—for example, to the Settings page. The `ChatRoom` component unmounts. Finally, the user clicks Back and `ChatRoom` mounts again. This would set up a second connection—but the first connection was never destroyed! As the user navigates across the app, the connections would keep piling up.

Bugs like this are easy to miss without extensive manual testing. To help you spot them quickly, in development React remounts every component once immediately after its initial mount.

Seeing the `"✅ Connecting..."` log twice helps you notice the real issue: your code doesn’t close the connection when the component unmounts.

To fix the issue, return a *cleanup function* from your Effect:

```
  useEffect(() => {

    const connection = createConnection();

    connection.connect();

    return () => {

      connection.disconnect();

    };

  }, []);
```

React will call your cleanup function each time before the Effect runs again, and one final time when the component unmounts (gets removed). Let’s see what happens when the cleanup function is implemented:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useEffect } from 'react';
import { createConnection } from './chat.js';

export default function ChatRoom() {
  useEffect(() => {
    const connection = createConnection();
    connection.connect();
    return () => connection.disconnect();
  }, []);
  return <h1>Welcome to the chat!</h1>;
}
```

```
  const connectionRef = useRef(null);

  useEffect(() => {

    // 🚩 This wont fix the bug!!!

    if (!connectionRef.current) {

      connectionRef.current = createConnection();

      connectionRef.current.connect();

    }

  }, []);
```

This makes it so you only see `"✅ Connecting..."` once in development, but it doesn’t fix the bug.

When the user navigates away, the connection still isn’t closed and when they navigate back, a new connection is created. As the user navigates across the app, the connections would keep piling up, the same as it would before the “fix”.

To fix the bug, it is not enough to just make the Effect run once. The effect needs to work after re-mounting, which means the connection needs to be cleaned up like in the solution above.

See the examples below for how to handle common patterns.

### Controlling non-React widgets[](#controlling-non-react-widgets "Link for Controlling non-React widgets ")

Sometimes you need to add UI widgets that aren’t written in React. For example, let’s say you’re adding a map component to your page. It has a `setZoomLevel()` method, and you’d like to keep the zoom level in sync with a `zoomLevel` state variable in your React code. Your Effect would look similar to this:

```
useEffect(() => {

  const map = mapRef.current;

  map.setZoomLevel(zoomLevel);

}, [zoomLevel]);
```

Note that there is no cleanup needed in this case. In development, React will call the Effect twice, but this is not a problem because calling `setZoomLevel` twice with the same value does not do anything. It may be slightly slower, but this doesn’t matter because it won’t remount needlessly in production.

Some APIs may not allow you to call them twice in a row. For example, the [`showModal`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLDialogElement/showModal) method of the built-in [`<dialog>`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLDialogElement) element throws if you call it twice. Implement the cleanup function and make it close the dialog:

```
useEffect(() => {

  const dialog = dialogRef.current;

  dialog.showModal();

  return () => dialog.close();

}, []);
```

In development, your Effect will call `showModal()`, then immediately `close()`, and then `showModal()` again. This has the same user-visible behavior as calling `showModal()` once, as you would see in production.

### Subscribing to events[](#subscribing-to-events "Link for Subscribing to events ")

If your Effect subscribes to something, the cleanup function should unsubscribe:

```
useEffect(() => {

  function handleScroll(e) {

    console.log(window.scrollX, window.scrollY);

  }

  window.addEventListener('scroll', handleScroll);

  return () => window.removeEventListener('scroll', handleScroll);

}, []);
```

In development, your Effect will call `addEventListener()`, then immediately `removeEventListener()`, and then `addEventListener()` again with the same handler. So there would be only one active subscription at a time. This has the same user-visible behavior as calling `addEventListener()` once, as in production.

### Triggering animations[](#triggering-animations "Link for Triggering animations ")

If your Effect animates something in, the cleanup function should reset the animation to the initial values:

```
useEffect(() => {

  const node = ref.current;

  node.style.opacity = 1; // Trigger the animation

  return () => {

    node.style.opacity = 0; // Reset to the initial value

  };

}, []);
```

In development, opacity will be set to `1`, then to `0`, and then to `1` again. This should have the same user-visible behavior as setting it to `1` directly, which is what would happen in production. If you use a third-party animation library with support for tweening, your cleanup function should reset the timeline to its initial state.

### Fetching data[](#fetching-data "Link for Fetching data ")

If your Effect fetches something, the cleanup function should either [abort the fetch](https://developer.mozilla.org/en-US/docs/Web/API/AbortController) or ignore its result:

```
useEffect(() => {

  let ignore = false;



  async function startFetching() {

    const json = await fetchTodos(userId);

    if (!ignore) {

      setTodos(json);

    }

  }



  startFetching();



  return () => {

    ignore = true;

  };

}, [userId]);
```

You can’t “undo” a network request that already happened, but your cleanup function should ensure that the fetch that’s *not relevant anymore* does not keep affecting your application. If the `userId` changes from `'Alice'` to `'Bob'`, cleanup ensures that the `'Alice'` response is ignored even if it arrives after `'Bob'`.

**In development, you will see two fetches in the Network tab.** There is nothing wrong with that. With the approach above, the first Effect will immediately get cleaned up so its copy of the `ignore` variable will be set to `true`. So even though there is an extra request, it won’t affect the state thanks to the `if (!ignore)` check.

**In production, there will only be one request.** If the second request in development is bothering you, the best approach is to use a solution that deduplicates requests and caches their responses between components:

```
function TodoList() {

  const todos = useSomeDataLibrary(`/api/user/${userId}/todos`);

  // ...
```

* **If you use a [framework](/learn/creating-a-react-app#full-stack-frameworks), use its built-in data fetching mechanism.** Modern React frameworks have integrated data fetching mechanisms that are efficient and don’t suffer from the above pitfalls.
* **Otherwise, consider using or building a client-side cache.** Popular open source solutions include [TanStack Query](https://tanstack.com/query/latest), [useSWR](https://swr.vercel.app/), and [React Router 6.4+.](https://beta.reactrouter.com/en/main/start/overview) You can build your own solution too, in which case you would use Effects under the hood, but add logic for deduplicating requests, caching responses, and avoiding network waterfalls (by preloading data or hoisting data requirements to routes).

You can continue fetching data directly in Effects if neither of these approaches suit you.

### Sending analytics[](#sending-analytics "Link for Sending analytics ")

Consider this code that sends an analytics event on the page visit:

```
useEffect(() => {

  logVisit(url); // Sends a POST request

}, [url]);
```

In development, `logVisit` will be called twice for every URL, so you might be tempted to try to fix that. **We recommend keeping this code as is.** Like with earlier examples, there is no *user-visible* behavior difference between running it once and running it twice. From a practical point of view, `logVisit` should not do anything in development because you don’t want the logs from the development machines to skew the production metrics. Your component remounts every time you save its file, so it logs extra visits in development anyway.

**In production, there will be no duplicate visit logs.**

To debug the analytics events you’re sending, you can deploy your app to a staging environment (which runs in production mode) or temporarily opt out of [Strict Mode](/reference/react/StrictMode) and its development-only remounting checks. You may also send analytics from the route change event handlers instead of Effects. For more precise analytics, [intersection observers](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API) can help track which components are in the viewport and how long they remain visible.

### Not an Effect: Initializing the application[](#not-an-effect-initializing-the-application "Link for Not an Effect: Initializing the application ")

Some logic should only run once when the application starts. You can put it outside your components:

```
if (typeof window !== 'undefined') { // Check if we're running in the browser.

  checkAuthToken();

  loadDataFromLocalStorage();

}



function App() {

  // ...

}
```

This guarantees that such logic only runs once after the browser loads the page.

### Not an Effect: Buying a product[](#not-an-effect-buying-a-product "Link for Not an Effect: Buying a product ")

Sometimes, even if you write a cleanup function, there’s no way to prevent user-visible consequences of running the Effect twice. For example, maybe your Effect sends a POST request like buying a product:

```
useEffect(() => {

  // 🔴 Wrong: This Effect fires twice in development, exposing a problem in the code.

  fetch('/api/buy', { method: 'POST' });

}, []);
```

You wouldn’t want to buy the product twice. However, this is also why you shouldn’t put this logic in an Effect. What if the user goes to another page and then presses Back? Your Effect would run again. You don’t want to buy the product when the user *visits* a page; you want to buy it when the user *clicks* the Buy button.

Buying is not caused by rendering; it’s caused by a specific interaction. It should run only when the user presses the button. **Delete the Effect and move your `/api/buy` request into the Buy button event handler:**

```
  function handleClick() {

    // ✅ Buying is an event because it is caused by a particular interaction.

    fetch('/api/buy', { method: 'POST' });

  }
```

**This illustrates that if remounting breaks the logic of your application, this usually uncovers existing bugs.** From a user’s perspective, visiting a page shouldn’t be different from visiting it, clicking a link, then pressing Back to view the page again. React verifies that your components abide by this principle by remounting them once in development.

## Putting it all together[](#putting-it-all-together "Link for Putting it all together ")

This playground can help you “get a feel” for how Effects work in practice.

This example uses [`setTimeout`](https://developer.mozilla.org/en-US/docs/Web/API/setTimeout) to schedule a console log with the input text to appear three seconds after the Effect runs. The cleanup function cancels the pending timeout. Start by pressing “Mount the component”:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useEffect } from 'react';

function Playground() {
  const [text, setText] = useState('a');

  useEffect(() => {
    function onTimeout() {
      console.log('⏰ ' + text);
    }

    console.log('🔵 Schedule "' + text + '" log');
    const timeoutId = setTimeout(onTimeout, 3000);

    return () => {
      console.log('🟡 Cancel "' + text + '" log');
      clearTimeout(timeoutId);
    };
  }, [text]);

  return (
    <>
      <label>
        What to log:{' '}
        <input
          value={text}
          onChange={e => setText(e.target.value)}
        />
      </label>
      <h1>{text}</h1>
    </>
  );
}

export default function App() {
  const [show, setShow] = useState(false);
  return (
    <>
      <button onClick={() => setShow(!show)}>
        {show ? 'Unmount' : 'Mount'} the component
      </button>
      {show && <hr />}
      {show && <Playground />}
    </>
  );
}
```

```
export default function ChatRoom({ roomId }) {

  useEffect(() => {

    const connection = createConnection(roomId);

    connection.connect();

    return () => connection.disconnect();

  }, [roomId]);



  return <h1>Welcome to {roomId}!</h1>;

}
```

Let’s see what exactly happens as the user navigates around the app.

#### Initial render[](#initial-render "Link for Initial render ")

The user visits `<ChatRoom roomId="general" />`. Let’s [mentally substitute](/learn/state-as-a-snapshot#rendering-takes-a-snapshot-in-time) `roomId` with `'general'`:

```
  // JSX for the first render (roomId = "general")

  return <h1>Welcome to general!</h1>;
```

**The Effect is *also* a part of the rendering output.** The first render’s Effect becomes:

```
  // Effect for the first render (roomId = "general")

  () => {

    const connection = createConnection('general');

    connection.connect();

    return () => connection.disconnect();

  },

  // Dependencies for the first render (roomId = "general")

  ['general']
```

React runs this Effect, which connects to the `'general'` chat room.

#### Re-render with same dependencies[](#re-render-with-same-dependencies "Link for Re-render with same dependencies ")

Let’s say `<ChatRoom roomId="general" />` re-renders. The JSX output is the same:

```
  // JSX for the second render (roomId = "general")

  return <h1>Welcome to general!</h1>;
```

React sees that the rendering output has not changed, so it doesn’t update the DOM.

The Effect from the second render looks like this:

```
  // Effect for the second render (roomId = "general")

  () => {

    const connection = createConnection('general');

    connection.connect();

    return () => connection.disconnect();

  },

  // Dependencies for the second render (roomId = "general")

  ['general']
```

React compares `['general']` from the second render with `['general']` from the first render. **Because all dependencies are the same, React *ignores* the Effect from the second render.** It never gets called.

#### Re-render with different dependencies[](#re-render-with-different-dependencies "Link for Re-render with different dependencies ")

Then, the user visits `<ChatRoom roomId="travel" />`. This time, the component returns different JSX:

```
  // JSX for the third render (roomId = "travel")

  return <h1>Welcome to travel!</h1>;
```

React updates the DOM to change `"Welcome to general"` into `"Welcome to travel"`.

The Effect from the third render looks like this:

```
  // Effect for the third render (roomId = "travel")

  () => {

    const connection = createConnection('travel');

    connection.connect();

    return () => connection.disconnect();

  },

  // Dependencies for the third render (roomId = "travel")

  ['travel']
```

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useEffect, useRef } from 'react';

export default function MyInput({ value, onChange }) {
  const ref = useRef(null);

  // TODO: This doesn't quite work. Fix it.
  // ref.current.focus()

  return (
    <input
      ref={ref}
      value={value}
      onChange={onChange}
    />
  );
}
```

To verify that your solution works, press “Show form” and verify that the input receives focus (becomes highlighted and the cursor is placed inside). Press “Hide form” and “Show form” again. Verify the input is highlighted again.

`MyInput` should only focus *on mount* rather than after every render. To verify that the behavior is right, press “Show form” and then repeatedly press the “Make it uppercase” checkbox. Clicking the checkbox should *not* focus the input above it.

[PreviousManipulating the DOM with Refs](/learn/manipulating-the-dom-with-refs)

[NextYou Might Not Need an Effect](/learn/you-might-not-need-an-effect)

***

----
url: https://18.react.dev/learn/reusing-logic-with-custom-hooks
----

import { useState, useEffect } from 'react';



export default function StatusBar() {

const \[isOnline, setIsOnline] = useState(true);

useEffect(() => {

function handleOnline() {

setIsOnline(true);

}

function handleOffline() {

setIsOnline(false);

}

window\.addEventListener('online', handleOnline);

window\.addEventListener('offline', handleOffline);

return () => {

window\.removeEventListener('online', handleOnline);

window\.removeEventListener('offline', handleOffline);

};

}, \[]);



return \<h1>{isOnline ? '✅ Online' : '❌ Disconnected'}\</h1>;

}



Try turning your network on and off, and notice how this `StatusBar` updates in response to your actions.

Now imagine you *also* want to use the same logic in a different component. You want to implement a Save button that will become disabled and show “Reconnecting…” instead of “Save” while the network is off.

To start, you can copy and paste the `isOnline` state and the Effect into `SaveButton`:

```
import { useState, useEffect } from 'react';

export default function SaveButton() {
  const [isOnline, setIsOnline] = useState(true);
  useEffect(() => {
    function handleOnline() {
      setIsOnline(true);
    }
    function handleOffline() {
      setIsOnline(false);
    }
    window.addEventListener('online', handleOnline);
    window.addEventListener('offline', handleOffline);
    return () => {
      window.removeEventListener('online', handleOnline);
      window.removeEventListener('offline', handleOffline);
    };
  }, []);

  function handleSaveClick() {
    console.log('✅ Progress saved');
  }

  return (
    <button disabled={!isOnline} onClick={handleSaveClick}>
      {isOnline ? 'Save progress' : 'Reconnecting...'}
    </button>
  );
}
```

Verify that, if you turn off the network, the button will change its appearance.

These two components work fine, but the duplication in logic between them is unfortunate. It seems like even though they have different *visual appearance,* you want to reuse the logic between them.

### Extracting your own custom Hook from a component[](#extracting-your-own-custom-hook-from-a-component "Link for Extracting your own custom Hook from a component ")

Imagine for a moment that, similar to [`useState`](/reference/react/useState) and [`useEffect`](/reference/react/useEffect), there was a built-in `useOnlineStatus` Hook. Then both of these components could be simplified and you could remove the duplication between them:

```
function StatusBar() {

  const isOnline = useOnlineStatus();

  return <h1>{isOnline ? '✅ Online' : '❌ Disconnected'}</h1>;

}



function SaveButton() {

  const isOnline = useOnlineStatus();



  function handleSaveClick() {

    console.log('✅ Progress saved');

  }



  return (

    <button disabled={!isOnline} onClick={handleSaveClick}>

      {isOnline ? 'Save progress' : 'Reconnecting...'}

    </button>

  );

}
```

Although there is no such built-in Hook, you can write it yourself. Declare a function called `useOnlineStatus` and move all the duplicated code into it from the components you wrote earlier:

```
function useOnlineStatus() {

  const [isOnline, setIsOnline] = useState(true);

  useEffect(() => {

    function handleOnline() {

      setIsOnline(true);

    }

    function handleOffline() {

      setIsOnline(false);

    }

    window.addEventListener('online', handleOnline);

    window.addEventListener('offline', handleOffline);

    return () => {

      window.removeEventListener('online', handleOnline);

      window.removeEventListener('offline', handleOffline);

    };

  }, []);

  return isOnline;

}
```

At the end of the function, return `isOnline`. This lets your components read that value:

```
import { useOnlineStatus } from './useOnlineStatus.js';

function StatusBar() {
  const isOnline = useOnlineStatus();
  return <h1>{isOnline ? '✅ Online' : '❌ Disconnected'}</h1>;
}

function SaveButton() {
  const isOnline = useOnlineStatus();

  function handleSaveClick() {
    console.log('✅ Progress saved');
  }

  return (
    <button disabled={!isOnline} onClick={handleSaveClick}>
      {isOnline ? 'Save progress' : 'Reconnecting...'}
    </button>
  );
}

export default function App() {
  return (
    <>
      <SaveButton />
      <StatusBar />
    </>
  );
}
```

```
// 🔴 Avoid: A Hook that doesn't use Hooks

function useSorted(items) {

  return items.slice().sort();

}



// ✅ Good: A regular function that doesn't use Hooks

function getSorted(items) {

  return items.slice().sort();

}
```

This ensures that your code can call this regular function anywhere, including conditions:

```
function List({ items, shouldSort }) {

  let displayedItems = items;

  if (shouldSort) {

    // ✅ It's ok to call getSorted() conditionally because it's not a Hook

    displayedItems = getSorted(items);

  }

  // ...

}
```

You should give `use` prefix to a function (and thus make it a Hook) if it uses at least one Hook inside of it:

```
// ✅ Good: A Hook that uses other Hooks

function useAuth() {

  return useContext(Auth);

}
```

Technically, this isn’t enforced by React. In principle, you could make a Hook that doesn’t call other Hooks. This is often confusing and limiting so it’s best to avoid that pattern. However, there may be rare cases where it is helpful. For example, maybe your function doesn’t use any Hooks right now, but you plan to add some Hook calls to it in the future. Then it makes sense to name it with the `use` prefix:

```
// ✅ Good: A Hook that will likely use some other Hooks later

function useAuth() {

  // TODO: Replace with this line when authentication is implemented:

  // return useContext(Auth);

  return TEST_USER;

}
```

Then components won’t be able to call it conditionally. This will become important when you actually add Hook calls inside. If you don’t plan to use Hooks inside it (now or later), don’t make it a Hook.

### Custom Hooks let you share stateful logic, not state itself[](#custom-hooks-let-you-share-stateful-logic-not-state-itself "Link for Custom Hooks let you share stateful logic, not state itself ")

In the earlier example, when you turned the network on and off, both components updated together. However, it’s wrong to think that a single `isOnline` state variable is shared between them. Look at this code:

```
function StatusBar() {

  const isOnline = useOnlineStatus();

  // ...

}



function SaveButton() {

  const isOnline = useOnlineStatus();

  // ...

}
```

It works the same way as before you extracted the duplication:

```
function StatusBar() {

  const [isOnline, setIsOnline] = useState(true);

  useEffect(() => {

    // ...

  }, []);

  // ...

}



function SaveButton() {

  const [isOnline, setIsOnline] = useState(true);

  useEffect(() => {

    // ...

  }, []);

  // ...

}
```

These are two completely independent state variables and Effects! They happened to have the same value at the same time because you synchronized them with the same external value (whether the network is on).

To better illustrate this, we’ll need a different example. Consider this `Form` component:

```
import { useState } from 'react';

export default function Form() {
  const [firstName, setFirstName] = useState('Mary');
  const [lastName, setLastName] = useState('Poppins');

  function handleFirstNameChange(e) {
    setFirstName(e.target.value);
  }

  function handleLastNameChange(e) {
    setLastName(e.target.value);
  }

  return (
    <>
      <label>
        First name:
        <input value={firstName} onChange={handleFirstNameChange} />
      </label>
      <label>
        Last name:
        <input value={lastName} onChange={handleLastNameChange} />
      </label>
      <p><b>Good morning, {firstName} {lastName}.</b></p>
    </>
  );
}
```

There’s some repetitive logic for each form field:

1. There’s a piece of state (`firstName` and `lastName`).
2. There’s a change handler (`handleFirstNameChange` and `handleLastNameChange`).
3. There’s a piece of JSX that specifies the `value` and `onChange` attributes for that input.

You can extract the repetitive logic into this `useFormInput` custom Hook:

```
import { useState } from 'react';

export function useFormInput(initialValue) {
  const [value, setValue] = useState(initialValue);

  function handleChange(e) {
    setValue(e.target.value);
  }

  const inputProps = {
    value: value,
    onChange: handleChange
  };

  return inputProps;
}
```

Notice that it only declares *one* state variable called `value`.

However, the `Form` component calls `useFormInput` *two times:*

```
function Form() {

  const firstNameProps = useFormInput('Mary');

  const lastNameProps = useFormInput('Poppins');

  // ...
```

This is why it works like declaring two separate state variables!

**Custom Hooks let you share *stateful logic* but not *state itself.* Each call to a Hook is completely independent from every other call to the same Hook.** This is why the two sandboxes above are completely equivalent. If you’d like, scroll back up and compare them. The behavior before and after extracting a custom Hook is identical.

When you need to share the state itself between multiple components, [lift it up and pass it down](/learn/sharing-state-between-components) instead.

## Passing reactive values between Hooks[](#passing-reactive-values-between-hooks "Link for Passing reactive values between Hooks ")

The code inside your custom Hooks will re-run during every re-render of your component. This is why, like components, custom Hooks [need to be pure.](/learn/keeping-components-pure) Think of custom Hooks’ code as part of your component’s body!

Because custom Hooks re-render together with your component, they always receive the latest props and state. To see what this means, consider this chat room example. Change the server URL or the chat room:

```
import { useState, useEffect } from 'react';
import { createConnection } from './chat.js';
import { showNotification } from './notifications.js';

export default function ChatRoom({ roomId }) {
  const [serverUrl, setServerUrl] = useState('https://localhost:1234');

  useEffect(() => {
    const options = {
      serverUrl: serverUrl,
      roomId: roomId
    };
    const connection = createConnection(options);
    connection.on('message', (msg) => {
      showNotification('New message: ' + msg);
    });
    connection.connect();
    return () => connection.disconnect();
  }, [roomId, serverUrl]);

  return (
    <>
      <label>
        Server URL:
        <input value={serverUrl} onChange={e => setServerUrl(e.target.value)} />
      </label>
      <h1>Welcome to the {roomId} room!</h1>
    </>
  );
}
```

When you change `serverUrl` or `roomId`, the Effect [“reacts” to your changes](/learn/lifecycle-of-reactive-effects#effects-react-to-reactive-values) and re-synchronizes. You can tell by the console messages that the chat re-connects every time that you change your Effect’s dependencies.

Now move the Effect’s code into a custom Hook:

```
export function useChatRoom({ serverUrl, roomId }) {

  useEffect(() => {

    const options = {

      serverUrl: serverUrl,

      roomId: roomId

    };

    const connection = createConnection(options);

    connection.connect();

    connection.on('message', (msg) => {

      showNotification('New message: ' + msg);

    });

    return () => connection.disconnect();

  }, [roomId, serverUrl]);

}
```

This lets your `ChatRoom` component call your custom Hook without worrying about how it works inside:

```
export default function ChatRoom({ roomId }) {

  const [serverUrl, setServerUrl] = useState('https://localhost:1234');



  useChatRoom({

    roomId: roomId,

    serverUrl: serverUrl

  });



  return (

    <>

      <label>

        Server URL:

        <input value={serverUrl} onChange={e => setServerUrl(e.target.value)} />

      </label>

      <h1>Welcome to the {roomId} room!</h1>

    </>

  );

}
```

This looks much simpler! (But it does the same thing.)

Notice that the logic *still responds* to prop and state changes. Try editing the server URL or the selected room:

```
import { useState } from 'react';
import { useChatRoom } from './useChatRoom.js';

export default function ChatRoom({ roomId }) {
  const [serverUrl, setServerUrl] = useState('https://localhost:1234');

  useChatRoom({
    roomId: roomId,
    serverUrl: serverUrl
  });

  return (
    <>
      <label>
        Server URL:
        <input value={serverUrl} onChange={e => setServerUrl(e.target.value)} />
      </label>
      <h1>Welcome to the {roomId} room!</h1>
    </>
  );
}
```

Notice how you’re taking the return value of one Hook:

```
export default function ChatRoom({ roomId }) {

  const [serverUrl, setServerUrl] = useState('https://localhost:1234');



  useChatRoom({

    roomId: roomId,

    serverUrl: serverUrl

  });

  // ...
```

and pass it as an input to another Hook:

```
export default function ChatRoom({ roomId }) {

  const [serverUrl, setServerUrl] = useState('https://localhost:1234');



  useChatRoom({

    roomId: roomId,

    serverUrl: serverUrl

  });

  // ...
```

Every time your `ChatRoom` component re-renders, it passes the latest `roomId` and `serverUrl` to your Hook. This is why your Effect re-connects to the chat whenever their values are different after a re-render. (If you ever worked with audio or video processing software, chaining Hooks like this might remind you of chaining visual or audio effects. It’s as if the output of `useState` “feeds into” the input of the `useChatRoom`.)

### Passing event handlers to custom Hooks[](#passing-event-handlers-to-custom-hooks "Link for Passing event handlers to custom Hooks ")

### Under Construction

This section describes an **experimental API that has not yet been released** in a stable version of React.

As you start using `useChatRoom` in more components, you might want to let components customize its behavior. For example, currently, the logic for what to do when a message arrives is hardcoded inside the Hook:

```
export function useChatRoom({ serverUrl, roomId }) {

  useEffect(() => {

    const options = {

      serverUrl: serverUrl,

      roomId: roomId

    };

    const connection = createConnection(options);

    connection.connect();

    connection.on('message', (msg) => {

      showNotification('New message: ' + msg);

    });

    return () => connection.disconnect();

  }, [roomId, serverUrl]);

}
```

Let’s say you want to move this logic back to your component:

```
export default function ChatRoom({ roomId }) {

  const [serverUrl, setServerUrl] = useState('https://localhost:1234');



  useChatRoom({

    roomId: roomId,

    serverUrl: serverUrl,

    onReceiveMessage(msg) {

      showNotification('New message: ' + msg);

    }

  });

  // ...
```

To make this work, change your custom Hook to take `onReceiveMessage` as one of its named options:

```
export function useChatRoom({ serverUrl, roomId, onReceiveMessage }) {

  useEffect(() => {

    const options = {

      serverUrl: serverUrl,

      roomId: roomId

    };

    const connection = createConnection(options);

    connection.connect();

    connection.on('message', (msg) => {

      onReceiveMessage(msg);

    });

    return () => connection.disconnect();

  }, [roomId, serverUrl, onReceiveMessage]); // ✅ All dependencies declared

}
```

This will work, but there’s one more improvement you can do when your custom Hook accepts event handlers.

Adding a dependency on `onReceiveMessage` is not ideal because it will cause the chat to re-connect every time the component re-renders. [Wrap this event handler into an Effect Event to remove it from the dependencies:](/learn/removing-effect-dependencies#wrapping-an-event-handler-from-the-props)

```
import { useEffect, useEffectEvent } from 'react';

// ...



export function useChatRoom({ serverUrl, roomId, onReceiveMessage }) {

  const onMessage = useEffectEvent(onReceiveMessage);



  useEffect(() => {

    const options = {

      serverUrl: serverUrl,

      roomId: roomId

    };

    const connection = createConnection(options);

    connection.connect();

    connection.on('message', (msg) => {

      onMessage(msg);

    });

    return () => connection.disconnect();

  }, [roomId, serverUrl]); // ✅ All dependencies declared

}
```

Now the chat won’t re-connect every time that the `ChatRoom` component re-renders. Here is a fully working demo of passing an event handler to a custom Hook that you can play with:

```
import { useState } from 'react';
import { useChatRoom } from './useChatRoom.js';
import { showNotification } from './notifications.js';

export default function ChatRoom({ roomId }) {
  const [serverUrl, setServerUrl] = useState('https://localhost:1234');

  useChatRoom({
    roomId: roomId,
    serverUrl: serverUrl,
    onReceiveMessage(msg) {
      showNotification('New message: ' + msg);
    }
  });

  return (
    <>
      <label>
        Server URL:
        <input value={serverUrl} onChange={e => setServerUrl(e.target.value)} />
      </label>
      <h1>Welcome to the {roomId} room!</h1>
    </>
  );
}
```

Notice how you no longer need to know *how* `useChatRoom` works in order to use it. You could add it to any other component, pass any other options, and it would work the same way. That’s the power of custom Hooks.

## When to use custom Hooks[](#when-to-use-custom-hooks "Link for When to use custom Hooks ")

You don’t need to extract a custom Hook for every little duplicated bit of code. Some duplication is fine. For example, extracting a `useFormInput` Hook to wrap a single `useState` call like earlier is probably unnecessary.

However, whenever you write an Effect, consider whether it would be clearer to also wrap it in a custom Hook. [You shouldn’t need Effects very often,](/learn/you-might-not-need-an-effect) so if you’re writing one, it means that you need to “step outside React” to synchronize with some external system or to do something that React doesn’t have a built-in API for. Wrapping it into a custom Hook lets you precisely communicate your intent and how the data flows through it.

For example, consider a `ShippingForm` component that displays two dropdowns: one shows the list of cities, and another shows the list of areas in the selected city. You might start with some code that looks like this:

```
function ShippingForm({ country }) {

  const [cities, setCities] = useState(null);

  // This Effect fetches cities for a country

  useEffect(() => {

    let ignore = false;

    fetch(`/api/cities?country=${country}`)

      .then(response => response.json())

      .then(json => {

        if (!ignore) {

          setCities(json);

        }

      });

    return () => {

      ignore = true;

    };

  }, [country]);



  const [city, setCity] = useState(null);

  const [areas, setAreas] = useState(null);

  // This Effect fetches areas for the selected city

  useEffect(() => {

    if (city) {

      let ignore = false;

      fetch(`/api/areas?city=${city}`)

        .then(response => response.json())

        .then(json => {

          if (!ignore) {

            setAreas(json);

          }

        });

      return () => {

        ignore = true;

      };

    }

  }, [city]);



  // ...
```

Although this code is quite repetitive, [it’s correct to keep these Effects separate from each other.](/learn/removing-effect-dependencies#is-your-effect-doing-several-unrelated-things) They synchronize two different things, so you shouldn’t merge them into one Effect. Instead, you can simplify the `ShippingForm` component above by extracting the common logic between them into your own `useData` Hook:

```
function useData(url) {

  const [data, setData] = useState(null);

  useEffect(() => {

    if (url) {

      let ignore = false;

      fetch(url)

        .then(response => response.json())

        .then(json => {

          if (!ignore) {

            setData(json);

          }

        });

      return () => {

        ignore = true;

      };

    }

  }, [url]);

  return data;

}
```

Now you can replace both Effects in the `ShippingForm` components with calls to `useData`:

```
function ShippingForm({ country }) {

  const cities = useData(`/api/cities?country=${country}`);

  const [city, setCity] = useState(null);

  const areas = useData(city ? `/api/areas?city=${city}` : null);

  // ...
```

```
function ChatRoom({ roomId }) {

  const [serverUrl, setServerUrl] = useState('https://localhost:1234');



  // 🔴 Avoid: using custom "lifecycle" Hooks

  useMount(() => {

    const connection = createConnection({ roomId, serverUrl });

    connection.connect();



    post('/analytics/event', { eventName: 'visit_chat' });

  });

  // ...

}



// 🔴 Avoid: creating custom "lifecycle" Hooks

function useMount(fn) {

  useEffect(() => {

    fn();

  }, []); // 🔴 React Hook useEffect has a missing dependency: 'fn'

}
```

**Custom “lifecycle” Hooks like `useMount` don’t fit well into the React paradigm.** For example, this code example has a mistake (it doesn’t “react” to `roomId` or `serverUrl` changes), but the linter won’t warn you about it because the linter only checks direct `useEffect` calls. It won’t know about your Hook.

If you’re writing an Effect, start by using the React API directly:

```
function ChatRoom({ roomId }) {

  const [serverUrl, setServerUrl] = useState('https://localhost:1234');



  // ✅ Good: two raw Effects separated by purpose



  useEffect(() => {

    const connection = createConnection({ serverUrl, roomId });

    connection.connect();

    return () => connection.disconnect();

  }, [serverUrl, roomId]);



  useEffect(() => {

    post('/analytics/event', { eventName: 'visit_chat', roomId });

  }, [roomId]);



  // ...

}
```

Then, you can (but don’t have to) extract custom Hooks for different high-level use cases:

```
function ChatRoom({ roomId }) {

  const [serverUrl, setServerUrl] = useState('https://localhost:1234');



  // ✅ Great: custom Hooks named after their purpose

  useChatRoom({ serverUrl, roomId });

  useImpressionLog('visit_chat', { roomId });

  // ...

}
```

**A good custom Hook makes the calling code more declarative by constraining what it does.** For example, `useChatRoom(options)` can only connect to the chat room, while `useImpressionLog(eventName, extraData)` can only send an impression log to the analytics. If your custom Hook API doesn’t constrain the use cases and is very abstract, in the long run it’s likely to introduce more problems than it solves.

### Custom Hooks help you migrate to better patterns[](#custom-hooks-help-you-migrate-to-better-patterns "Link for Custom Hooks help you migrate to better patterns ")

Effects are an [“escape hatch”](/learn/escape-hatches): you use them when you need to “step outside React” and when there is no better built-in solution for your use case. With time, the React team’s goal is to reduce the number of the Effects in your app to the minimum by providing more specific solutions to more specific problems. Wrapping your Effects in custom Hooks makes it easier to upgrade your code when these solutions become available.

Let’s return to this example:

```
import { useState, useEffect } from 'react';

export function useOnlineStatus() {
  const [isOnline, setIsOnline] = useState(true);
  useEffect(() => {
    function handleOnline() {
      setIsOnline(true);
    }
    function handleOffline() {
      setIsOnline(false);
    }
    window.addEventListener('online', handleOnline);
    window.addEventListener('offline', handleOffline);
    return () => {
      window.removeEventListener('online', handleOnline);
      window.removeEventListener('offline', handleOffline);
    };
  }, []);
  return isOnline;
}
```

In the above example, `useOnlineStatus` is implemented with a pair of [`useState`](/reference/react/useState) and [`useEffect`.](/reference/react/useEffect) However, this isn’t the best possible solution. There is a number of edge cases it doesn’t consider. For example, it assumes that when the component mounts, `isOnline` is already `true`, but this may be wrong if the network already went offline. You can use the browser [`navigator.onLine`](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/onLine) API to check for that, but using it directly would not work on the server for generating the initial HTML. In short, this code could be improved.

Luckily, React 18 includes a dedicated API called [`useSyncExternalStore`](/reference/react/useSyncExternalStore) which takes care of all of these problems for you. Here is how your `useOnlineStatus` Hook, rewritten to take advantage of this new API:

```
import { useSyncExternalStore } from 'react';

function subscribe(callback) {
  window.addEventListener('online', callback);
  window.addEventListener('offline', callback);
  return () => {
    window.removeEventListener('online', callback);
    window.removeEventListener('offline', callback);
  };
}

export function useOnlineStatus() {
  return useSyncExternalStore(
    subscribe,
    () => navigator.onLine, // How to get the value on the client
    () => true // How to get the value on the server
  );
}
```

Notice how **you didn’t need to change any of the components** to make this migration:

```
function StatusBar() {

  const isOnline = useOnlineStatus();

  // ...

}



function SaveButton() {

  const isOnline = useOnlineStatus();

  // ...

}
```

This is another reason for why wrapping Effects in custom Hooks is often beneficial:

1. You make the data flow to and from your Effects very explicit.
2. You let your components focus on the intent rather than on the exact implementation of your Effects.
3. When React adds new features, you can remove those Effects without changing any of your components.

Similar to a [design system,](https://uxdesign.cc/everything-you-need-to-know-about-design-systems-54b109851969) you might find it helpful to start extracting common idioms from your app’s components into custom Hooks. This will keep your components’ code focused on the intent, and let you avoid writing raw Effects very often. Many excellent custom Hooks are maintained by the React community.

##### Deep Dive#### Will React provide any built-in solution for data fetching?[](#will-react-provide-any-built-in-solution-for-data-fetching "Link for Will React provide any built-in solution for data fetching? ")

We’re still working out the details, but we expect that in the future, you’ll write data fetching like this:

```
import { use } from 'react'; // Not available yet!



function ShippingForm({ country }) {

  const cities = use(fetch(`/api/cities?country=${country}`));

  const [city, setCity] = useState(null);

  const areas = city ? use(fetch(`/api/areas?city=${city}`)) : null;

  // ...
```

If you use custom Hooks like `useData` above in your app, it will require fewer changes to migrate to the eventually recommended approach than if you write raw Effects in every component manually. However, the old approach will still work fine, so if you feel happy writing raw Effects, you can continue to do that.

### There is more than one way to do it[](#there-is-more-than-one-way-to-do-it "Link for There is more than one way to do it ")

Let’s say you want to implement a fade-in animation *from scratch* using the browser [`requestAnimationFrame`](https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame) API. You might start with an Effect that sets up an animation loop. During each frame of the animation, you could change the opacity of the DOM node you [hold in a ref](/learn/manipulating-the-dom-with-refs) until it reaches `1`. Your code might start like this:

```
import { useState, useEffect, useRef } from 'react';

function Welcome() {
  const ref = useRef(null);

  useEffect(() => {
    const duration = 1000;
    const node = ref.current;

    let startTime = performance.now();
    let frameId = null;

    function onFrame(now) {
      const timePassed = now - startTime;
      const progress = Math.min(timePassed / duration, 1);
      onProgress(progress);
      if (progress < 1) {
        // We still have more frames to paint
        frameId = requestAnimationFrame(onFrame);
      }
    }

    function onProgress(progress) {
      node.style.opacity = progress;
    }

    function start() {
      onProgress(0);
      startTime = performance.now();
      frameId = requestAnimationFrame(onFrame);
    }

    function stop() {
      cancelAnimationFrame(frameId);
      startTime = null;
      frameId = null;
    }

    start();
    return () => stop();
  }, []);

  return (
    <h1 className="welcome" ref={ref}>
      Welcome
    </h1>
  );
}

export default function App() {
  const [show, setShow] = useState(false);
  return (
    <>
      <button onClick={() => setShow(!show)}>
        {show ? 'Remove' : 'Show'}
      </button>
      <hr />
      {show && <Welcome />}
    </>
  );
}
```

To make the component more readable, you might extract the logic into a `useFadeIn` custom Hook:

```
import { useState, useEffect, useRef } from 'react';
import { useFadeIn } from './useFadeIn.js';

function Welcome() {
  const ref = useRef(null);

  useFadeIn(ref, 1000);

  return (
    <h1 className="welcome" ref={ref}>
      Welcome
    </h1>
  );
}

export default function App() {
  const [show, setShow] = useState(false);
  return (
    <>
      <button onClick={() => setShow(!show)}>
        {show ? 'Remove' : 'Show'}
      </button>
      <hr />
      {show && <Welcome />}
    </>
  );
}
```

You could keep the `useFadeIn` code as is, but you could also refactor it more. For example, you could extract the logic for setting up the animation loop out of `useFadeIn` into a custom `useAnimationLoop` Hook:

```
import { useState, useEffect } from 'react';
import { experimental_useEffectEvent as useEffectEvent } from 'react';

export function useFadeIn(ref, duration) {
  const [isRunning, setIsRunning] = useState(true);

  useAnimationLoop(isRunning, (timePassed) => {
    const progress = Math.min(timePassed / duration, 1);
    ref.current.style.opacity = progress;
    if (progress === 1) {
      setIsRunning(false);
    }
  });
}

function useAnimationLoop(isRunning, drawFrame) {
  const onFrame = useEffectEvent(drawFrame);

  useEffect(() => {
    if (!isRunning) {
      return;
    }

    const startTime = performance.now();
    let frameId = null;

    function tick(now) {
      const timePassed = now - startTime;
      onFrame(timePassed);
      frameId = requestAnimationFrame(tick);
    }

    tick();
    return () => cancelAnimationFrame(frameId);
  }, [isRunning]);
}
```

However, you didn’t *have to* do that. As with regular functions, ultimately you decide where to draw the boundaries between different parts of your code. You could also take a very different approach. Instead of keeping the logic in the Effect, you could move most of the imperative logic inside a JavaScript [class:](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes)

```
import { useState, useEffect } from 'react';
import { FadeInAnimation } from './animation.js';

export function useFadeIn(ref, duration) {
  useEffect(() => {
    const animation = new FadeInAnimation(ref.current);
    animation.start(duration);
    return () => {
      animation.stop();
    };
  }, [ref, duration]);
}
```

Effects let you connect React to external systems. The more coordination between Effects is needed (for example, to chain multiple animations), the more it makes sense to extract that logic out of Effects and Hooks *completely* like in the sandbox above. Then, the code you extracted *becomes* the “external system”. This lets your Effects stay simple because they only need to send messages to the system you’ve moved outside React.

The examples above assume that the fade-in logic needs to be written in JavaScript. However, this particular fade-in animation is both simpler and much more efficient to implement with a plain [CSS Animation:](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Animations/Using_CSS_animations)

```
.welcome {
  color: white;
  padding: 50px;
  text-align: center;
  font-size: 50px;
  background-image: radial-gradient(circle, rgba(63,94,251,1) 0%, rgba(252,70,107,1) 100%);

  animation: fadeIn 1000ms;
}

@keyframes fadeIn {
  0% { opacity: 0; }
  100% { opacity: 1; }
}
```

```
export default function Counter() {

  const count = useCounter();

  return <h1>Seconds passed: {count}</h1>;

}
```

You’ll need to write your custom Hook in `useCounter.js` and import it into the `App.js` file.

```
import { useState, useEffect } from 'react';

export default function Counter() {
  const [count, setCount] = useState(0);
  useEffect(() => {
    const id = setInterval(() => {
      setCount(c => c + 1);
    }, 1000);
    return () => clearInterval(id);
  }, []);
  return <h1>Seconds passed: {count}</h1>;
}
```

[PreviousRemoving Effect Dependencies](/learn/removing-effect-dependencies)

***

----
url: https://legacy.reactjs.org/blog/2015/10/19/reactiflux-is-moving-to-discord.html
----

October 19, 2015 by [Paul Benigeri](https://github.com/benigeri)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

TL;DR: Slack decided that Reactiflux had too many members and disabled new invites. Reactiflux is moving to Discord. Join us: [http://join.reactiflux.com](http://join.reactiflux.com/)

## [](#what-happened-with-slack)What happened with Slack?

A few weeks ago, Reactiflux reached 7,500 members on Slack. Shortly after, Slack decided we were too big and disabled invites. There was no way for new users to join. Many of us were sad and upset. We loved Slack. Our community was built around it.

We reached out to Slack several times, but their decision was firm. Our large community caused performance issues. Slack wants to focus on building a great product for teams, not necessarily large open communities. Losing focus and building for too many use cases always leads to product bloat, and eventually a decrease in quality.

## [](#so-why-discord)So… why Discord?

After a [long and thorough debate](https://github.com/reactiflux/volunteers/issues/25), Discord quickly emerged as the most promising service. After just a few days, 400 members had joined the Discord server, and many already loved it.

### [](#easiest-to-join)Easiest to join

Discord is the easiest platform to join. New users can immediately join our conversations without having to create an account. All they need to do is provide a name. No permission granting, no password, no email confirmation.

This is critically useful for us, and will make Reactiflux even more open and accessible.

### [](#great-apps)Great apps

Out of all of the services we’ve tried, Discord’s apps are by far the most polished. They are well designed, easy to use, and surprisingly fast. In addition to the web app, they have mobile apps on both iOS and Android as well as desktop apps for OS X and Windows, with Linux support coming soon.

Their desktop apps are built with React and Electron, and their iOS app is built with React Native.

### [](#moderation-tools)Moderation tools

So far, we’ve been fortunate not to have to deal with spammers and trolls. As our community continues to grow, that might change. Unsurprisingly, Discord is the only app we’ve seen with legitimate moderation tools. It was built for gaming communities, after all.

### [](#great-multiple-server-support)Great multiple Server support

Your Discord account works with every Discord server, which is the equivalent of a Slack team. You don’t need to create a new account every time you join a new team. You can join new servers in one click, and it’s very easy to switch between them. Discord messages also work across servers, so your personal conversations are not scoped to a single server.

Instead of having one huge, crowded Reactiflux server, we can branch off closely related channels into sub-servers. Communities will start overlapping, and it will be easy to interact with non-Reactiflux channels.

### [](#its-hosted)It’s hosted

Self-hosted apps require maintenance. We’re all busy, and we can barely find the time to keep our landing page up to date and running smoothly. More than anything, we need a stable platform, and we don’t have the resources to guarantee that right now.

It’s a much safer bet to offload the hosting to Discord, who is already keeping the lights on for all their users.

### [](#we-like-the-team)We like the team

And they seem to like us back. They are excited for us to join them, and they’ve been very responsive to our feedback and suggestions.

They implemented code syntax highlighting just a few days after we told them we needed it.

Discord’s team has already built a solid suite of apps, and they have shown us how much they care about their users. We’re excited to see how they will continue to improve their product.

## [](#and-whats-the-catch)And what’s the catch?

Choosing the best chat service is subjective. There are a million reasons why Discord *might be* a terrible idea. Here are the ones that we’re most worried about:

### [](#difficult-channel-management)Difficult channel management

Channel management seems to be the biggest issue. There is no way to opt out of channels; you can only mute them. And you can only mute channels one by one. There is no way to star channels, and channels can only be sorted on the server level. Each user will see the list of channels in the same order.

As the number of channels grow, it will be challenging to keep things in order. Branching off sub-servers will help, and we will keep an easily accessible directory of channels across our main server and all of the sub-servers.

We can build simple tools to make channel lookup easier, and the Discord team is working on improvements that should make this more manageable.

### [](#no-search)No Search

Lack of search is clearly a bummer, but Discord is working on it. Search is coming!

### [](#firewall)Firewall

A couple of users aren’t able to access Discord at work since other corporate filters classify it as a gaming application. This sucks, but it seems to be a rare case. So far, it seems only to affect 0.6% of our current community (3/500).

We hope that these users can get Discord’s domains whitelisted, and we’ll try to find a solution if this is a widespread issue. The Discord team is aware of the issue as well.

## [](#is-discord-going-to-disappear-tomorrow)Is Discord going to disappear tomorrow?

Probably not tomorrow. They have 14 people [full time](https://discordapp.com/company), and they’ve raised money from some of the best investors in Silicon Valley, including [Benchmark](http://www.benchmark.com/) and [Accel](http://www.accel.com/companies/).

By focusing on gaming communities, Discord has differentiated itself from the many other communication apps. Discord is well received and has a rapidly growing user base. They plan to keep their basic offerings free for unlimited users and hope to make money with premium offerings (themes, add-ons, content, and more).

## [](#join-us)Join us!

More than 500 of us have already migrated to the new Reactiflux. Join us, we’re one click away: [http://join.reactiflux.com](http://join.reactiflux.com/)

*Note: Jordan Hawker’s thorough [research](http://jhawk.co/team-chat-comparison) made our decision a lot easier.*

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2015-10-19-reactiflux-is-moving-to-discord.md)

----
url: https://legacy.reactjs.org/docs/test-utils.html
----

**Importing**

```
import ReactTestUtils from 'react-dom/test-utils'; // ES6
var ReactTestUtils = require('react-dom/test-utils'); // ES5 with npm
```

## [](#overview)Overview

`ReactTestUtils` makes it easy to test React components in the testing framework of your choice. At Facebook we use [Jest](https://facebook.github.io/jest/) for painless JavaScript testing. Learn how to get started with Jest through the Jest website’s [React Tutorial](https://jestjs.io/docs/tutorial-react).

> Note:
>
> We recommend using [React Testing Library](https://testing-library.com/react) which is designed to enable and encourage writing tests that use your components as the end users do.
>
> For React versions <= 16, the [Enzyme](https://airbnb.io/enzyme/) library makes it easy to assert, manipulate, and traverse your React Components’ output.

* [`act()`](#act)
* [`mockComponent()`](#mockcomponent)
* [`isElement()`](#iselement)
* [`isElementOfType()`](#iselementoftype)
* [`isDOMComponent()`](#isdomcomponent)
* [`isCompositeComponent()`](#iscompositecomponent)
* [`isCompositeComponentWithType()`](#iscompositecomponentwithtype)
* [`findAllInRenderedTree()`](#findallinrenderedtree)
* [`scryRenderedDOMComponentsWithClass()`](#scryrendereddomcomponentswithclass)
* [`findRenderedDOMComponentWithClass()`](#findrendereddomcomponentwithclass)
* [`scryRenderedDOMComponentsWithTag()`](#scryrendereddomcomponentswithtag)
* [`findRenderedDOMComponentWithTag()`](#findrendereddomcomponentwithtag)
* [`scryRenderedComponentsWithType()`](#scryrenderedcomponentswithtype)
* [`findRenderedComponentWithType()`](#findrenderedcomponentwithtype)
* [`renderIntoDocument()`](#renderintodocument)
* [`Simulate`](#simulate)

## [](#reference)Reference

### [](#act)`act()`

To prepare a component for assertions, wrap the code rendering it and performing updates inside an `act()` call. This makes your test run closer to how React works in the browser.

> Note
>
> If you use `react-test-renderer`, it also provides an `act` export that behaves the same way.

For example, let’s say we have this `Counter` component:

```
class Counter extends React.Component {
  constructor(props) {
    super(props);
    this.state = {count: 0};
    this.handleClick = this.handleClick.bind(this);
  }
  componentDidMount() {
    document.title = `You clicked ${this.state.count} times`;
  }
  componentDidUpdate() {
    document.title = `You clicked ${this.state.count} times`;
  }
  handleClick() {
    this.setState(state => ({
      count: state.count + 1,
    }));
  }
  render() {
    return (
      <div>
        <p>You clicked {this.state.count} times</p>
        <button onClick={this.handleClick}>
          Click me
        </button>
      </div>
    );
  }
}
```

Here is how we can test it:

```
import React from 'react';
import ReactDOM from 'react-dom/client';
import { act } from 'react-dom/test-utils';import Counter from './Counter';

let container;

beforeEach(() => {
  container = document.createElement('div');
  document.body.appendChild(container);
});

afterEach(() => {
  document.body.removeChild(container);
  container = null;
});

it('can render and update a counter', () => {
  // Test first render and componentDidMount
  act(() => {    ReactDOM.createRoot(container).render(<Counter />);  });  const button = container.querySelector('button');
  const label = container.querySelector('p');
  expect(label.textContent).toBe('You clicked 0 times');
  expect(document.title).toBe('You clicked 0 times');

  // Test second render and componentDidUpdate
  act(() => {    button.dispatchEvent(new MouseEvent('click', {bubbles: true}));  });  expect(label.textContent).toBe('You clicked 1 times');
  expect(document.title).toBe('You clicked 1 times');
});
```

* Don’t forget that dispatching DOM events only works when the DOM container is added to the `document`. You can use a library like [React Testing Library](https://testing-library.com/react) to reduce the boilerplate code.
* The [`recipes`](/docs/testing-recipes.html) document contains more details on how `act()` behaves, with examples and usage.

***

### [](#mockcomponent)`mockComponent()`

```
mockComponent(
  componentClass,
  [mockTagName]
)
```

Pass a mocked component module to this method to augment it with useful methods that allow it to be used as a dummy React component. Instead of rendering as usual, the component will become a simple `<div>` (or other tag if `mockTagName` is provided) containing any provided children.

> Note:
>
> `mockComponent()` is a legacy API. We recommend using [`jest.mock()`](https://jestjs.io/docs/tutorial-react-native#mock-native-modules-using-jestmock) instead.

***

### [](#iselement)`isElement()`

```
isElement(element)
```

Returns `true` if `element` is any React element.

***

### [](#iselementoftype)`isElementOfType()`

```
isElementOfType(
  element,
  componentClass
)
```

Returns `true` if `element` is a React element whose type is of a React `componentClass`.

***

### [](#isdomcomponent)`isDOMComponent()`

```
isDOMComponent(instance)
```

Returns `true` if `instance` is a DOM component (such as a `<div>` or `<span>`).

***

### [](#iscompositecomponent)`isCompositeComponent()`

```
isCompositeComponent(instance)
```

Returns `true` if `instance` is a user-defined component, such as a class or a function.

***

### [](#iscompositecomponentwithtype)`isCompositeComponentWithType()`

```
isCompositeComponentWithType(
  instance,
  componentClass
)
```

Returns `true` if `instance` is a component whose type is of a React `componentClass`.

***

### [](#findallinrenderedtree)`findAllInRenderedTree()`

```
findAllInRenderedTree(
  tree,
  test
)
```

Traverse all components in `tree` and accumulate all components where `test(component)` is `true`. This is not that useful on its own, but it’s used as a primitive for other test utils.

***

### [](#scryrendereddomcomponentswithclass)`scryRenderedDOMComponentsWithClass()`

```
scryRenderedDOMComponentsWithClass(
  tree,
  className
)
```

Finds all DOM elements of components in the rendered tree that are DOM components with the class name matching `className`.

***

### [](#findrendereddomcomponentwithclass)`findRenderedDOMComponentWithClass()`

```
findRenderedDOMComponentWithClass(
  tree,
  className
)
```

Like [`scryRenderedDOMComponentsWithClass()`](#scryrendereddomcomponentswithclass) but expects there to be one result, and returns that one result, or throws exception if there is any other number of matches besides one.

***

### [](#scryrendereddomcomponentswithtag)`scryRenderedDOMComponentsWithTag()`

```
scryRenderedDOMComponentsWithTag(
  tree,
  tagName
)
```

Finds all DOM elements of components in the rendered tree that are DOM components with the tag name matching `tagName`.

***

### [](#findrendereddomcomponentwithtag)`findRenderedDOMComponentWithTag()`

```
findRenderedDOMComponentWithTag(
  tree,
  tagName
)
```

Like [`scryRenderedDOMComponentsWithTag()`](#scryrendereddomcomponentswithtag) but expects there to be one result, and returns that one result, or throws exception if there is any other number of matches besides one.

***

### [](#scryrenderedcomponentswithtype)`scryRenderedComponentsWithType()`

```
scryRenderedComponentsWithType(
  tree,
  componentClass
)
```

Finds all instances of components with type equal to `componentClass`.

***

### [](#findrenderedcomponentwithtype)`findRenderedComponentWithType()`

```
findRenderedComponentWithType(
  tree,
  componentClass
)
```

Same as [`scryRenderedComponentsWithType()`](#scryrenderedcomponentswithtype) but expects there to be one result and returns that one result, or throws exception if there is any other number of matches besides one.

***

### [](#renderintodocument)`renderIntoDocument()`

```
renderIntoDocument(element)
```

Render a React element into a detached DOM node in the document. **This function requires a DOM.** It is effectively equivalent to:

```
const domContainer = document.createElement('div');
ReactDOM.createRoot(domContainer).render(element);
```

> Note:
>
> You will need to have `window`, `window.document` and `window.document.createElement` globally available **before** you import `React`. Otherwise React will think it can’t access the DOM and methods like `setState` won’t work.

***

## [](#other-utilities)Other Utilities

### [](#simulate)`Simulate`

```
Simulate.{eventName}(
  element,
  [eventData]
)
```

Simulate an event dispatch on a DOM node with optional `eventData` event data.

`Simulate` has a method for [every event that React understands](/docs/events.html#supported-events).

**Clicking an element**

```
// <button ref={(node) => this.button = node}>...</button>
const node = this.button;
ReactTestUtils.Simulate.click(node);
```

**Changing the value of an input field and then pressing ENTER.**

```
// <input ref={(node) => this.textInput = node} />
const node = this.textInput;
node.value = 'giraffe';
ReactTestUtils.Simulate.change(node);
ReactTestUtils.Simulate.keyDown(node, {key: "Enter", keyCode: 13, which: 13});
```

> Note
>
> You will have to provide any event property that you’re using in your component (e.g. keyCode, which, etc…) as React is not creating any of these for you.

***

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/addons-test-utils.md)

----
url: https://legacy.reactjs.org/docs/hooks-overview.html
----

> These docs are old and won’t be updated. Go to [react.dev](https://react.dev/) for the new React docs.
>
> These new documentation pages teach React with Hooks:
>
> * [Quick Start](https://react.dev/learn)
> * [Tutorial](https://react.dev/learn/tutorial-tic-tac-toe)
> * [`react`: Hooks](https://react.dev/reference/react)

*Hooks* are a new addition in React 16.8. They let you use state and other React features without writing a class.

Hooks are [backwards-compatible](/docs/hooks-intro.html#no-breaking-changes). This page provides an overview of Hooks for experienced React users. This is a fast-paced overview. If you get confused, look for a yellow box like this:

> Detailed Explanation
>
> Read the [Motivation](/docs/hooks-intro.html#motivation) to learn why we’re introducing Hooks to React.

**↑↑↑ Each section ends with a yellow box like this.** They link to detailed explanations.

## [](#state-hook)📌 State Hook

This example renders a counter. When you click the button, it increments the value:

```
import React, { useState } from 'react';
function Example() {
  // Declare a new state variable, which we'll call "count"  const [count, setCount] = useState(0);
  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}
```

Here, `useState` is a *Hook* (we’ll talk about what this means in a moment). We call it inside a function component to add some local state to it. React will preserve this state between re-renders. `useState` returns a pair: the *current* state value and a function that lets you update it. You can call this function from an event handler or somewhere else. It’s similar to `this.setState` in a class, except it doesn’t merge the old and new state together. (We’ll show an example comparing `useState` to `this.state` in [Using the State Hook](/docs/hooks-state.html).)

The only argument to `useState` is the initial state. In the example above, it is `0` because our counter starts from zero. Note that unlike `this.state`, the state here doesn’t have to be an object — although it can be if you want. The initial state argument is only used during the first render.

#### [](#declaring-multiple-state-variables)Declaring multiple state variables

You can use the State Hook more than once in a single component:

```
function ExampleWithManyStates() {
  // Declare multiple state variables!
  const [age, setAge] = useState(42);
  const [fruit, setFruit] = useState('banana');
  const [todos, setTodos] = useState([{ text: 'Learn Hooks' }]);
  // ...
}
```

The [array destructuring](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Array_destructuring) syntax lets us give different names to the state variables we declared by calling `useState`. These names aren’t a part of the `useState` API. Instead, React assumes that if you call `useState` many times, you do it in the same order during every render. We’ll come back to why this works and when this is useful later.

#### [](#but-what-is-a-hook)But what is a Hook?

Hooks are functions that let you “hook into” React state and lifecycle features from function components. Hooks don’t work inside classes — they let you use React without classes. (We [don’t recommend](/docs/hooks-intro.html#gradual-adoption-strategy) rewriting your existing components overnight but you can start using Hooks in the new ones if you’d like.)

React provides a few built-in Hooks like `useState`. You can also create your own Hooks to reuse stateful behavior between different components. We’ll look at the built-in Hooks first.

> Detailed Explanation
>
> You can learn more about the State Hook on a dedicated page: [Using the State Hook](/docs/hooks-state.html).

## [](#effect-hook)⚡️ Effect Hook

You’ve likely performed data fetching, subscriptions, or manually changing the DOM from React components before. We call these operations “side effects” (or “effects” for short) because they can affect other components and can’t be done during rendering.

The Effect Hook, `useEffect`, adds the ability to perform side effects from a function component. It serves the same purpose as `componentDidMount`, `componentDidUpdate`, and `componentWillUnmount` in React classes, but unified into a single API. (We’ll show examples comparing `useEffect` to these methods in [Using the Effect Hook](/docs/hooks-effect.html).)

For example, this component sets the document title after React updates the DOM:

```
import React, { useState, useEffect } from 'react';
function Example() {
  const [count, setCount] = useState(0);

  // Similar to componentDidMount and componentDidUpdate:  useEffect(() => {    // Update the document title using the browser API    document.title = `You clicked ${count} times`;  });
  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}
```

When you call `useEffect`, you’re telling React to run your “effect” function after flushing changes to the DOM. Effects are declared inside the component so they have access to its props and state. By default, React runs the effects after every render — *including* the first render. (We’ll talk more about how this compares to class lifecycles in [Using the Effect Hook](/docs/hooks-effect.html).)

Effects may also optionally specify how to “clean up” after them by returning a function. For example, this component uses an effect to subscribe to a friend’s online status, and cleans up by unsubscribing from it:

```
import React, { useState, useEffect } from 'react';

function FriendStatus(props) {
  const [isOnline, setIsOnline] = useState(null);

  function handleStatusChange(status) {
    setIsOnline(status.isOnline);
  }

  useEffect(() => {    ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);    return () => {      ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);    };  });
  if (isOnline === null) {
    return 'Loading...';
  }
  return isOnline ? 'Online' : 'Offline';
}
```

In this example, React would unsubscribe from our `ChatAPI` when the component unmounts, as well as before re-running the effect due to a subsequent render. (If you want, there’s a way to [tell React to skip re-subscribing](/docs/hooks-effect.html#tip-optimizing-performance-by-skipping-effects) if the `props.friend.id` we passed to `ChatAPI` didn’t change.)

Just like with `useState`, you can use more than a single effect in a component:

```
function FriendStatusWithCounter(props) {
  const [count, setCount] = useState(0);
  useEffect(() => {    document.title = `You clicked ${count} times`;
  });

  const [isOnline, setIsOnline] = useState(null);
  useEffect(() => {    ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
    return () => {
      ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
    };
  });

  function handleStatusChange(status) {
    setIsOnline(status.isOnline);
  }
  // ...
```

Hooks let you organize side effects in a component by what pieces are related (such as adding and removing a subscription), rather than forcing a split based on lifecycle methods.

> Detailed Explanation
>
> You can learn more about `useEffect` on a dedicated page: [Using the Effect Hook](/docs/hooks-effect.html).

## [](#rules-of-hooks)✌️ Rules of Hooks

Hooks are JavaScript functions, but they impose two additional rules:

* Only call Hooks **at the top level**. Don’t call Hooks inside loops, conditions, or nested functions.
* Only call Hooks **from React function components**. Don’t call Hooks from regular JavaScript functions. (There is just one other valid place to call Hooks — your own custom Hooks. We’ll learn about them in a moment.)

We provide a [linter plugin](https://www.npmjs.com/package/eslint-plugin-react-hooks) to enforce these rules automatically. We understand these rules might seem limiting or confusing at first, but they are essential to making Hooks work well.

> Detailed Explanation
>
> You can learn more about these rules on a dedicated page: [Rules of Hooks](/docs/hooks-rules.html).

## [](#building-your-own-hooks)💡 Building Your Own Hooks

Sometimes, we want to reuse some stateful logic between components. Traditionally, there were two popular solutions to this problem: [higher-order components](/docs/higher-order-components.html) and [render props](/docs/render-props.html). Custom Hooks let you do this, but without adding more components to your tree.

Earlier on this page, we introduced a `FriendStatus` component that calls the `useState` and `useEffect` Hooks to subscribe to a friend’s online status. Let’s say we also want to reuse this subscription logic in another component.

First, we’ll extract this logic into a custom Hook called `useFriendStatus`:

```
import React, { useState, useEffect } from 'react';

function useFriendStatus(friendID) {  const [isOnline, setIsOnline] = useState(null);

  function handleStatusChange(status) {
    setIsOnline(status.isOnline);
  }

  useEffect(() => {
    ChatAPI.subscribeToFriendStatus(friendID, handleStatusChange);
    return () => {
      ChatAPI.unsubscribeFromFriendStatus(friendID, handleStatusChange);
    };
  });

  return isOnline;
}
```

It takes `friendID` as an argument, and returns whether our friend is online.

Now we can use it from both components:

```
function FriendStatus(props) {
  const isOnline = useFriendStatus(props.friend.id);
  if (isOnline === null) {
    return 'Loading...';
  }
  return isOnline ? 'Online' : 'Offline';
}
```

```
function FriendListItem(props) {
  const isOnline = useFriendStatus(props.friend.id);
  return (
    <li style={{ color: isOnline ? 'green' : 'black' }}>
      {props.friend.name}
    </li>
  );
}
```

The state of each component is completely independent. Hooks are a way to reuse *stateful logic*, not state itself. In fact, each *call* to a Hook has a completely isolated state — so you can even use the same custom Hook twice in one component.

Custom Hooks are more of a convention than a feature. If a function’s name starts with ”`use`” and it calls other Hooks, we say it is a custom Hook. The `useSomething` naming convention is how our linter plugin is able to find bugs in the code using Hooks.

You can write custom Hooks that cover a wide range of use cases like form handling, animation, declarative subscriptions, timers, and probably many more we haven’t considered. We are excited to see what custom Hooks the React community will come up with.

> Detailed Explanation
>
> You can learn more about custom Hooks on a dedicated page: [Building Your Own Hooks](/docs/hooks-custom.html).

## [](#other-hooks)🔌 Other Hooks

There are a few less commonly used built-in Hooks that you might find useful. For example, [`useContext`](/docs/hooks-reference.html#usecontext) lets you subscribe to React context without introducing nesting:

```
function Example() {
  const locale = useContext(LocaleContext);  const theme = useContext(ThemeContext);  // ...
}
```

And [`useReducer`](/docs/hooks-reference.html#usereducer) lets you manage local state of complex components with a reducer:

```
function Todos() {
  const [todos, dispatch] = useReducer(todosReducer);  // ...
```

> Detailed Explanation
>
> You can learn more about all the built-in Hooks on a dedicated page: [Hooks API Reference](/docs/hooks-reference.html).

## [](#next-steps)Next Steps

Phew, that was fast! If some things didn’t quite make sense or you’d like to learn more in detail, you can read the next pages, starting with the [State Hook](/docs/hooks-state.html) documentation.

You can also check out the [Hooks API reference](/docs/hooks-reference.html) and the [Hooks FAQ](/docs/hooks-faq.html).

Finally, don’t miss the [introduction page](/docs/hooks-intro.html) which explains *why* we’re adding Hooks and how we’ll start using them side by side with classes — without rewriting our apps.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/hooks-overview.md)

* Previous article

  [Introducing Hooks](/docs/hooks-intro.html)

* Next article

  [Using the State Hook](/docs/hooks-state.html)

----
url: https://legacy.reactjs.org/blog/2015/03/03/react-v0.13-rc2.html
----

March 03, 2015 by [Sebastian Markbåge](https://twitter.com/sebmarkbage)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

Thanks to everybody who has already been testing the release candidate. We’ve received some good feedback and as a result we’re going to do a second release candidate. The changes are minimal. We haven’t changed the behavior of any APIs we exposed in the previous release candidate. Here’s a summary of the changes:

* Introduced a new API (`React.cloneElement`, see below for details).
* Fixed a bug related to validating `propTypes` when using the new `React.addons.createFragment` API.
* Improved a couple warning messages.
* Upgraded jstransform and esprima.

The release candidate is available for download:

* **React**\
  Dev build with warnings: <https://fb.me/react-0.13.0-rc2.js>\
  Minified build for production: <https://fb.me/react-0.13.0-rc2.min.js>
* **React with Add-Ons**\
  Dev build with warnings: <https://fb.me/react-with-addons-0.13.0-rc2.js>\
  Minified build for production: <https://fb.me/react-with-addons-0.13.0-rc2.min.js>
* **In-Browser JSX transformer**\
  <https://fb.me/JSXTransformer-0.13.0-rc2.js>

We’ve also published version `0.13.0-rc2` of the `react` and `react-tools` packages on npm and the `react` package on bower.

***

## [](#reactcloneelement)React.cloneElement

In React v0.13 RC2 we will introduce a new API, similar to `React.addons.cloneWithProps`, with this signature:

```
React.cloneElement(element, props, ...children);
```

Unlike `cloneWithProps`, this new function does not have any magic built-in behavior for merging `style` and `className` for the same reason we don’t have that feature from `transferPropsTo`. Nobody is sure what exactly the complete list of magic things are, which makes it difficult to reason about the code and difficult to reuse when `style` has a different signature (e.g. in the upcoming React Native).

`React.cloneElement` is *almost* equivalent to:

```
<element.type {...element.props} {...props}>{children}</element.type>
```

However, unlike JSX and `cloneWithProps`, it also preserves `ref`s. This means that if you get a child with a `ref` on it, you won’t accidentally steal it from your ancestor. You will get the same `ref` attached to your new element.

One common pattern is to map over your children and add a new prop. There were many issues reported about `cloneWithProps` losing the ref, making it harder to reason about your code. Now following the same pattern with `cloneElement` will work as expected. For example:

```
var newChildren = React.Children.map(this.props.children, function(child) {
  return React.cloneElement(child, { foo: true })
});
```

> Note: `React.cloneElement(child, { ref: 'newRef' })` *DOES* override the `ref` so it is still not possible for two parents to have a ref to the same child, unless you use callback-refs.

This was a critical feature to get into React 0.13 since props are now immutable. The upgrade path is often to clone the element, but by doing so you might lose the `ref`. Therefore, we needed a nicer upgrade path here. As we were upgrading callsites at Facebook we realized that we needed this method. We got the same feedback from the community. Therefore we decided to make another RC before the final release to make sure we get this in.

We plan to eventually deprecate `React.addons.cloneWithProps`. We’re not doing it yet, but this is a good opportunity to start thinking about your own uses and consider using `React.cloneElement` instead. We’ll be sure to ship a release with deprecation notices before we actually remove it so no immediate action is necessary.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2015-03-03-react-v0.13-rc2.md)

----
url: https://legacy.reactjs.org/blog/2014/08/03/community-roundup-21.html
----

August 03, 2014 by [Lou Husson](https://twitter.com/loukan42)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

## [](#react-router)React Router

[Ryan Florence](http://ryanflorence.com/) and [Michael Jackson](https://twitter.com/mjackson) ported Ember’s router to React in a project called [React Router](https://github.com/rackt/react-router). This is a very good example of both communities working together to make the web better!

```
React.renderComponent((
  <Routes>
    <Route handler={App}>
      <Route name="about" handler={About}/>
      <Route name="users" handler={Users}>
        <Route name="user" path="/user/:userId" handler={User}/>
      </Route>
    </Route>
  </Routes>
), document.getElementById('example'));
```

## [](#going-big-with-react)Going Big with React

Areeb Malik, from Facebook, talks about his experience using React. “On paper, all those JS frameworks look promising: clean implementations, quick code design, flawless execution. But what happens when you stress test JavaScript? What happens when you throw 6 megabytes of code at it? In this talk, we’ll investigate how React performs in a high stress situation, and how it has helped our team build safe code on a massive scale”

[](https://skillsmatter.com/skillscasts/5429-going-big-with-react)

## [](#what-is-react)What is React?

[Craig McKeachie](http://www.funnyant.com/author/admin/) author of [JavaScript Framework Guide](http://www.funnyant.com/javascript-framework-guide/) wrote an excellent news named [“What is React.js? Another Template Library?](http://www.funnyant.com/reactjs-what-is-it/)

* Is React a template library?
* Is React similar to Web Components?
* Are the Virtual DOM and Shadow DOM the same?
* Can React be used with other JavaScript MVC frameworks?
* Who uses React?
* Is React a premature optimization if you aren’t Facebook or Instagram?
* Can I work with designers?
* Will React hurt my search engine optimizations (SEO)?
* Is React a framework for building applications or a library with one feature?
* Are components a better way to build an application?
* Can I build something complex with React?

## [](#referencing-dynamic-children)Referencing Dynamic Children

While Matt Zabriskie was working on [react-tabs](https://www.npmjs.com/package/react-tabs) he discovered how to use React.Children.map and React.addons.cloneWithProps in order to [reference dynamic children](http://www.mattzabriskie.com/blog/react-referencing-dynamic-children).

```
var App = React.createClass({
  render: function () {
    var children = React.Children.map(this.props.children, function(child, index) {
      return React.addons.cloneWithProps(child, {
        ref: 'child-' + index
      });
    });
    return <div>{children}</div>;
  }
});
```

## [](#jsx-with-sweetjs-using-readtables)JSX with Sweet.js using Readtables

Have you ever wondered how JSX was implemented? James Long wrote a very instructive blog post that explains how to [compile JSX with Sweet.js using Readtables](http://jlongster.com/Compiling-JSX-with-Sweet.js-using-Readtables).

[](http://jlongster.com/Compiling-JSX-with-Sweet.js-using-Readtables)

## [](#first-look-getting-started-with-react)First Look: Getting Started with React

[Kirill Buga](http://modernweb.com/authors/kirill-buga/) wrote an article on Modern Web explaining how [React is different from traditional MVC](http://modernweb.com/2014/07/23/getting-started-reactjs/) used by most JavaScript applications

[](http://modernweb.com/2014/07/23/getting-started-reactjs)

## [](#react-draggable)React Draggable

[Matt Zabriskie](https://github.com/mzabriskie) released a [project](https://github.com/mzabriskie/react-draggable) to make your react components draggable.

[](https://mzabriskie.github.io/react-draggable/example/)

## [](#html-parser2-react)HTML Parser2 React

[Jason Brown](https://browniefed.github.io/) adapted htmlparser2 to React: [htmlparser2-react](https://www.npmjs.com/package/htmlparser2-react). That allows you to convert raw HTML to the virtual DOM. This is not the intended way to use React but can be useful as last resort if you have an existing piece of HTML.

```
var html = '<div data-id="1" class="hey this is a class" ' +
  'style="width:100%;height: 100%;"><article id="this-article">' +
  '<p>hey this is a paragraph</p><div><ul><li>1</li><li>2</li>' +
  '<li>3</li></ul></div></article></div>';
var parsedComponent = reactParser(html, React);
```

## [](#building-uis-with-react)Building UIs with React

If you haven’t yet tried out React, Jacob Rios did a Hangout where he covers the most important aspects and thankfully he recorded it!

## [](#random-tweets)Random Tweets

> We shipped reddit's first production [@reactjs](https://twitter.com/reactjs) code last week, our checkout process. <https://t.co/KUInwsCmAF>
>
> — Brian Holt (@holtbt) [July 28, 2014](https://twitter.com/holtbt/statuses/493852312604254208)

> .[@AirbnbNerds](https://twitter.com/AirbnbNerds) just launched our first user-facing React.js feature to production! We love it so far. <https://t.co/KtyudemcIW> /[@floydophone](https://twitter.com/floydophone)
>
> — spikebrehm (@spikebrehm) [July 22, 2014](https://twitter.com/spikebrehm/statuses/491645223643013121)

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2014-08-03-community-roundup-21.md)

----
url: https://18.react.dev/reference/react/use
----

[API Reference](/reference/react)

[APIs](/reference/react/apis)

# use[](#undefined "Link for this heading")

### Canary

The `use` API is currently only available in React’s Canary and experimental channels. Learn more about [React’s release channels here](/community/versioning-policy#all-release-channels).

`use` is a React API that lets you read the value of a resource like a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) or [context](/learn/passing-data-deeply-with-context).

```
const value = use(resource);
```

* [Reference](#reference)
  * [`use(resource)`](#use)

* [Usage](#usage)

  * [Reading context with `use`](#reading-context-with-use)
  * [Streaming data from the server to the client](#streaming-data-from-server-to-client)
  * [Dealing with rejected Promises](#dealing-with-rejected-promises)

* [Troubleshooting](#troubleshooting)
  * [“Suspense Exception: This is not a real error!”](#suspense-exception-error)

***

## Reference[](#reference "Link for Reference ")

### `use(resource)`[](#use "Link for this heading")

Call `use` in your component to read the value of a resource like a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) or [context](/learn/passing-data-deeply-with-context).

```
import { use } from 'react';



function MessageComponent({ messagePromise }) {

  const message = use(messagePromise);

  const theme = use(ThemeContext);

  // ...
```

Unlike React Hooks, `use` can be called within loops and conditional statements like `if`. Like React Hooks, the function that calls `use` must be a Component or Hook.

When called with a Promise, the `use` API integrates with [`Suspense`](/reference/react/Suspense) and [error boundaries](/reference/react/Component#catching-rendering-errors-with-an-error-boundary). The component calling `use` *suspends* while the Promise passed to `use` is pending. If the component that calls `use` is wrapped in a Suspense boundary, the fallback will be displayed. Once the Promise is resolved, the Suspense fallback is replaced by the rendered components using the data returned by the `use` API. If the Promise passed to `use` is rejected, the fallback of the nearest Error Boundary will be displayed.

[See more examples below.](#usage)

#### Parameters[](#parameters "Link for Parameters ")

* `resource`: this is the source of the data you want to read a value from. A resource can be a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) or a [context](/learn/passing-data-deeply-with-context).

#### Returns[](#returns "Link for Returns ")

The `use` API returns the value that was read from the resource like the resolved value of a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) or [context](/learn/passing-data-deeply-with-context).

#### Caveats[](#caveats "Link for Caveats ")

* The `use` API must be called inside a Component or a Hook.
* When fetching data in a [Server Component](/reference/rsc/use-server), prefer `async` and `await` over `use`. `async` and `await` pick up rendering from the point where `await` was invoked, whereas `use` re-renders the component after the data is resolved.
* Prefer creating Promises in [Server Components](/reference/rsc/use-server) and passing them to [Client Components](/reference/rsc/use-client) over creating Promises in Client Components. Promises created in Client Components are recreated on every render. Promises passed from a Server Component to a Client Component are stable across re-renders. [See this example](#streaming-data-from-server-to-client).

***

## Usage[](#usage "Link for Usage ")

### Reading context with `use`[](#reading-context-with-use "Link for this heading")

When a [context](/learn/passing-data-deeply-with-context) is passed to `use`, it works similarly to [`useContext`](/reference/react/useContext). While `useContext` must be called at the top level of your component, `use` can be called inside conditionals like `if` and loops like `for`. `use` is preferred over `useContext` because it is more flexible.

```
import { use } from 'react';



function Button() {

  const theme = use(ThemeContext);

  // ...
```

`use` returns the context value for the context you passed. To determine the context value, React searches the component tree and finds **the closest context provider above** for that particular context.

To pass context to a `Button`, wrap it or one of its parent components into the corresponding context provider.

```
function MyPage() {

  return (

    <ThemeContext.Provider value="dark">

      <Form />

    </ThemeContext.Provider>

  );

}



function Form() {

  // ... renders buttons inside ...

}
```

It doesn’t matter how many layers of components there are between the provider and the `Button`. When a `Button` *anywhere* inside of `Form` calls `use(ThemeContext)`, it will receive `"dark"` as the value.

Unlike [`useContext`](/reference/react/useContext), `use` can be called in conditionals and loops like `if`.

```
function HorizontalRule({ show }) {

  if (show) {

    const theme = use(ThemeContext);

    return <hr className={theme} />;

  }

  return false;

}
```

`use` is called from inside a `if` statement, allowing you to conditionally read values from a Context.

### Pitfall

Like `useContext`, `use(context)` always looks for the closest context provider *above* the component that calls it. It searches upwards and **does not** consider context providers in the component from which you’re calling `use(context)`.

```
import { createContext, use } from 'react';

const ThemeContext = createContext(null);

export default function MyApp() {
  return (
    <ThemeContext.Provider value="dark">
      <Form />
    </ThemeContext.Provider>
  )
}

function Form() {
  return (
    <Panel title="Welcome">
      <Button show={true}>Sign up</Button>
      <Button show={false}>Log in</Button>
    </Panel>
  );
}

function Panel({ title, children }) {
  const theme = use(ThemeContext);
  const className = 'panel-' + theme;
  return (
    <section className={className}>
      <h1>{title}</h1>
      {children}
    </section>
  )
}

function Button({ show, children }) {
  if (show) {
    const theme = use(ThemeContext);
    const className = 'button-' + theme;
    return (
      <button className={className}>
        {children}
      </button>
    );
  }
  return false
}
```

### Streaming data from the server to the client[](#streaming-data-from-server-to-client "Link for Streaming data from the server to the client ")

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.

```
import { fetchMessage } from './lib.js';

import { Message } from './message.js';



export default function App() {

  const messagePromise = fetchMessage();

  return (

    <Suspense fallback={<p>waiting for message...</p>}>

      <Message messagePromise={messagePromise} />

    </Suspense>

  );

}
```

The Client Component then takes the Promise it received as a prop and passes it to the `use` API. This allows the Client Component to read the value from the Promise that was initially created by the Server Component.

```
// message.js

'use client';



import { use } from 'react';



export function Message({ messagePromise }) {

  const messageContent = use(messagePromise);

  return <p>Here is the message: {messageContent}</p>;

}
```

Because `Message` is wrapped in [`Suspense`](/reference/react/Suspense), the fallback will be displayed until the Promise is resolved. When the Promise is resolved, the value will be read by the `use` API and the `Message` component will replace the Suspense fallback.

```
"use client";

import { use, Suspense } from "react";

function Message({ messagePromise }) {
  const messageContent = use(messagePromise);
  return <p>Here is the message: {messageContent}</p>;
}

export function MessageContainer({ messagePromise }) {
  return (
    <Suspense fallback={<p>⌛Downloading message...</p>}>
      <Message messagePromise={messagePromise} />
    </Suspense>
  );
}
```

### Note

When passing a Promise from a Server Component to a Client Component, its resolved value must be serializable to pass between server and client. Data types like functions aren’t serializable and cannot be the resolved value of such a Promise.

##### Deep Dive#### Should I resolve a Promise in a Server or Client Component?[](#resolve-promise-in-server-or-client-component "Link for Should I resolve a Promise in a Server or Client Component? ")

A Promise can be passed from a Server Component to a Client Component and resolved in the Client Component with the `use` API. You can also resolve the Promise in a Server Component with `await` and pass the required data to the Client Component as a prop.

```
export default async function App() {

  const messageContent = await fetchMessage();

  return <Message messageContent={messageContent} />

}
```

But using `await` in a [Server Component](/reference/react/components#server-components) will block its rendering until the `await` statement is finished. Passing a Promise from a Server Component to a Client Component prevents the Promise from blocking the rendering of the Server Component.

### Dealing with rejected Promises[](#dealing-with-rejected-promises "Link for Dealing with rejected Promises ")

In some cases a Promise passed to `use` could be rejected. You can handle rejected Promises by either:

1. [Displaying an error to users with an error boundary.](#displaying-an-error-to-users-with-error-boundary)
2. [Providing an alternative value with `Promise.catch`](#providing-an-alternative-value-with-promise-catch)

### Pitfall

`use` cannot be called in a try-catch block. Instead of a try-catch block [wrap your component in an Error Boundary](#displaying-an-error-to-users-with-error-boundary), or [provide an alternative value to use with the Promise’s `.catch` method](#providing-an-alternative-value-with-promise-catch).

#### Displaying an error to users with an error boundary[](#displaying-an-error-to-users-with-error-boundary "Link for Displaying an error to users with an error boundary ")

If you’d like to display an error to your users when a Promise is rejected, you can use an [error boundary](/reference/react/Component#catching-rendering-errors-with-an-error-boundary). To use an error boundary, wrap the component where you are calling the `use` API in an error boundary. If the Promise passed to `use` is rejected the fallback for the error boundary will be displayed.

```
"use client";

import { use, Suspense } from "react";
import { ErrorBoundary } from "react-error-boundary";

export function MessageContainer({ messagePromise }) {
  return (
    <ErrorBoundary fallback={<p>⚠️Something went wrong</p>}>
      <Suspense fallback={<p>⌛Downloading message...</p>}>
        <Message messagePromise={messagePromise} />
      </Suspense>
    </ErrorBoundary>
  );
}

function Message({ messagePromise }) {
  const content = use(messagePromise);
  return <p>Here is the message: {content}</p>;
}
```

#### Providing an alternative value with `Promise.catch`[](#providing-an-alternative-value-with-promise-catch "Link for this heading")

If you’d like to provide an alternative value when the Promise passed to `use` is rejected you can use the Promise’s [`catch`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/catch) method.

```
import { Message } from './message.js';



export default function App() {

  const messagePromise = new Promise((resolve, reject) => {

    reject();

  }).catch(() => {

    return "no new message found.";

  });



  return (

    <Suspense fallback={<p>waiting for message...</p>}>

      <Message messagePromise={messagePromise} />

    </Suspense>

  );

}
```

To use the Promise’s `catch` method, call `catch` on the Promise object. `catch` takes a single argument: a function that takes an error message as an argument. Whatever is returned by the function passed to `catch` will be used as the resolved value of the Promise.

***

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### “Suspense Exception: This is not a real error!”[](#suspense-exception-error "Link for “Suspense Exception: This is not a real error!” ")

You are either calling `use` outside of a React Component or Hook function, or calling `use` in a try–catch block. If you are calling `use` inside a try–catch block, wrap your component in an error boundary, or call the Promise’s `catch` to catch the error and resolve the Promise with another value. [See these examples](#dealing-with-rejected-promises).

If you are calling `use` outside a React Component or Hook function, move the `use` call to a React Component or Hook function.

```
function MessageComponent({messagePromise}) {

  function download() {

    // ❌ the function calling `use` is not a Component or Hook

    const message = use(messagePromise);

    // ...
```

Instead, call `use` outside any component closures, where the function that calls `use` is a Component or Hook.

```
function MessageComponent({messagePromise}) {

  // ✅ `use` is being called from a component. 

  const message = use(messagePromise);

  // ...
```

[PreviousstartTransition](/reference/react/startTransition)

[Nextexperimental\_taintObjectReference](/reference/react/experimental_taintObjectReference)

***

----
url: https://legacy.reactjs.org/docs/glossary.html
----

## [](#single-page-application)Single-page Application

A single-page application is an application that loads a single HTML page and all the necessary assets (such as JavaScript and CSS) required for the application to run. Any interactions with the page or subsequent pages do not require a round trip to the server which means the page is not reloaded.

Though you may build a single-page application in React, it is not a requirement. React can also be used for enhancing small parts of existing websites with additional interactivity. Code written in React can coexist peacefully with markup rendered on the server by something like PHP, or with other client-side libraries. In fact, this is exactly how React is being used at Facebook.

## [](#es6-es2015-es2016-etc)ES6, ES2015, ES2016, etc

These acronyms all refer to the most recent versions of the ECMAScript Language Specification standard, which the JavaScript language is an implementation of. The ES6 version (also known as ES2015) includes many additions to the previous versions such as: arrow functions, classes, template literals, `let` and `const` statements. You can learn more about specific versions [here](https://en.wikipedia.org/wiki/ECMAScript#Versions).

## [](#compilers)Compilers

A JavaScript compiler takes JavaScript code, transforms it and returns JavaScript code in a different format. The most common use case is to take ES6 syntax and transform it into syntax that older browsers are capable of interpreting. [Babel](https://babeljs.io/) is the compiler most commonly used with React.

## [](#bundlers)Bundlers

Bundlers take JavaScript and CSS code written as separate modules (often hundreds of them), and combine them together into a few files better optimized for the browsers. Some bundlers commonly used in React applications include [Webpack](https://webpack.js.org/) and [Browserify](http://browserify.org/).

## [](#package-managers)Package Managers

Package managers are tools that allow you to manage dependencies in your project. [npm](https://www.npmjs.com/) and [Yarn](https://yarnpkg.com/) are two package managers commonly used in React applications. Both of them are clients for the same npm package registry.

## [](#cdn)CDN

CDN stands for Content Delivery Network. CDNs deliver cached, static content from a network of servers across the globe.

## [](#jsx)JSX

JSX is a syntax extension to JavaScript. It is similar to a template language, but it has full power of JavaScript. JSX gets compiled to `React.createElement()` calls which return plain JavaScript objects called “React elements”. To get a basic introduction to JSX [see the docs here](/docs/introducing-jsx.html) and find a more in-depth tutorial on JSX [here](/docs/jsx-in-depth.html).

React DOM uses camelCase property naming convention instead of HTML attribute names. For example, `tabindex` becomes `tabIndex` in JSX. The attribute `class` is also written as `className` since `class` is a reserved word in JavaScript:

```
<h1 className="hello">My name is Clementine!</h1>
```

## [](#elements)[Elements](/docs/rendering-elements.html)

React elements are the building blocks of React applications. One might confuse elements with a more widely known concept of “components”. An element describes what you want to see on the screen. React elements are immutable.

```
const element = <h1>Hello, world</h1>;
```

Typically, elements are not used directly, but get returned from components.

## [](#components)[Components](/docs/components-and-props.html)

React components are small, reusable pieces of code that return a React element to be rendered to the page. The simplest version of React component is a plain JavaScript function that returns a React element:

```
function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}
```

Components can also be ES6 classes:

```
class Welcome extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}
```

Components can be broken down into distinct pieces of functionality and used within other components. Components can return other components, arrays, strings and numbers. A good rule of thumb is that if a part of your UI is used several times (Button, Panel, Avatar), or is complex enough on its own (App, FeedStory, Comment), it is a good candidate to be a reusable component. Component names should also always start with a capital letter (`<Wrapper/>` **not** `<wrapper/>`). See [this documentation](/docs/components-and-props.html#rendering-a-component) for more information on rendering components.

### [](#props)[`props`](/docs/components-and-props.html)

`props` are inputs to a React component. They are data passed down from a parent component to a child component.

Remember that `props` are readonly. They should not be modified in any way:

```
// Wrong!
props.number = 42;
```

If you need to modify some value in response to user input or a network response, use `state` instead.

### [](#propschildren)`props.children`

`props.children` is available on every component. It contains the content between the opening and closing tags of a component. For example:

```
<Welcome>Hello world!</Welcome>
```

The string `Hello world!` is available in `props.children` in the `Welcome` component:

```
function Welcome(props) {
  return <p>{props.children}</p>;
}
```

For components defined as classes, use `this.props.children`:

```
class Welcome extends React.Component {
  render() {
    return <p>{this.props.children}</p>;
  }
}
```

### [](#state)[`state`](/docs/state-and-lifecycle.html#adding-local-state-to-a-class)

A component needs `state` when some data associated with it changes over time. For example, a `Checkbox` component might need `isChecked` in its state, and a `NewsFeed` component might want to keep track of `fetchedPosts` in its state.

The most important difference between `state` and `props` is that `props` are passed from a parent component, but `state` is managed by the component itself. A component cannot change its `props`, but it can change its `state`.

For each particular piece of changing data, there should be just one component that “owns” it in its state. Don’t try to synchronize states of two different components. Instead, [lift it up](/docs/lifting-state-up.html) to their closest shared ancestor, and pass it down as props to both of them.

## [](#lifecycle-methods)[Lifecycle Methods](/docs/state-and-lifecycle.html#adding-lifecycle-methods-to-a-class)

Lifecycle methods are custom functionality that gets executed during the different phases of a component. There are methods available when the component gets created and inserted into the DOM ([mounting](/docs/react-component.html#mounting)), when the component updates, and when the component gets unmounted or removed from the DOM.

## [](#controlled-vs-uncontrolled-components)[Controlled](/docs/forms.html#controlled-components) vs. [Uncontrolled Components](/docs/uncontrolled-components.html)

React has two different approaches to dealing with form inputs.

An input form element whose value is controlled by React is called a *controlled component*. When a user enters data into a controlled component a change event handler is triggered and your code decides whether the input is valid (by re-rendering with the updated value). If you do not re-render then the form element will remain unchanged.

An *uncontrolled component* works like form elements do outside of React. When a user inputs data into a form field (an input box, dropdown, etc) the updated information is reflected without React needing to do anything. However, this also means that you can’t force the field to have a certain value.

In most cases you should use controlled components.

## [](#keys)[Keys](/docs/lists-and-keys.html)

A “key” is a special string attribute you need to include when creating arrays of elements. Keys help React identify which items have changed, are added, or are removed. Keys should be given to the elements inside an array to give the elements a stable identity.

Keys only need to be unique among sibling elements in the same array. They don’t need to be unique across the whole application or even a single component.

Don’t pass something like `Math.random()` to keys. It is important that keys have a “stable identity” across re-renders so that React can determine when items are added, removed, or re-ordered. Ideally, keys should correspond to unique and stable identifiers coming from your data, such as `post.id`.

## [](#refs)[Refs](/docs/refs-and-the-dom.html)

React supports a special attribute that you can attach to any component. The `ref` attribute can be an object created by [`React.createRef()` function](/docs/react-api.html#reactcreateref) or a callback function, or a string (in legacy API). When the `ref` attribute is a callback function, the function receives the underlying DOM element or class instance (depending on the type of element) as its argument. This allows you to have direct access to the DOM element or component instance.

Use refs sparingly. If you find yourself often using refs to “make things happen” in your app, consider getting more familiar with [top-down data flow](/docs/lifting-state-up.html).

## [](#events)[Events](/docs/handling-events.html)

Handling events with React elements has some syntactic differences:

* React event handlers are named using camelCase, rather than lowercase.
* With JSX you pass a function as the event handler, rather than a string.

## [](#reconciliation)[Reconciliation](/docs/reconciliation.html)

When a component’s props or state change, React decides whether an actual DOM update is necessary by comparing the newly returned element with the previously rendered one. When they are not equal, React will update the DOM. This process is called “reconciliation”.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/reference-glossary.md)

----
url: https://react.dev/learn/typescript
----

[Learn React](/learn)

[Setup](/learn/setup)

All [production-grade React frameworks](/learn/creating-a-react-app#full-stack-frameworks) offer support for using TypeScript. Follow the framework specific guide for installation:

```
npm install --save-dev @types/react @types/react-dom
```

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")[TypeScript Playground](https://www.typescriptlang.org/play#src=import%20*%20as%20React%20from%20'react'%3B%0A%0Afunction%20MyButton\(%7B%20title%20%7D%3A%20%7B%20title%3A%20string%20%7D\)%20%7B%0A%20%20return%20\(%0A%20%20%20%20%3Cbutton%3E%7Btitle%7D%3C%2Fbutton%3E%0A%20%20\)%3B%0A%7D%0A%0Aexport%20default%20function%20MyApp\(\)%20%7B%0A%20%20return%20\(%0A%20%20%20%20%3Cdiv%3E%0A%20%20%20%20%20%20%3Ch1%3EWelcome%20to%20my%20app%3C%2Fh1%3E%0A%20%20%20%20%20%20%3CMyButton%20title%3D%22I'm%20a%20button%22%20%2F%3E%0A%20%20%20%20%3C%2Fdiv%3E%0A%20%20\)%3B%0A%7D%0A "Open in TypeScript Playground")

```
function MyButton({ title }: { title: string }) {
  return (
    <button>{title}</button>
  );
}

export default function MyApp() {
  return (
    <div>
      <h1>Welcome to my app</h1>
      <MyButton title="I'm a button" />
    </div>
  );
}
```

### Note

These sandboxes can handle TypeScript code, but they do not run the type-checker. This means you can amend the TypeScript sandboxes to learn, but you won’t get any type errors or warnings. To get type-checking, you can use the [TypeScript Playground](https://www.typescriptlang.org/play) or use a more fully-featured online sandbox.

This inline syntax is the simplest way to provide types for a component, though once you start to have a few fields to describe it can become unwieldy. Instead, you can use an `interface` or `type` to describe the component’s props:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")[TypeScript Playground](https://www.typescriptlang.org/play#src=import%20*%20as%20React%20from%20'react'%3B%0A%0Ainterface%20MyButtonProps%20%7B%0A%20%20%2F**%20The%20text%20to%20display%20inside%20the%20button%20*%2F%0A%20%20title%3A%20string%3B%0A%20%20%2F**%20Whether%20the%20button%20can%20be%20interacted%20with%20*%2F%0A%20%20disabled%3A%20boolean%3B%0A%7D%0A%0Afunction%20MyButton\(%7B%20title%2C%20disabled%20%7D%3A%20MyButtonProps\)%20%7B%0A%20%20return%20\(%0A%20%20%20%20%3Cbutton%20disabled%3D%7Bdisabled%7D%3E%7Btitle%7D%3C%2Fbutton%3E%0A%20%20\)%3B%0A%7D%0A%0Aexport%20default%20function%20MyApp\(\)%20%7B%0A%20%20return%20\(%0A%20%20%20%20%3Cdiv%3E%0A%20%20%20%20%20%20%3Ch1%3EWelcome%20to%20my%20app%3C%2Fh1%3E%0A%20%20%20%20%20%20%3CMyButton%20title%3D%22I'm%20a%20disabled%20button%22%20disabled%3D%7Btrue%7D%2F%3E%0A%20%20%20%20%3C%2Fdiv%3E%0A%20%20\)%3B%0A%7D%0A "Open in TypeScript Playground")

```
interface MyButtonProps {
  /** The text to display inside the button */
  title: string;
  /** Whether the button can be interacted with */
  disabled: boolean;
}

function MyButton({ title, disabled }: MyButtonProps) {
  return (
    <button disabled={disabled}>{title}</button>
  );
}

export default function MyApp() {
  return (
    <div>
      <h1>Welcome to my app</h1>
      <MyButton title="I'm a disabled button" disabled={true}/>
    </div>
  );
}
```

The type describing your component’s props can be as simple or as complex as you need, though they should be an object type described with either a `type` or `interface`. You can learn about how TypeScript describes objects in [Object Types](https://www.typescriptlang.org/docs/handbook/2/objects.html) but you may also be interested in using [Union Types](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#union-types) to describe a prop that can be one of a few different types and the [Creating Types from Types](https://www.typescriptlang.org/docs/handbook/2/types-from-types.html) guide for more advanced use cases.

## Example Hooks[](#example-hooks "Link for Example Hooks ")

The type definitions from `@types/react` include types for the built-in Hooks, so you can use them in your components without any additional setup. They are built to take into account the code you write in your component, so you will get [inferred types](https://www.typescriptlang.org/docs/handbook/type-inference.html) a lot of the time and ideally do not need to handle the minutiae of providing the types.

However, we can look at a few examples of how to provide types for Hooks.

### `useState`[](#typing-usestate "Link for this heading")

The [`useState` Hook](/reference/react/useState) will re-use the value passed in as the initial state to determine what the type of the value should be. For example:

```
// Infer the type as "boolean"

const [enabled, setEnabled] = useState(false);
```

This will assign the type of `boolean` to `enabled`, and `setEnabled` will be a function accepting either a `boolean` argument, or a function that returns a `boolean`. If you want to explicitly provide a type for the state, you can do so by providing a type argument to the `useState` call:

```
// Explicitly set the type to "boolean"

const [enabled, setEnabled] = useState<boolean>(false);
```

This isn’t very useful in this case, but a common case where you may want to provide a type is when you have a union type. For example, `status` here can be one of a few different strings:

```
type Status = "idle" | "loading" | "success" | "error";



const [status, setStatus] = useState<Status>("idle");
```

Or, as recommended in [Principles for structuring state](/learn/choosing-the-state-structure#principles-for-structuring-state), you can group related state as an object and describe the different possibilities via object types:

```
type RequestState =

  | { status: 'idle' }

  | { status: 'loading' }

  | { status: 'success', data: any }

  | { status: 'error', error: Error };



const [requestState, setRequestState] = useState<RequestState>({ status: 'idle' });
```

### `useReducer`[](#typing-usereducer "Link for this heading")

The [`useReducer` Hook](/reference/react/useReducer) is a more complex Hook that takes a reducer function and an initial state. The types for the reducer function are inferred from the initial state. You can optionally provide a type argument to the `useReducer` call to provide a type for the state, but it is often better to set the type on the initial state instead:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")[TypeScript Playground](https://www.typescriptlang.org/play#src=import%20*%20as%20React%20from%20'react'%3B%0A%0Aimport%20%7BuseReducer%7D%20from%20'react'%3B%0A%0Ainterface%20State%20%7B%0A%20%20%20count%3A%20number%0A%7D%3B%0A%0Atype%20CounterAction%20%3D%0A%20%20%7C%20%7B%20type%3A%20%22reset%22%20%7D%0A%20%20%7C%20%7B%20type%3A%20%22setCount%22%3B%20value%3A%20State%5B%22count%22%5D%20%7D%0A%0Aconst%20initialState%3A%20State%20%3D%20%7B%20count%3A%200%20%7D%3B%0A%0Afunction%20stateReducer\(state%3A%20State%2C%20action%3A%20CounterAction\)%3A%20State%20%7B%0A%20%20switch%20\(action.type\)%20%7B%0A%20%20%20%20case%20%22reset%22%3A%0A%20%20%20%20%20%20return%20initialState%3B%0A%20%20%20%20case%20%22setCount%22%3A%0A%20%20%20%20%20%20return%20%7B%20...state%2C%20count%3A%20action.value%20%7D%3B%0A%20%20%20%20default%3A%0A%20%20%20%20%20%20throw%20new%20Error\(%22Unknown%20action%22\)%3B%0A%20%20%7D%0A%7D%0A%0Aexport%20default%20function%20App\(\)%20%7B%0A%20%20const%20%5Bstate%2C%20dispatch%5D%20%3D%20useReducer\(stateReducer%2C%20initialState\)%3B%0A%0A%20%20const%20addFive%20%3D%20\(\)%20%3D%3E%20dispatch\(%7B%20type%3A%20%22setCount%22%2C%20value%3A%20state.count%20%2B%205%20%7D\)%3B%0A%20%20const%20reset%20%3D%20\(\)%20%3D%3E%20dispatch\(%7B%20type%3A%20%22reset%22%20%7D\)%3B%0A%0A%20%20return%20\(%0A%20%20%20%20%3Cdiv%3E%0A%20%20%20%20%20%20%3Ch1%3EWelcome%20to%20my%20counter%3C%2Fh1%3E%0A%0A%20%20%20%20%20%20%3Cp%3ECount%3A%20%7Bstate.count%7D%3C%2Fp%3E%0A%20%20%20%20%20%20%3Cbutton%20onClick%3D%7BaddFive%7D%3EAdd%205%3C%2Fbutton%3E%0A%20%20%20%20%20%20%3Cbutton%20onClick%3D%7Breset%7D%3EReset%3C%2Fbutton%3E%0A%20%20%20%20%3C%2Fdiv%3E%0A%20%20\)%3B%0A%7D%0A%0A "Open in TypeScript Playground")

```
import {useReducer} from 'react';

interface State {
   count: number
};

type CounterAction =
  | { type: "reset" }
  | { type: "setCount"; value: State["count"] }

const initialState: State = { count: 0 };

function stateReducer(state: State, action: CounterAction): State {
  switch (action.type) {
    case "reset":
      return initialState;
    case "setCount":
      return { ...state, count: action.value };
    default:
      throw new Error("Unknown action");
  }
}

export default function App() {
  const [state, dispatch] = useReducer(stateReducer, initialState);

  const addFive = () => dispatch({ type: "setCount", value: state.count + 5 });
  const reset = () => dispatch({ type: "reset" });

  return (
    <div>
      <h1>Welcome to my counter</h1>

      <p>Count: {state.count}</p>
      <button onClick={addFive}>Add 5</button>
      <button onClick={reset}>Reset</button>
    </div>
  );
}
```

We are using TypeScript in a few key places:

* `interface State` describes the shape of the reducer’s state.
* `type CounterAction` describes the different actions which can be dispatched to the reducer.
* `const initialState: State` provides a type for the initial state, and also the type which is used by `useReducer` by default.
* `stateReducer(state: State, action: CounterAction): State` sets the types for the reducer function’s arguments and return value.

A more explicit alternative to setting the type on `initialState` is to provide a type argument to `useReducer`:

```
import { stateReducer, State } from './your-reducer-implementation';



const initialState = { count: 0 };



export default function App() {

  const [state, dispatch] = useReducer<State>(stateReducer, initialState);

}
```

### `useContext`[](#typing-usecontext "Link for this heading")

The [`useContext` Hook](/reference/react/useContext) is a technique for passing data down the component tree without having to pass props through components. It is used by creating a provider component and often by creating a Hook to consume the value in a child component.

The type of the value provided by the context is inferred from the value passed to the `createContext` call:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")[TypeScript Playground](https://www.typescriptlang.org/play#src=import%20*%20as%20React%20from%20'react'%3B%0A%0Aimport%20%7B%20createContext%2C%20useContext%2C%20useState%20%7D%20from%20'react'%3B%0A%0Atype%20Theme%20%3D%20%22light%22%20%7C%20%22dark%22%20%7C%20%22system%22%3B%0Aconst%20ThemeContext%20%3D%20createContext%3CTheme%3E\(%22system%22\)%3B%0A%0Aconst%20useGetTheme%20%3D%20\(\)%20%3D%3E%20useContext\(ThemeContext\)%3B%0A%0Aexport%20default%20function%20MyApp\(\)%20%7B%0A%20%20const%20%5Btheme%2C%20setTheme%5D%20%3D%20useState%3CTheme%3E\('light'\)%3B%0A%0A%20%20return%20\(%0A%20%20%20%20%3CThemeContext%20value%3D%7Btheme%7D%3E%0A%20%20%20%20%20%20%3CMyComponent%20%2F%3E%0A%20%20%20%20%3C%2FThemeContext%3E%0A%20%20\)%0A%7D%0A%0Afunction%20MyComponent\(\)%20%7B%0A%20%20const%20theme%20%3D%20useGetTheme\(\)%3B%0A%0A%20%20return%20\(%0A%20%20%20%20%3Cdiv%3E%0A%20%20%20%20%20%20%3Cp%3ECurrent%20theme%3A%20%7Btheme%7D%3C%2Fp%3E%0A%20%20%20%20%3C%2Fdiv%3E%0A%20%20\)%0A%7D%0A "Open in TypeScript Playground")

```
import { createContext, useContext, useState } from 'react';

type Theme = "light" | "dark" | "system";
const ThemeContext = createContext<Theme>("system");

const useGetTheme = () => useContext(ThemeContext);

export default function MyApp() {
  const [theme, setTheme] = useState<Theme>('light');

  return (
    <ThemeContext value={theme}>
      <MyComponent />
    </ThemeContext>
  )
}

function MyComponent() {
  const theme = useGetTheme();

  return (
    <div>
      <p>Current theme: {theme}</p>
    </div>
  )
}
```

This technique works when you have a default value which makes sense - but there are occasionally cases when you do not, and in those cases `null` can feel reasonable as a default value. However, to allow the type-system to understand your code, you need to explicitly set `ContextShape | null` on the `createContext`.

This causes the issue that you need to eliminate the `| null` in the type for context consumers. Our recommendation is to have the Hook do a runtime check for it’s existence and throw an error when not present:

```
import { createContext, useContext, useState, useMemo } from 'react';



// This is a simpler example, but you can imagine a more complex object here

type ComplexObject = {

  kind: string

};



// The context is created with `| null` in the type, to accurately reflect the default value.

const Context = createContext<ComplexObject | null>(null);



// The `| null` will be removed via the check in the Hook.

const useGetComplexObject = () => {

  const object = useContext(Context);

  if (!object) { throw new Error("useGetComplexObject must be used within a Provider") }

  return object;

}



export default function MyApp() {

  const object = useMemo(() => ({ kind: "complex" }), []);



  return (

    <Context value={object}>

      <MyComponent />

    </Context>

  )

}



function MyComponent() {

  const object = useGetComplexObject();



  return (

    <div>

      <p>Current object: {object.kind}</p>

    </div>

  )

}
```

### `useMemo`[](#typing-usememo "Link for this heading")

### Note

[React Compiler](/learn/react-compiler) automatically memoizes values and functions, reducing the need for manual `useMemo` calls. You can use the compiler to handle memoization automatically.

The [`useMemo`](/reference/react/useMemo) Hooks will create/re-access a memorized value from a function call, re-running the function only when dependencies passed as the 2nd parameter are changed. The result of calling the Hook is inferred from the return value from the function in the first parameter. You can be more explicit by providing a type argument to the Hook.

```
// The type of visibleTodos is inferred from the return value of filterTodos

const visibleTodos = useMemo(() => filterTodos(todos, tab), [todos, tab]);
```

### `useCallback`[](#typing-usecallback "Link for this heading")

### Note

[React Compiler](/learn/react-compiler) automatically memoizes values and functions, reducing the need for manual `useCallback` calls. You can use the compiler to handle memoization automatically.

The [`useCallback`](/reference/react/useCallback) provide a stable reference to a function as long as the dependencies passed into the second parameter are the same. Like `useMemo`, the function’s type is inferred from the return value of the function in the first parameter, and you can be more explicit by providing a type argument to the Hook.

```
const handleClick = useCallback(() => {

  // ...

}, [todos]);
```

When working in TypeScript strict mode `useCallback` requires adding types for the parameters in your callback. This is because the type of the callback is inferred from the return value of the function, and without parameters the type cannot be fully understood.

Depending on your code-style preferences, you could use the `*EventHandler` functions from the React types to provide the type for the event handler at the same time as defining the callback:

```
import { useState, useCallback } from 'react';



export default function Form() {

  const [value, setValue] = useState("Change me");



  const handleChange = useCallback<React.ChangeEventHandler<HTMLInputElement>>((event) => {

    setValue(event.currentTarget.value);

  }, [setValue])



  return (

    <>

      <input value={value} onChange={handleChange} />

      <p>Value: {value}</p>

    </>

  );

}
```

## Useful Types[](#useful-types "Link for Useful Types ")

There is quite an expansive set of types which come from the `@types/react` package, it is worth a read when you feel comfortable with how React and TypeScript interact. You can find them [in React’s folder in DefinitelyTyped](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/react/index.d.ts). We will cover a few of the more common types here.

### DOM Events[](#typing-dom-events "Link for DOM Events ")

When working with DOM events in React, the type of the event can often be inferred from the event handler. However, when you want to extract a function to be passed to an event handler, you will need to explicitly set the type of the event.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")[TypeScript Playground](https://www.typescriptlang.org/play#src=import%20*%20as%20React%20from%20'react'%3B%0A%0Aimport%20%7B%20useState%20%7D%20from%20'react'%3B%0A%0Aexport%20default%20function%20Form\(\)%20%7B%0A%20%20const%20%5Bvalue%2C%20setValue%5D%20%3D%20useState\(%22Change%20me%22\)%3B%0A%0A%20%20function%20handleChange\(event%3A%20React.ChangeEvent%3CHTMLInputElement%3E\)%20%7B%0A%20%20%20%20setValue\(event.currentTarget.value\)%3B%0A%20%20%7D%0A%0A%20%20return%20\(%0A%20%20%20%20%3C%3E%0A%20%20%20%20%20%20%3Cinput%20value%3D%7Bvalue%7D%20onChange%3D%7BhandleChange%7D%20%2F%3E%0A%20%20%20%20%20%20%3Cp%3EValue%3A%20%7Bvalue%7D%3C%2Fp%3E%0A%20%20%20%20%3C%2F%3E%0A%20%20\)%3B%0A%7D%0A "Open in TypeScript Playground")

```
import { useState } from 'react';

export default function Form() {
  const [value, setValue] = useState("Change me");

  function handleChange(event: React.ChangeEvent<HTMLInputElement>) {
    setValue(event.currentTarget.value);
  }

  return (
    <>
      <input value={value} onChange={handleChange} />
      <p>Value: {value}</p>
    </>
  );
}
```

There are many types of events provided in the React types - the full list can be found [here](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/b580df54c0819ec9df62b0835a315dd48b8594a9/types/react/index.d.ts#L1247C1-L1373) which is based on the [most popular events from the DOM](https://developer.mozilla.org/en-US/docs/Web/Events).

When determining the type you are looking for you can first look at the hover information for the event handler you are using, which will show the type of the event.

If you need to use an event that is not included in this list, you can use the `React.SyntheticEvent` type, which is the base type for all events.

### Children[](#typing-children "Link for Children ")

There are two common paths to describing the children of a component. The first is to use the `React.ReactNode` type, which is a union of all the possible types that can be passed as children in JSX:

```
interface ModalRendererProps {

  title: string;

  children: React.ReactNode;

}
```

This is a very broad definition of children. The second is to use the `React.ReactElement` type, which is only JSX elements and not JavaScript primitives like strings or numbers:

```
interface ModalRendererProps {

  title: string;

  children: React.ReactElement;

}
```

Note, that you cannot use TypeScript to describe that the children are a certain type of JSX elements, so you cannot use the type-system to describe a component which only accepts `<li>` children.

You can see an example of both `React.ReactNode` and `React.ReactElement` with the type-checker in [this TypeScript playground](https://www.typescriptlang.org/play?#code/JYWwDg9gTgLgBAJQKYEMDG8BmUIjgIilQ3wChSB6CxYmAOmXRgDkIATJOdNJMGAZzgwAFpxAR+8YADswAVwGkZMJFEzpOjDKw4AFHGEEBvUnDhphwADZsi0gFw0mDWjqQBuUgF9yaCNMlENzgAXjgACjADfkctFnYkfQhDAEpQgD44AB42YAA3dKMo5P46C2tbJGkvLIpcgt9-QLi3AEEwMFCItJDMrPTTbIQ3dKywdIB5aU4kKyQQKpha8drhhIGzLLWODbNs3b3s8YAxKBQAcwXpAThMaGWDvbH0gFloGbmrgQfBzYpd1YjQZbEYARkB6zMwO2SHSAAlZlYIBCdtCRkZpHIrFYahQYQD8UYYFA5EhcfjyGYqHAXnJAsIUHlOOUbHYhMIIHJzsI0Qk4P9SLUBuRqXEXEwAKKfRZcNA8PiCfxWACecAAUgBlAAacFm80W-CU11U6h4TgwUv11yShjgJjMLMqDnN9Dilq+nh8pD8AXgCHdMrCkWisVoAet0R6fXqhWKhjKllZVVxMcavpd4Zg7U6Qaj+2hmdG4zeRF10uu-Aeq0LBfLMEe-V+T2L7zLVu+FBWLdLeq+lc7DYFf39deFVOotMCACNOCh1dq219a+30uC8YWoZsRyuEdjkevR8uvoVMdjyTWt4WiSSydXD4NqZP4AymeZE072ZzuUeZQKheQgA).

### Style Props[](#typing-style-props "Link for Style Props ")

When using inline styles in React, you can use `React.CSSProperties` to describe the object passed to the `style` prop. This type is a union of all the possible CSS properties, and is a good way to ensure you are passing valid CSS properties to the `style` prop, and to get auto-complete in your editor.

```
interface MyComponentProps {

  style: React.CSSProperties;

}
```

***

----
url: https://react.dev/reference/react/Fragment
----

[API Reference](/reference/react)

[Components](/reference/react/components)

# \<Fragment> (<>...\</>)[](#undefined "Link for this heading")

`<Fragment>`, often used via `<>...</>` syntax, lets you group elements without a wrapper node.

### Canary

Fragments can also accept refs, which enable interacting with underlying DOM nodes without adding wrapper elements.

```
<>

  <OneChild />

  <AnotherChild />

</>
```

* [Reference](#reference)

  * [`<Fragment>`](#fragment)
  * [Canary only `FragmentInstance`](#fragmentinstance)

* [Usage](#usage)

  * [Returning multiple elements](#returning-multiple-elements)
  * [Assigning multiple elements to a variable](#assigning-multiple-elements-to-a-variable)
  * [Grouping elements with text](#grouping-elements-with-text)
  * [Rendering a list of Fragments](#rendering-a-list-of-fragments)
  * [Canary only Adding event listeners without a wrapper element](#adding-event-listeners-without-wrapper)
  * [Canary only Managing focus across a group of elements](#managing-focus-across-elements)
  * [Canary only Scrolling a group of elements into view](#scrolling-group-into-view)
  * [Canary only Observing visibility without a wrapper element](#observing-visibility-without-wrapper)
  * [Canary only Caching a global IntersectionObserver](#caching-global-intersection-observer)

***

## Reference[](#reference "Link for Reference ")

### `<Fragment>`[](#fragment "Link for this heading")

Wrap elements in `<Fragment>` to group them together in situations where you need a single element. Grouping elements in `Fragment` has no effect on the resulting DOM; it is the same as if the elements were not grouped. The empty JSX tag `<></>` is shorthand for `<Fragment></Fragment>` in most cases.

#### Props[](#props "Link for Props ")

* **optional** `key`: Fragments declared with the explicit `<Fragment>` syntax may have [keys.](/learn/rendering-lists#keeping-list-items-in-order-with-key)
* Canary only **optional** `ref`: A ref object (e.g. from [`useRef`](/reference/react/useRef)) or [callback function](/reference/react-dom/components/common#ref-callback). React provides a `FragmentInstance` as the ref value that implements methods for interacting with the DOM nodes wrapped by the Fragment.

#### Caveats[](#caveats "Link for Caveats ")

* If you want to pass `key` to a Fragment, you can’t use the `<>...</>` syntax. You have to explicitly import `Fragment` from `'react'` and render `<Fragment key={yourKey}>...</Fragment>`.

* React does not [reset state](/learn/preserving-and-resetting-state) when you go from rendering `<><Child /></>` to `[<Child />]` or back, or when you go from rendering `<><Child /></>` to `<Child />` and back. This only works a single level deep: for example, going from `<><><Child /></></>` to `<Child />` resets the state. See the precise semantics [here.](https://gist.github.com/clemmy/b3ef00f9507909429d8aa0d3ee4f986b)

* Canary only If you want to pass `ref` to a Fragment, you can’t use the `<>...</>` syntax. You have to explicitly import `Fragment` from `'react'` and render `<Fragment ref={yourRef}>...</Fragment>`.

***

### Canary only `FragmentInstance`[](#fragmentinstance "Link for this heading")

When you pass a `ref` to a Fragment, React provides a `FragmentInstance` object. It implements methods for interacting with the first-level DOM children wrapped by the Fragment.

* [`addEventListener`](#addeventlistener) and [`removeEventListener`](#removeeventlistener) manage event listeners across all first-level DOM children.
* [`dispatchEvent`](#dispatchevent) dispatches an event on the Fragment, which can bubble to the DOM parent.
* [`focus`](#focus), [`focusLast`](#focuslast), and [`blur`](#blur) manage focus across all nested children depth-first.
* [`observeUsing`](#observeusing) and [`unobserveUsing`](#unobserveusing) attach and detach `IntersectionObserver` or `ResizeObserver` instances.
* [`getClientRects`](#getclientrects) returns bounding rectangles of all first-level DOM children.
* [`getRootNode`](#getrootnode) returns the root node of the Fragment’s parent.
* [`compareDocumentPosition`](#comparedocumentposition) compares the Fragment’s position with another node.
* [`scrollIntoView`](#scrollintoview) scrolls the Fragment’s children into view.

***

#### `addEventListener(type, listener, options?)`[](#addeventlistener "Link for this heading")

Adds an event listener to all first-level DOM children of the Fragment.

```
fragmentRef.current.addEventListener('click', handleClick);
```

##### Parameters[](#addeventlistener-parameters "Link for Parameters ")

* `type`: A string representing the event type to listen for (e.g. `'click'`, `'focus'`).
* `listener`: The event handler function.
* **optional** `options`: An options object or boolean for capture, matching the [DOM `addEventListener` API.](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener)

##### Returns[](#addeventlistener-returns "Link for Returns ")

`addEventListener` does not return anything (`undefined`).

***

#### `removeEventListener(type, listener, options?)`[](#removeeventlistener "Link for this heading")

Removes an event listener from all first-level DOM children of the Fragment.

```
fragmentRef.current.removeEventListener('click', handleClick);
```

##### Parameters[](#removeeventlistener-parameters "Link for Parameters ")

* `type`: The event type string.
* `listener`: The event handler function to remove.
* **optional** `options`: An options object or boolean, matching the [DOM `removeEventListener` API.](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/removeEventListener)

##### Returns[](#removeeventlistener-returns "Link for Returns ")

`removeEventListener` does not return anything (`undefined`).

***

#### `dispatchEvent(event)`[](#dispatchevent "Link for this heading")

Dispatches an event on the Fragment. Added event listeners are called, and the event can bubble to the Fragment’s DOM parent.

```
fragmentRef.current.dispatchEvent(new Event('custom', { bubbles: true }));
```

##### Parameters[](#dispatchevent-parameters "Link for Parameters ")

* `event`: An [`Event`](https://developer.mozilla.org/en-US/docs/Web/API/Event) object to dispatch. If `bubbles` is `true`, the event bubbles to the Fragment’s parent DOM node.

##### Returns[](#dispatchevent-returns "Link for Returns ")

`true` if the event was not cancelled, `false` if `preventDefault()` was called.

***

#### `focus(options?)`[](#focus "Link for this heading")

Focuses the first focusable DOM node in the Fragment. Unlike calling `element.focus()` on a DOM element, this method searches *all* nested children depth-first until it finds a focusable element—not just the element itself or its direct children.

```
fragmentRef.current.focus();
```

##### Parameters[](#focus-parameters "Link for Parameters ")

* **optional** `options`: A [`FocusOptions`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus#options) object (e.g. `{ preventScroll: true }`).

##### Returns[](#focus-returns "Link for Returns ")

`focus` does not return anything (`undefined`).

***

#### `focusLast(options?)`[](#focuslast "Link for this heading")

Focuses the last focusable DOM node in the Fragment. Searches nested children depth-first, then iterates in reverse.

```
fragmentRef.current.focusLast();
```

##### Parameters[](#focuslast-parameters "Link for Parameters ")

* **optional** `options`: A [`FocusOptions`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus#options) object.

##### Returns[](#focuslast-returns "Link for Returns ")

`focusLast` does not return anything (`undefined`).

***

#### `blur()`[](#blur "Link for this heading")

Removes focus from the active element if it is within the Fragment. If `document.activeElement` is not within the Fragment, `blur` does nothing.

```
fragmentRef.current.blur();
```

##### Returns[](#blur-returns "Link for Returns ")

`blur` does not return anything (`undefined`).

***

#### `observeUsing(observer)`[](#observeusing "Link for this heading")

Starts observing all first-level DOM children of the Fragment with the provided observer.

```
const observer = new IntersectionObserver(callback, options);

fragmentRef.current.observeUsing(observer);
```

##### Parameters[](#observeusing-parameters "Link for Parameters ")

* `observer`: An [`IntersectionObserver`](https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver) or [`ResizeObserver`](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver) instance.

##### Returns[](#observeusing-returns "Link for Returns ")

`observeUsing` does not return anything (`undefined`).

***

#### `unobserveUsing(observer)`[](#unobserveusing "Link for this heading")

Stops observing the Fragment’s DOM children with the specified observer.

```
fragmentRef.current.unobserveUsing(observer);
```

##### Parameters[](#unobserveusing-parameters "Link for Parameters ")

* `observer`: The same `IntersectionObserver` or `ResizeObserver` instance previously passed to [`observeUsing`](#observeusing).

##### Returns[](#unobserveusing-returns "Link for Returns ")

`unobserveUsing` does not return anything (`undefined`).

***

#### `getClientRects()`[](#getclientrects "Link for this heading")

Returns a flat array of [`DOMRect`](https://developer.mozilla.org/en-US/docs/Web/API/DOMRect) objects representing the bounding rectangles of all first-level DOM children.

```
const rects = fragmentRef.current.getClientRects();
```

##### Returns[](#getclientrects-returns "Link for Returns ")

An `Array<DOMRect>` containing the bounding rectangles of all children.

***

#### `getRootNode(options?)`[](#getrootnode "Link for this heading")

Returns the root node containing the Fragment’s parent DOM node, matching the behavior of [`Node.getRootNode()`](https://developer.mozilla.org/en-US/docs/Web/API/Node/getRootNode).

```
const root = fragmentRef.current.getRootNode();
```

##### Parameters[](#getrootnode-parameters "Link for Parameters ")

* **optional** `options`: An object with a `composed` boolean property, matching the [DOM `getRootNode` API.](https://developer.mozilla.org/en-US/docs/Web/API/Node/getRootNode#options)

##### Returns[](#getrootnode-returns "Link for Returns ")

A `Document`, `ShadowRoot`, or the `FragmentInstance` itself if there is no parent DOM node.

***

#### `compareDocumentPosition(otherNode)`[](#comparedocumentposition "Link for this heading")

Compares the document position of the Fragment with another node, returning a bitmask matching the behavior of [`Node.compareDocumentPosition()`](https://developer.mozilla.org/en-US/docs/Web/API/Node/compareDocumentPosition).

```
const position = fragmentRef.current.compareDocumentPosition(otherElement);
```

##### Parameters[](#comparedocumentposition-parameters "Link for Parameters ")

* `otherNode`: The DOM node to compare against.

##### Returns[](#comparedocumentposition-returns "Link for Returns ")

A bitmask of [position flags](https://developer.mozilla.org/en-US/docs/Web/API/Node/compareDocumentPosition#return_value). Empty Fragments and Fragments with children rendered through a [portal](/reference/react-dom/createPortal) include `Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC` in the result.

***

#### `scrollIntoView(alignToTop?)`[](#scrollintoview "Link for this heading")

Scrolls the Fragment’s children into view. When `alignToTop` is `true` or omitted, scrolls to align the first child with the top of the scrollable ancestor. When `alignToTop` is `false`, scrolls to align the last child with the bottom.

```
fragmentRef.current.scrollIntoView();
```

##### Parameters[](#scrollintoview-parameters "Link for Parameters ")

* **optional** `alignToTop`: A boolean. If `true` (the default), scrolls the first child to the top of the scrollable area. If `false`, scrolls the last child to the bottom. Unlike [`Element.scrollIntoView()`](https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView), this method does not accept a `ScrollIntoViewOptions` object.

##### Returns[](#scrollintoview-returns "Link for Returns ")

`scrollIntoView` does not return anything (`undefined`).

##### Caveats[](#scrollintoview-caveats "Link for Caveats ")

* `scrollIntoView` does not accept an options object. Passing one throws an error. Use the `alignToTop` boolean instead.
* When the Fragment has no children, `scrollIntoView` scrolls the nearest sibling or parent into view as a fallback.

***

#### `FragmentInstance` Caveats[](#fragmentinstance-caveats "Link for this heading")

* Methods that target children (such as `addEventListener`, `observeUsing`, and `getClientRects`) operate on *first-level host (DOM) children* of the Fragment. They do not directly target children nested inside another DOM element.
* `focus` and `focusLast` search nested children depth-first for focusable elements, unlike event and observer methods which only target first-level host children.
* `observeUsing` does not work on text nodes. React logs a warning in development if the Fragment contains only text children.
* React does not apply event listeners added via `addEventListener` to hidden [`<Activity>`](/reference/react/Activity) trees. When an `Activity` boundary switches from hidden to visible, listeners are applied automatically.
* Each first-level DOM child of a Fragment with a `ref` gets a `reactFragments` property—a `Set<FragmentInstance>` containing all Fragment instances that own the element. This enables [caching a shared observer](#caching-global-intersection-observer) across multiple Fragments.

***

## Usage[](#usage "Link for Usage ")

### Returning multiple elements[](#returning-multiple-elements "Link for Returning multiple elements ")

Use `Fragment`, or the equivalent `<>...</>` syntax, to group multiple elements together. You can use it to put multiple elements in any place where a single element can go. For example, a component can only return one element, but by using a Fragment you can group multiple elements together and then return them as a group:

```
function Post() {

  return (

    <>

      <PostTitle />

      <PostBody />

    </>

  );

}
```

Fragments are useful because grouping elements with a Fragment has no effect on layout or styles, unlike if you wrapped the elements in another container like a DOM element. If you inspect this example with the browser tools, you’ll see that all `<h1>` and `<article>` DOM nodes appear as siblings without wrappers around them:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
export default function Blog() {
  return (
    <>
      <Post title="An update" body="It's been a while since I posted..." />
      <Post title="My new blog" body="I am starting a new blog!" />
    </>
  )
}

function Post({ title, body }) {
  return (
    <>
      <PostTitle title={title} />
      <PostBody body={body} />
    </>
  );
}

function PostTitle({ title }) {
  return <h1>{title}</h1>
}

function PostBody({ body }) {
  return (
    <article>
      <p>{body}</p>
    </article>
  );
}
```

##### Deep Dive#### How to write a Fragment without the special syntax?[](#how-to-write-a-fragment-without-the-special-syntax "Link for How to write a Fragment without the special syntax? ")

The example above is equivalent to importing `Fragment` from React:

```
import { Fragment } from 'react';



function Post() {

  return (

    <Fragment>

      <PostTitle />

      <PostBody />

    </Fragment>

  );

}
```

Usually you won’t need this unless you need to [pass a `key` to your `Fragment`.](#rendering-a-list-of-fragments)

***

### Assigning multiple elements to a variable[](#assigning-multiple-elements-to-a-variable "Link for Assigning multiple elements to a variable ")

Like any other element, you can assign Fragment elements to variables, pass them as props, and so on:

```
function CloseDialog() {

  const buttons = (

    <>

      <OKButton />

      <CancelButton />

    </>

  );

  return (

    <AlertDialog buttons={buttons}>

      Are you sure you want to leave this page?

    </AlertDialog>

  );

}
```

***

### Grouping elements with text[](#grouping-elements-with-text "Link for Grouping elements with text ")

You can use `Fragment` to group text together with components:

```
function DateRangePicker({ start, end }) {

  return (

    <>

      From

      <DatePicker date={start} />

      to

      <DatePicker date={end} />

    </>

  );

}
```

***

### Rendering a list of Fragments[](#rendering-a-list-of-fragments "Link for Rendering a list of Fragments ")

Here’s a situation where you need to write `Fragment` explicitly instead of using the `<></>` syntax. When you [render multiple elements in a loop](/learn/rendering-lists), you need to assign a `key` to each element. If the elements within the loop are Fragments, you need to use the normal JSX element syntax in order to provide the `key` attribute:

```
function Blog() {

  return posts.map(post =>

    <Fragment key={post.id}>

      <PostTitle title={post.title} />

      <PostBody body={post.body} />

    </Fragment>

  );

}
```

You can inspect the DOM to verify that there are no wrapper elements around the Fragment children:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { Fragment } from 'react';

const posts = [
  { id: 1, title: 'An update', body: "It's been a while since I posted..." },
  { id: 2, title: 'My new blog', body: 'I am starting a new blog!' }
];

export default function Blog() {
  return posts.map(post =>
    <Fragment key={post.id}>
      <PostTitle title={post.title} />
      <PostBody body={post.body} />
    </Fragment>
  );
}

function PostTitle({ title }) {
  return <h1>{title}</h1>
}

function PostBody({ body }) {
  return (
    <article>
      <p>{body}</p>
    </article>
  );
}
```

***

### Canary only Adding event listeners without a wrapper element[](#adding-event-listeners-without-wrapper "Link for this heading")

Fragment `ref`s let you add event listeners to a group of elements without adding a wrapper DOM node. Use a [ref callback](/reference/react-dom/components/common#ref-callback) to attach and clean up listeners:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { Fragment, useState, useRef, useEffect } from 'react';

function ClickableFragment({ children, onClick }) {
  const fragmentRef = useRef(null);
  useEffect(() => {
    const fragmentInstance = fragmentRef.current;
    if (fragmentInstance === null) {
      return;
    }
    fragmentInstance.addEventListener('click', onClick);
    return () => {
      fragmentInstance.removeEventListener(
        'click',
        onClick
      );
    };
  }, [onClick])
  return (
    <Fragment ref={fragmentRef}>
      {children}
    </Fragment>
  );
}

export default function App() {
  const [clicks, setClicks] = useState(0);

  return (
    <>
      <p>Total clicks: {clicks}</p>
      <ClickableFragment onClick={() => {
        setClicks(c => c + 1);
      }}>
        <button>Button A</button>
        <button>Button B</button>
        <button>Button C</button>
      </ClickableFragment>
    </>
  );
}
```

The `addEventListener` call applies the listener to every first-level DOM child of the Fragment. When children are dynamically added or removed, the `FragmentInstance` automatically adds or removes the listener.

##### Deep Dive#### Which children does a Fragment ref target?[](#which-children-does-a-fragment-ref-target "Link for Which children does a Fragment ref target? ")

A `FragmentInstance` targets the **first-level host (DOM) children** of the Fragment. Consider this tree:

```
<Fragment ref={ref}>

  <div id="A" />

  <Wrapper>

    <div id="B">

      <div id="C" />

    </div>

  </Wrapper>

  <div id="D" />

</Fragment>
```

`Wrapper` is a React component, so the `FragmentInstance` looks through it to find DOM nodes. The targeted children are `A`, `B`, and `D`. `C` is not targeted because it is nested inside the DOM element `B`.

Methods like `addEventListener`, `observeUsing`, and `getClientRects` operate on these first-level DOM children. `focus` and `focusLast` are different—they search *all* nested children depth-first to find focusable elements.

***

### Canary only Managing focus across a group of elements[](#managing-focus-across-elements "Link for this heading")

Fragment `ref`s provide `focus`, `focusLast`, and `blur` methods that operate across all DOM nodes within the Fragment:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { Fragment, useRef } from 'react';

function FormFields({ children }) {
  const fragmentRef = useRef(null);

  return (
    <>
      <div className="buttons">
        <button onClick={() => {
          fragmentRef.current.focus();
        }}>
          Focus first
        </button>
        <button onClick={() => {
          fragmentRef.current.focusLast();
        }}>
          Focus last
        </button>
        <button onClick={() => {
          fragmentRef.current.blur();
        }}>
          Blur
        </button>
      </div>
      <Fragment ref={fragmentRef}>
        {children}
      </Fragment>
    </>
  );
}

// Even though the inputs are deeply nested,
// focus() searches depth-first to find them.
export default function App() {
  return (
    <FormFields>
      <fieldset>
        <legend>Shipping</legend>
        <label>
          Street: <input name="street" />
        </label>
        <label>
          City: <input name="city" />
        </label>
      </fieldset>
    </FormFields>
  );
}
```

Calling `focus()` focuses the `street` input—even though it is nested inside a `<fieldset>` and `<label>`. `focus()` searches depth-first through all nested children, not just direct children of the Fragment. `focusLast()` does the same in reverse, and `blur()` removes focus if the currently focused element is within the Fragment.

***

### Canary only Scrolling a group of elements into view[](#scrolling-group-into-view "Link for this heading")

Use `scrollIntoView` to scroll a Fragment’s children into view without a wrapper element. Pass `true` (or omit the argument) to scroll the first child to the top. Pass `false` to scroll the last child to the bottom:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { Fragment, useRef } from 'react';

function ScrollableSection({ children }) {
  const fragmentRef = useRef(null);

  return (
    <>
      <div className="buttons">
        <button onClick={() => {
          fragmentRef.current.scrollIntoView();
        }}>
          Scroll to top
        </button>
        <button onClick={() => {
          fragmentRef.current.scrollIntoView(false);
        }}>
          Scroll to bottom
        </button>
      </div>
      <div className="container">
        <Fragment ref={fragmentRef}>
          {children}
        </Fragment>
      </div>
    </>
  );
}

const items = [];
for (let i = 1; i <= 25; i++) {
  items.push('Item ' + i);
}

export default function App() {
  return (
    <ScrollableSection>
      <h3>Section Start</h3>
      {items.map((item) => (
        <p key={item}>{item}</p>
      ))}
      <h3>Section End</h3>
    </ScrollableSection>
  );
}
```

***

### Canary only Observing visibility without a wrapper element[](#observing-visibility-without-wrapper "Link for this heading")

Use `observeUsing` to attach an `IntersectionObserver` to all first-level DOM children of a Fragment. This lets you track visibility without requiring child components to expose `ref`s or adding a wrapper element:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import {
  Fragment,
  useRef,
  useLayoutEffect,
  useState,
} from 'react';
import Card from './Card';

function VisibleGroup({ onVisibilityChange, children }) {
  const fragmentRef = useRef(null);

  useLayoutEffect(() => {
    const visibleElements = new Set();
    const observer = new IntersectionObserver(
      (entries) => {
        entries.forEach(e => {
          if (e.isIntersecting) {
            visibleElements.add(e.target);
          } else {
            visibleElements.delete(e.target);
          }
        });
        onVisibilityChange(visibleElements.size > 0);
      }
    );
    const fragmentInstance = fragmentRef.current;
    fragmentInstance.observeUsing(observer);
    return () => {
      fragmentInstance.unobserveUsing(observer);
    };
  }, [onVisibilityChange]);

  return (
    <Fragment ref={fragmentRef}>
      {children}
    </Fragment>
  );
}

export default function App() {
  const [isVisible, setIsVisible] = useState(true);

  return (
    <div className={isVisible ? 'page visible' : 'page'}>
      <div className="filler">Scroll down</div>
      <VisibleGroup onVisibilityChange={setIsVisible}>
        <Card title="First section" />
        <Card title="Second section" />
      </VisibleGroup>
      <div className="filler">Scroll up</div>
    </div>
  );
}
```

***

### Canary only Caching a global IntersectionObserver[](#caching-global-intersection-observer "Link for this heading")

A common performance optimization for sites with many observers is to share a single IntersectionObserver per config and route its entries to the correct callbacks based on which element intersected. Fragment `ref`s support this same pattern through the `reactFragments` property.

Each first-level DOM child of a Fragment with a `ref` has a `reactFragments` property: a `Set` of `FragmentInstance` objects that contain that element. When the shared observer fires, you can use this property to look up which `FragmentInstance` owns the intersecting element and run the right callbacks.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useCallback } from 'react';
import ObservedGroup from './ObservedGroup';
import Card from './Card';

export default function App() {
  const [bgColor, setBgColor] = useState(null);

  const onGreen = useCallback((entry) => {
    if (entry.isIntersecting) {
      setBgColor('#d4edda');
    }
  }, []);

  const onBlue = useCallback((entry) => {
    if (entry.isIntersecting) {
      setBgColor('#cce5ff');
    }
  }, []);

  return (
    <div className="page" style={{
      background: bgColor || 'white',
    }}>
      <div className="filler">Scroll down</div>
      <ObservedGroup onIntersection={onGreen}>
        <Card title="Green section" className="green" />
      </ObservedGroup>
      <div className="filler" />
      <ObservedGroup onIntersection={onBlue}>
        <Card title="Blue section" className="blue" />
      </ObservedGroup>
      <div className="filler">Scroll up</div>
    </div>
  );
}
```

Multiple `ObservedGroup` components with the same options reuse a single `IntersectionObserver`. When either section scrolls into view, the shared observer fires and uses `reactFragments` to route the entry to the correct callback.

[PreviousComponents](/reference/react/components)

[Next\<Profiler>](/reference/react/Profiler)

***

----
url: https://18.react.dev/reference/react/experimental_taintUniqueValue
----

[API Reference](/reference/react)

[APIs](/reference/react/apis)

# experimental\_taintUniqueValue[](#undefined "Link for this heading")

### Under Construction

```
taintUniqueValue(errMessage, lifetime, value)
```

To prevent passing an object containing sensitive data, see [`taintObjectReference`](/reference/react/experimental_taintObjectReference).

* [Reference](#reference)
  * [`taintUniqueValue(message, lifetime, value)`](#taintuniquevalue)
* [Usage](#usage)
  * [Prevent a token from being passed to Client Components](#prevent-a-token-from-being-passed-to-client-components)

***

## Reference[](#reference "Link for Reference ")

### `taintUniqueValue(message, lifetime, value)`[](#taintuniquevalue "Link for this heading")

Call `taintUniqueValue` with a password, token, key or hash to register it with React as something that should not be allowed to be passed to the Client as is:

```
import {experimental_taintUniqueValue} from 'react';



experimental_taintUniqueValue(

  'Do not pass secret keys to the client.',

  process,

  process.env.SECRET_KEY

);
```

***

## Usage[](#usage "Link for Usage ")

### Prevent a token from being passed to Client Components[](#prevent-a-token-from-being-passed-to-client-components "Link for Prevent a token from being passed to Client Components ")

To ensure that sensitive information such as passwords, session tokens, or other unique values do not inadvertently get passed to Client Components, the `taintUniqueValue` function provides a layer of protection. When a value is tainted, any attempt to pass it to a Client Component will result in an error.

The `lifetime` argument defines the duration for which the value remains tainted. For values that should remain tainted indefinitely, objects like [`globalThis`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/globalThis) or `process` can serve as the `lifetime` argument. These objects have a lifespan that spans the entire duration of your app’s execution.

```
import {experimental_taintUniqueValue} from 'react';



experimental_taintUniqueValue(

  'Do not pass a user password to the client.',

  globalThis,

  process.env.SECRET_KEY

);
```

If the tainted value’s lifespan is tied to a object, the `lifetime` should be the object that encapsulates the value. This ensures the tainted value remains protected for the lifetime of the encapsulating object.

```
import {experimental_taintUniqueValue} from 'react';



export async function getUser(id) {

  const user = await db`SELECT * FROM users WHERE id = ${id}`;

  experimental_taintUniqueValue(

    'Do not pass a user session token to the client.',

    user,

    user.session.token

  );

  return user;

}
```

In this example, the `user` object serves as the `lifetime` argument. If this object gets stored in a global cache or is accessible by another request, the session token remains tainted.

### Pitfall

**Do not rely solely on tainting for security.** Tainting a value doesn’t block every possible derived value. For example, creating a new value by upper casing a tainted string will not taint the new value.

```
import {experimental_taintUniqueValue} from 'react';



const password = 'correct horse battery staple';



experimental_taintUniqueValue(

  'Do not pass the password to the client.',

  globalThis,

  password

);



const uppercasePassword = password.toUpperCase() // `uppercasePassword` is not tainted
```

In this example, the constant `password` is tainted. Then `password` is used to create a new value `uppercasePassword` by calling the `toUpperCase` method on `password`. The newly created `uppercasePassword` is not tainted.

Other similar ways of deriving new values from tainted values like concatenating it into a larger string, converting it to base64, or returning a substring create untained values.

Tainting only protects against simple mistakes like explicitly passing secret values to the client. Mistakes in calling the `taintUniqueValue` like using a global store outside of React, without the corresponding lifetime object, can cause the tainted value to become untainted. Tainting is a layer of protection; a secure app will have multiple layers of protection, well designed APIs, and isolation patterns.

##### Deep Dive#### Using `server-only` and `taintUniqueValue` to prevent leaking secrets[](#using-server-only-and-taintuniquevalue-to-prevent-leaking-secrets "Link for this heading")

If you’re running a Server Components environment that has access to private keys or passwords such as database passwords, you have to be careful not to pass that to a Client Component.

```
export async function Dashboard(props) {

  // DO NOT DO THIS

  return <Overview password={process.env.API_PASSWORD} />;

}
```

```
"use client";



import {useEffect} from '...'



export async function Overview({ password }) {

  useEffect(() => {

    const headers = { Authorization: password };

    fetch(url, { headers }).then(...);

  }, [password]);

  ...

}
```

This example would leak the secret API token to the client. If this API token can be used to access data this particular user shouldn’t have access to, it could lead to a data breach.

Ideally, secrets like this are abstracted into a single helper file that can only be imported by trusted data utilities on the server. The helper can even be tagged with [`server-only`](https://www.npmjs.com/package/server-only) to ensure that this file isn’t imported on the client.

```
import "server-only";



export function fetchAPI(url) {

  const headers = { Authorization: process.env.API_PASSWORD };

  return fetch(url, { headers });

}
```

Sometimes mistakes happen during refactoring and not all of your colleagues might know about this. To protect against this mistakes happening down the line we can “taint” the actual password:

```
import "server-only";

import {experimental_taintUniqueValue} from 'react';



experimental_taintUniqueValue(

  'Do not pass the API token password to the client. ' +

    'Instead do all fetches on the server.'

  process,

  process.env.API_PASSWORD

);
```

Now whenever anyone tries to pass this password to a Client Component, or send the password to a Client Component with a Server Action, an error will be thrown with message you defined when you called `taintUniqueValue`.

***

[Previousexperimental\_taintObjectReference](/reference/react/experimental_taintObjectReference)

***

----
url: https://legacy.reactjs.org/docs/react-component.html
----

> These docs are old and won’t be updated. Go to [react.dev](https://react.dev/) for the new React docs.
>
> These new documentation pages teach modern React:
>
> * [`React.Component`](https://react.dev/reference/react/Component)

This page contains a detailed API reference for the React component class definition. It assumes you’re familiar with fundamental React concepts, such as [Components and Props](/docs/components-and-props.html), as well as [State and Lifecycle](/docs/state-and-lifecycle.html). If you’re not, read them first.

## [](#overview)Overview

React lets you define components as classes or functions. Components defined as classes currently provide more features which are described in detail on this page. To define a React component class, you need to extend `React.Component`:

```
class Welcome extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}
```

The only method you *must* define in a `React.Component` subclass is called [`render()`](#render). All the other methods described on this page are optional.

**We strongly recommend against creating your own base component classes.** In React components, [code reuse is primarily achieved through composition rather than inheritance](/docs/composition-vs-inheritance.html).

> Note:
>
> React doesn’t force you to use the ES6 class syntax. If you prefer to avoid it, you may use the `create-react-class` module or a similar custom abstraction instead. Take a look at [Using React without ES6](/docs/react-without-es6.html) to learn more.

### [](#the-component-lifecycle)The Component Lifecycle

Each component has several “lifecycle methods” that you can override to run code at particular times in the process. **You can use [this lifecycle diagram](https://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/) as a cheat sheet.** In the list below, commonly used lifecycle methods are marked as **bold**. The rest of them exist for relatively rare use cases.

#### [](#mounting)Mounting

These methods are called in the following order when an instance of a component is being created and inserted into the DOM:

* [**`constructor()`**](#constructor)
* [`static getDerivedStateFromProps()`](#static-getderivedstatefromprops)
* [**`render()`**](#render)
* [**`componentDidMount()`**](#componentdidmount)

> Note:
>
> This method is considered legacy and you should [avoid it](/blog/2018/03/27/update-on-async-rendering.html) in new code:
>
> * [`UNSAFE_componentWillMount()`](#unsafe_componentwillmount)

#### [](#updating)Updating

An update can be caused by changes to props or state. These methods are called in the following order when a component is being re-rendered:

* [`static getDerivedStateFromProps()`](#static-getderivedstatefromprops)
* [`shouldComponentUpdate()`](#shouldcomponentupdate)
* [**`render()`**](#render)
* [`getSnapshotBeforeUpdate()`](#getsnapshotbeforeupdate)
* [**`componentDidUpdate()`**](#componentdidupdate)

> Note:
>
> These methods are considered legacy and you should [avoid them](/blog/2018/03/27/update-on-async-rendering.html) in new code:
>
> * [`UNSAFE_componentWillUpdate()`](#unsafe_componentwillupdate)
> * [`UNSAFE_componentWillReceiveProps()`](#unsafe_componentwillreceiveprops)

#### [](#unmounting)Unmounting

This method is called when a component is being removed from the DOM:

* [**`componentWillUnmount()`**](#componentwillunmount)

#### [](#error-handling)Error Handling

These methods are called when there is an error during rendering, in a lifecycle method, or in the constructor of any child component.

* [`static getDerivedStateFromError()`](#static-getderivedstatefromerror)
* [`componentDidCatch()`](#componentdidcatch)

### [](#other-apis)Other APIs

Each component also provides some other APIs:

* [`setState()`](#setstate)
* [`forceUpdate()`](#forceupdate)

### [](#class-properties)Class Properties

* [`defaultProps`](#defaultprops)
* [`displayName`](#displayname)

### [](#instance-properties)Instance Properties

* [`props`](#props)
* [`state`](#state)

***

## [](#reference)Reference

### [](#commonly-used-lifecycle-methods)Commonly Used Lifecycle Methods

The methods in this section cover the vast majority of use cases you’ll encounter creating React components. **For a visual reference, check out [this lifecycle diagram](https://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/).**

### [](#render)`render()`

```
render()
```

The `render()` method is the only required method in a class component.

When called, it should examine `this.props` and `this.state` and return one of the following types:

* **React elements.** Typically created via [JSX](/docs/introducing-jsx.html). For example, `<div />` and `<MyComponent />` are React elements that instruct React to render a DOM node, or another user-defined component, respectively.
* **Arrays and fragments.** Let you return multiple elements from render. See the documentation on [fragments](/docs/fragments.html) for more details.
* **Portals**. Let you render children into a different DOM subtree. See the documentation on [portals](/docs/portals.html) for more details.
* **String and numbers.** These are rendered as text nodes in the DOM.
* **Booleans or `null` or `undefined`**. Render nothing. (Mostly exists to support `return test && <Child />` pattern, where `test` is boolean).

The `render()` function should be pure, meaning that it does not modify component state, it returns the same result each time it’s invoked, and it does not directly interact with the browser.

If you need to interact with the browser, perform your work in `componentDidMount()` or the other lifecycle methods instead. Keeping `render()` pure makes components easier to think about.

> Note
>
> `render()` will not be invoked if [`shouldComponentUpdate()`](#shouldcomponentupdate) returns false.

***

### [](#constructor)`constructor()`

```
constructor(props)
```

**If you don’t initialize state and you don’t bind methods, you don’t need to implement a constructor for your React component.**

The constructor for a React component is called before it is mounted. When implementing the constructor for a `React.Component` subclass, you should call `super(props)` before any other statement. Otherwise, `this.props` will be undefined in the constructor, which can lead to bugs.

Typically, in React constructors are only used for two purposes:

* Initializing [local state](/docs/state-and-lifecycle.html) by assigning an object to `this.state`.
* Binding [event handler](/docs/handling-events.html) methods to an instance.

You **should not call `setState()`** in the `constructor()`. Instead, if your component needs to use local state, **assign the initial state to `this.state`** directly in the constructor:

```
constructor(props) {
  super(props);
  // Don't call this.setState() here!
  this.state = { counter: 0 };
  this.handleClick = this.handleClick.bind(this);
}
```

Constructor is the only place where you should assign `this.state` directly. In all other methods, you need to use `this.setState()` instead.

Avoid introducing any side-effects or subscriptions in the constructor. For those use cases, use `componentDidMount()` instead.

> Note
>
> **Avoid copying props into state! This is a common mistake:**
>
> ```
> constructor(props) {
>  super(props);
>  // Don't do this!
>  this.state = { color: props.color };
> }
> ```
>
> The problem is that it’s both unnecessary (you can use `this.props.color` directly instead), and creates bugs (updates to the `color` prop won’t be reflected in the state).
>
> **Only use this pattern if you intentionally want to ignore prop updates.** In that case, it makes sense to rename the prop to be called `initialColor` or `defaultColor`. You can then force a component to “reset” its internal state by [changing its `key`](/blog/2018/06/07/you-probably-dont-need-derived-state.html#recommendation-fully-uncontrolled-component-with-a-key) when necessary.
>
> Read our [blog post on avoiding derived state](/blog/2018/06/07/you-probably-dont-need-derived-state.html) to learn about what to do if you think you need some state to depend on the props.

***

### [](#componentdidmount)`componentDidMount()`

```
componentDidMount()
```

`componentDidMount()` is invoked immediately after a component is mounted (inserted into the tree). Initialization that requires DOM nodes should go here. If you need to load data from a remote endpoint, this is a good place to instantiate the network request.

This method is a good place to set up any subscriptions. If you do that, don’t forget to unsubscribe in `componentWillUnmount()`.

You **may call `setState()` immediately** in `componentDidMount()`. It will trigger an extra rendering, but it will happen before the browser updates the screen. This guarantees that even though the `render()` will be called twice in this case, the user won’t see the intermediate state. Use this pattern with caution because it often causes performance issues. In most cases, you should be able to assign the initial state in the `constructor()` instead. It can, however, be necessary for cases like modals and tooltips when you need to measure a DOM node before rendering something that depends on its size or position.

***

### [](#componentdidupdate)`componentDidUpdate()`

```
componentDidUpdate(prevProps, prevState, snapshot)
```

`componentDidUpdate()` is invoked immediately after updating occurs. This method is not called for the initial render.

Use this as an opportunity to operate on the DOM when the component has been updated. This is also a good place to do network requests as long as you compare the current props to previous props (e.g. a network request may not be necessary if the props have not changed).

```
componentDidUpdate(prevProps) {
  // Typical usage (don't forget to compare props):
  if (this.props.userID !== prevProps.userID) {
    this.fetchData(this.props.userID);
  }
}
```

You **may call `setState()` immediately** in `componentDidUpdate()` but note that **it must be wrapped in a condition** like in the example above, or you’ll cause an infinite loop. It would also cause an extra re-rendering which, while not visible to the user, can affect the component performance. If you’re trying to “mirror” some state to a prop coming from above, consider using the prop directly instead. Read more about [why copying props into state causes bugs](/blog/2018/06/07/you-probably-dont-need-derived-state.html).

If your component implements the `getSnapshotBeforeUpdate()` lifecycle (which is rare), the value it returns will be passed as a third “snapshot” parameter to `componentDidUpdate()`. Otherwise this parameter will be undefined.

> Note
>
> `componentDidUpdate()` will not be invoked if [`shouldComponentUpdate()`](#shouldcomponentupdate) returns false.

***

### [](#componentwillunmount)`componentWillUnmount()`

```
componentWillUnmount()
```

`componentWillUnmount()` is invoked immediately before a component is unmounted and destroyed. Perform any necessary cleanup in this method, such as invalidating timers, canceling network requests, or cleaning up any subscriptions that were created in `componentDidMount()`.

You **should not call `setState()`** in `componentWillUnmount()` because the component will never be re-rendered. Once a component instance is unmounted, it will never be mounted again.

***

### [](#rarely-used-lifecycle-methods)Rarely Used Lifecycle Methods

The methods in this section correspond to uncommon use cases. They’re handy once in a while, but most of your components probably don’t need any of them. **You can see most of the methods below on [this lifecycle diagram](https://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/) if you click the “Show less common lifecycles” checkbox at the top of it.**

### [](#shouldcomponentupdate)`shouldComponentUpdate()`

```
shouldComponentUpdate(nextProps, nextState)
```

Use `shouldComponentUpdate()` to let React know if a component’s output is not affected by the current change in state or props. The default behavior is to re-render on every state change, and in the vast majority of cases you should rely on the default behavior.

`shouldComponentUpdate()` is invoked before rendering when new props or state are being received. Defaults to `true`. This method is not called for the initial render or when `forceUpdate()` is used.

This method only exists as a **[performance optimization](/docs/optimizing-performance.html).** Do not rely on it to “prevent” a rendering, as this can lead to bugs. **Consider using the built-in [`PureComponent`](/docs/react-api.html#reactpurecomponent)** instead of writing `shouldComponentUpdate()` by hand. `PureComponent` performs a shallow comparison of props and state, and reduces the chance that you’ll skip a necessary update.

If you are confident you want to write it by hand, you may compare `this.props` with `nextProps` and `this.state` with `nextState` and return `false` to tell React the update can be skipped. Note that returning `false` does not prevent child components from re-rendering when *their* state changes.

We do not recommend doing deep equality checks or using `JSON.stringify()` in `shouldComponentUpdate()`. It is very inefficient and will harm performance.

Currently, if `shouldComponentUpdate()` returns `false`, then [`UNSAFE_componentWillUpdate()`](#unsafe_componentwillupdate), [`render()`](#render), and [`componentDidUpdate()`](#componentdidupdate) will not be invoked. In the future React may treat `shouldComponentUpdate()` as a hint rather than a strict directive, and returning `false` may still result in a re-rendering of the component.

***

### [](#static-getderivedstatefromprops)`static getDerivedStateFromProps()`

```
static getDerivedStateFromProps(props, state)
```

`getDerivedStateFromProps` is invoked right before calling the render method, both on the initial mount and on subsequent updates. It should return an object to update the state, or `null` to update nothing.

This method exists for [rare use cases](/blog/2018/06/07/you-probably-dont-need-derived-state.html#when-to-use-derived-state) where the state depends on changes in props over time. For example, it might be handy for implementing a `<Transition>` component that compares its previous and next children to decide which of them to animate in and out.

Deriving state leads to verbose code and makes your components difficult to think about. [Make sure you’re familiar with simpler alternatives:](/blog/2018/06/07/you-probably-dont-need-derived-state.html)

* If you need to **perform a side effect** (for example, data fetching or an animation) in response to a change in props, use [`componentDidUpdate`](#componentdidupdate) lifecycle instead.
* If you want to **re-compute some data only when a prop changes**, [use a memoization helper instead](/blog/2018/06/07/you-probably-dont-need-derived-state.html#what-about-memoization).
* If you want to **“reset” some state when a prop changes**, consider either making a component [fully controlled](/blog/2018/06/07/you-probably-dont-need-derived-state.html#recommendation-fully-controlled-component) or [fully uncontrolled with a `key`](/blog/2018/06/07/you-probably-dont-need-derived-state.html#recommendation-fully-uncontrolled-component-with-a-key) instead.

This method doesn’t have access to the component instance. If you’d like, you can reuse some code between `getDerivedStateFromProps()` and the other class methods by extracting pure functions of the component props and state outside the class definition.

Note that this method is fired on *every* render, regardless of the cause. This is in contrast to `UNSAFE_componentWillReceiveProps`, which only fires when the parent causes a re-render and not as a result of a local `setState`.

***

### [](#getsnapshotbeforeupdate)`getSnapshotBeforeUpdate()`

```
getSnapshotBeforeUpdate(prevProps, prevState)
```

`getSnapshotBeforeUpdate()` is invoked right before the most recently rendered output is committed to e.g. the DOM. It enables your component to capture some information from the DOM (e.g. scroll position) before it is potentially changed. Any value returned by this lifecycle method will be passed as a parameter to `componentDidUpdate()`.

This use case is not common, but it may occur in UIs like a chat thread that need to handle scroll position in a special way.

A snapshot value (or `null`) should be returned.

For example:

```
class ScrollingList extends React.Component {
  constructor(props) {
    super(props);
    this.listRef = React.createRef();
  }

  getSnapshotBeforeUpdate(prevProps, prevState) {
    // Are we adding new items to the list?
    // Capture the scroll position so we can adjust scroll later.
    if (prevProps.list.length < this.props.list.length) {
      const list = this.listRef.current;
      return list.scrollHeight - list.scrollTop;
    }
    return null;
  }

  componentDidUpdate(prevProps, prevState, snapshot) {
    // If we have a snapshot value, we've just added new items.
    // Adjust scroll so these new items don't push the old ones out of view.
    // (snapshot here is the value returned from getSnapshotBeforeUpdate)
    if (snapshot !== null) {
      const list = this.listRef.current;
      list.scrollTop = list.scrollHeight - snapshot;
    }
  }

  render() {
    return (
      <div ref={this.listRef}>{/* ...contents... */}</div>
    );
  }
}
```

In the above examples, it is important to read the `scrollHeight` property in `getSnapshotBeforeUpdate` because there may be delays between “render” phase lifecycles (like `render`) and “commit” phase lifecycles (like `getSnapshotBeforeUpdate` and `componentDidUpdate`).

***

### [](#error-boundaries)Error boundaries

[Error boundaries](/docs/error-boundaries.html) are React components that catch JavaScript errors anywhere in their child component tree, log those errors, and display a fallback UI instead of the component tree that crashed. Error boundaries catch errors during rendering, in lifecycle methods, and in constructors of the whole tree below them.

A class component becomes an error boundary if it defines either (or both) of the lifecycle methods `static getDerivedStateFromError()` or `componentDidCatch()`. Updating state from these lifecycles lets you capture an unhandled JavaScript error in the below tree and display a fallback UI.

Only use error boundaries for recovering from unexpected exceptions; **don’t try to use them for control flow.**

For more details, see [*Error Handling in React 16*](/blog/2017/07/26/error-handling-in-react-16.html).

> Note
>
> Error boundaries only catch errors in the components **below** them in the tree. An error boundary can’t catch an error within itself.

### [](#static-getderivedstatefromerror)`static getDerivedStateFromError()`

```
static getDerivedStateFromError(error)
```

This lifecycle is invoked after an error has been thrown by a descendant component. It receives the error that was thrown as a parameter and should return a value to update state.

```
class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error) {    // Update state so the next render will show the fallback UI.    return { hasError: true };  }
  render() {
    if (this.state.hasError) {      // You can render any custom fallback UI      return <h1>Something went wrong.</h1>;    }
    return this.props.children;
  }
}
```

> Note
>
> `getDerivedStateFromError()` is called during the “render” phase, so side-effects are not permitted. For those use cases, use `componentDidCatch()` instead.

***

### [](#componentdidcatch)`componentDidCatch()`

```
componentDidCatch(error, info)
```

This lifecycle is invoked after an error has been thrown by a descendant component. It receives two parameters:

1. `error` - The error that was thrown.
2. `info` - An object with a `componentStack` key containing [information about which component threw the error](/docs/error-boundaries.html#component-stack-traces).

`componentDidCatch()` is called during the “commit” phase, so side-effects are permitted. It should be used for things like logging errors:

```
class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error) {
    // Update state so the next render will show the fallback UI.
    return { hasError: true };
  }

  componentDidCatch(error, info) {    // Example "componentStack":    //   in ComponentThatThrows (created by App)    //   in ErrorBoundary (created by App)    //   in div (created by App)    //   in App    logComponentStackToMyService(info.componentStack);  }
  render() {
    if (this.state.hasError) {
      // You can render any custom fallback UI
      return <h1>Something went wrong.</h1>;
    }

    return this.props.children;
  }
}
```

Production and development builds of React slightly differ in the way `componentDidCatch()` handles errors.

On development, the errors will bubble up to `window`, this means that any `window.onerror` or `window.addEventListener('error', callback)` will intercept the errors that have been caught by `componentDidCatch()`.

On production, instead, the errors will not bubble up, which means any ancestor error handler will only receive errors not explicitly caught by `componentDidCatch()`.

> Note
>
> In the event of an error, you can render a fallback UI with `componentDidCatch()` by calling `setState`, but this will be deprecated in a future release. Use `static getDerivedStateFromError()` to handle fallback rendering instead.

***

### [](#legacy-lifecycle-methods)Legacy Lifecycle Methods

The lifecycle methods below are marked as “legacy”. They still work, but we don’t recommend using them in the new code. You can learn more about migrating away from legacy lifecycle methods in [this blog post](/blog/2018/03/27/update-on-async-rendering.html).

### [](#unsafe_componentwillmount)`UNSAFE_componentWillMount()`

```
UNSAFE_componentWillMount()
```

> Note
>
> This lifecycle was previously named `componentWillMount`. That name will continue to work until version 17. Use the [`rename-unsafe-lifecycles` codemod](https://github.com/reactjs/react-codemod#rename-unsafe-lifecycles) to automatically update your components.

`UNSAFE_componentWillMount()` is invoked just before mounting occurs. It is called before `render()`, therefore calling `setState()` synchronously in this method will not trigger an extra rendering. Generally, we recommend using the `constructor()` instead for initializing state.

Avoid introducing any side-effects or subscriptions in this method. For those use cases, use `componentDidMount()` instead.

This is the only lifecycle method called on server rendering.

***

### [](#unsafe_componentwillreceiveprops)`UNSAFE_componentWillReceiveProps()`

```
UNSAFE_componentWillReceiveProps(nextProps)
```

> Note
>
> This lifecycle was previously named `componentWillReceiveProps`. That name will continue to work until version 17. Use the [`rename-unsafe-lifecycles` codemod](https://github.com/reactjs/react-codemod#rename-unsafe-lifecycles) to automatically update your components.

> Note:
>
> Using this lifecycle method often leads to bugs and inconsistencies
>
> * If you need to **perform a side effect** (for example, data fetching or an animation) in response to a change in props, use [`componentDidUpdate`](#componentdidupdate) lifecycle instead.
> * If you used `componentWillReceiveProps` for **re-computing some data only when a prop changes**, [use a memoization helper instead](/blog/2018/06/07/you-probably-dont-need-derived-state.html#what-about-memoization).
> * If you used `componentWillReceiveProps` to **“reset” some state when a prop changes**, consider either making a component [fully controlled](/blog/2018/06/07/you-probably-dont-need-derived-state.html#recommendation-fully-controlled-component) or [fully uncontrolled with a `key`](/blog/2018/06/07/you-probably-dont-need-derived-state.html#recommendation-fully-uncontrolled-component-with-a-key) instead.
>
> For other use cases, [follow the recommendations in this blog post about derived state](/blog/2018/06/07/you-probably-dont-need-derived-state.html).

`UNSAFE_componentWillReceiveProps()` is invoked before a mounted component receives new props. If you need to update the state in response to prop changes (for example, to reset it), you may compare `this.props` and `nextProps` and perform state transitions using `this.setState()` in this method.

Note that if a parent component causes your component to re-render, this method will be called even if props have not changed. Make sure to compare the current and next values if you only want to handle changes.

React doesn’t call `UNSAFE_componentWillReceiveProps()` with initial props during [mounting](#mounting). It only calls this method if some of component’s props may update. Calling `this.setState()` generally doesn’t trigger `UNSAFE_componentWillReceiveProps()`.

***

### [](#unsafe_componentwillupdate)`UNSAFE_componentWillUpdate()`

```
UNSAFE_componentWillUpdate(nextProps, nextState)
```

> Note
>
> This lifecycle was previously named `componentWillUpdate`. That name will continue to work until version 17. Use the [`rename-unsafe-lifecycles` codemod](https://github.com/reactjs/react-codemod#rename-unsafe-lifecycles) to automatically update your components.

`UNSAFE_componentWillUpdate()` is invoked just before rendering when new props or state are being received. Use this as an opportunity to perform preparation before an update occurs. This method is not called for the initial render.

Note that you cannot call `this.setState()` here; nor should you do anything else (e.g. dispatch a Redux action) that would trigger an update to a React component before `UNSAFE_componentWillUpdate()` returns.

Typically, this method can be replaced by `componentDidUpdate()`. If you were reading from the DOM in this method (e.g. to save a scroll position), you can move that logic to `getSnapshotBeforeUpdate()`.

> Note
>
> `UNSAFE_componentWillUpdate()` will not be invoked if [`shouldComponentUpdate()`](#shouldcomponentupdate) returns false.

***

## [](#other-apis-1)Other APIs

Unlike the lifecycle methods above (which React calls for you), the methods below are the methods *you* can call from your components.

There are just two of them: `setState()` and `forceUpdate()`.

### [](#setstate)`setState()`

```
setState(updater[, callback])
```

`setState()` enqueues changes to the component state and tells React that this component and its children need to be re-rendered with the updated state. This is the primary method you use to update the user interface in response to event handlers and server responses.

Think of `setState()` as a *request* rather than an immediate command to update the component. For better perceived performance, React may delay it, and then update several components in a single pass. 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), but this may hurt performance.

`setState()` does not always immediately update the component. It may batch or defer the update until later. This makes reading `this.state` right after calling `setState()` a potential pitfall. Instead, use `componentDidUpdate` or a `setState` callback (`setState(updater, callback)`), either of which are guaranteed to fire after the update has been applied. If you need to set the state based on the previous state, read about the `updater` argument below.

`setState()` will always lead to a re-render unless `shouldComponentUpdate()` returns `false`. If mutable objects are being used and conditional rendering logic cannot be implemented in `shouldComponentUpdate()`, calling `setState()` only when the new state differs from the previous state will avoid unnecessary re-renders.

The first argument is an `updater` function with the signature:

```
(state, props) => stateChange
```

`state` is a reference to the component state at the time the change is being applied. It should not be directly mutated. Instead, changes should be represented by building a new object based on the input from `state` and `props`. For instance, suppose we wanted to increment a value in state by `props.step`:

```
this.setState((state, props) => {
  return {counter: state.counter + props.step};
});
```

Both `state` and `props` received by the updater function are guaranteed to be up-to-date. The output of the updater is shallowly merged with `state`.

The second parameter to `setState()` is an optional callback function that will be executed once `setState` is completed and the component is re-rendered. Generally we recommend using `componentDidUpdate()` for such logic instead.

You may optionally pass an object as the first argument to `setState()` instead of a function:

```
setState(stateChange[, callback])
```

This performs a shallow merge of `stateChange` into the new state, e.g., to adjust a shopping cart item quantity:

```
this.setState({quantity: 2})
```

This form of `setState()` is also asynchronous, and multiple calls during the same cycle may be batched together. For example, if you attempt to increment an item quantity more than once in the same cycle, that will result in the equivalent of:

```
Object.assign(
  previousState,
  {quantity: state.quantity + 1},
  {quantity: state.quantity + 1},
  ...
)
```

Subsequent calls will override values from previous calls in the same cycle, so the quantity will only be incremented once. If the next state depends on the current state, we recommend using the updater function form, instead:

```
this.setState((state) => {
  return {quantity: state.quantity + 1};
});
```

For more detail, see:

* [State and Lifecycle guide](/docs/state-and-lifecycle.html)
* [In depth: When and why are `setState()` calls batched?](https://stackoverflow.com/a/48610973/458193)
* [In depth: Why isn’t `this.state` updated immediately?](https://github.com/facebook/react/issues/11527#issuecomment-360199710)

***

### [](#forceupdate)`forceUpdate()`

```
component.forceUpdate(callback)
```

By default, when your component’s state or props change, your component will re-render. If your `render()` method depends on some other data, you can tell React that the component needs re-rendering by calling `forceUpdate()`.

Calling `forceUpdate()` will cause `render()` to be called on the component, skipping `shouldComponentUpdate()`. This will trigger the normal lifecycle methods for child components, including the `shouldComponentUpdate()` method of each child. React will still only update the DOM if the markup changes.

Normally you should try to avoid all uses of `forceUpdate()` and only read from `this.props` and `this.state` in `render()`.

***

## [](#class-properties-1)Class Properties

### [](#defaultprops)`defaultProps`

`defaultProps` can be defined as a property on the component class itself, to set the default props for the class. This is used for `undefined` props, but not for `null` props. For example:

```
class CustomButton extends React.Component {
  // ...
}

CustomButton.defaultProps = {
  color: 'blue'
};
```

If `props.color` is not provided, it will be set by default to `'blue'`:

```
  render() {
    return <CustomButton /> ; // props.color will be set to blue
  }
```

If `props.color` is set to `null`, it will remain `null`:

```
  render() {
    return <CustomButton color={null} /> ; // props.color will remain null
  }
```

***

### [](#displayname)`displayName`

The `displayName` string is used in debugging messages. Usually, you don’t need to set it explicitly because it’s inferred from the name of the function or class that defines the component. You might want to set it explicitly if you want to display a different name for debugging purposes or when you create a higher-order component, see [Wrap the Display Name for Easy Debugging](/docs/higher-order-components.html#convention-wrap-the-display-name-for-easy-debugging) for details.

***

## [](#instance-properties-1)Instance Properties

### [](#props)`props`

`this.props` contains the props that were defined by the caller of this component. See [Components and Props](/docs/components-and-props.html) for an introduction to props.

In particular, `this.props.children` is a special prop, typically defined by the child tags in the JSX expression rather than in the tag itself.

### [](#state)`state`

The state contains data specific to this component that may change over time. The state is user-defined, and it should be a plain JavaScript object.

If some value isn’t used for rendering or data flow (for example, a timer ID), you don’t have to put it in the state. Such values can be defined as fields on the component instance.

See [State and Lifecycle](/docs/state-and-lifecycle.html) for more information about the state.

Never mutate `this.state` directly, as calling `setState()` afterwards may replace the mutation you made. Treat `this.state` as if it were immutable.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/reference-react-component.md)

----
url: https://legacy.reactjs.org/blog/2014/09/24/testing-flux-applications.html
----

September 24, 2014 by [Bill Fisher](https://twitter.com/fisherwebdev)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

**A more up-to-date version of this post is available as part of the [Flux documentation](https://facebook.github.io/flux/docs/testing-flux-applications.html).**

[Flux](https://facebook.github.io/flux/) is the application architecture that Facebook uses to build web applications with [React](/). It’s based on a unidirectional data flow. In previous blog posts and documentation articles, we’ve shown the [basic structure and data flow](https://facebook.github.io/flux/docs/overview.html), more closely examined the [dispatcher and action creators](/blog/2014/07/30/flux-actions-and-the-dispatcher.html), and shown how to put it all together with a [tutorial](https://facebook.github.io/flux/docs/todo-list.html). Now let’s look at how to do formal unit testing of Flux applications with [Jest](https://facebook.github.io/jest/), Facebook’s auto-mocking testing framework.

## [](#testing-with-jest)Testing with Jest

For a unit test to operate on a truly isolated *unit* of the application, we need to mock every module except the one we are testing. Jest makes the mocking of other parts of a Flux application trivial. To illustrate testing with Jest, we’ll return to our [example TodoMVC application](https://github.com/facebook/flux/tree/master/examples/flux-todomvc).

The first steps toward working with Jest are as follows:

1. Get the module dependencies for the application installed by running `npm install`.
2. Create a directory `__tests__/` with a test file, in this case TodoStore-test.js
3. Run `npm install jest-cli --save-dev`
4. Add the following to your package.json

```
{
  ...
  "scripts": {
    "test": "jest"
  }
  ...
}
```

Now you’re ready to run your tests from the command line with `npm test`.

By default, all modules are mocked, so the only boilerplate we need in TodoStore-test.js is a declarative call to Jest’s `dontMock()` method.

```
jest.dontMock('TodoStore');
```

This tells Jest to let TodoStore be a real object with real, live methods. Jest will mock all other objects involved with the test.

## [](#testing-stores)Testing Stores

At Facebook, Flux stores often receive a great deal of formal unit test coverage, as this is where the application state and logic lives. Stores are arguably the most important place in a Flux application to provide coverage, but at first glance, it’s not entirely obvious how to test them.

By design, stores can’t be modified from the outside. They have no setters. The only way new data can enter a store is through the callback it registers with the dispatcher.

We therefore need to simulate the Flux data flow with this *one weird trick*.

```
var mockRegister = MyDispatcher.register;
var mockRegisterInfo = mockRegister.mock;
var callsToRegister = mockRegisterInfo.calls;
var firstCall = callsToRegister[0];
var firstArgument = firstCall[0];
var callback = firstArgument;
```

We now have the store’s registered callback, the sole mechanism by which data can enter the store.

For folks new to Jest, or mocks in general, it might not be entirely obvious what is happening in that code block, so let’s look at each part of it a bit more closely. We start out by looking at the `register()` method of our application’s dispatcher — the method that the store uses to register its callback with the dispatcher. The dispatcher has been thoroughly mocked automatically by Jest, so we can get a reference to the mocked version of the `register()` method just as we would normally refer to that method in our production code. But we can get additional information about that method with the `mock` *property* of that method. We don’t often think of methods having properties, but in Jest, this idea is vital. Every method of a mocked object has this property, and it allows us to examine how the method is being called during the test. A chronologically ordered list of calls to `register()` is available with the `calls` property of `mock`, and each of these calls has a list of the arguments that were used in each method call.

So in this code, we are really saying, “Give me a reference to the first argument of the first call to MyDispatcher’s `register()` method.” That first argument is the store’s callback, so now we have all we need to start testing. But first, we can save ourselves some semicolons and roll all of this into a single line:

```
callback = MyDispatcher.register.mock.calls[0][0];
```

We can invoke that callback whenever we like, independent of our application’s dispatcher or action creators. We will, in fact, fake the behavior of the dispatcher and action creators by invoking the callback with an action that we’ll create directly in our test.

```
var payload = {
  source: 'VIEW_ACTION',
  action: {
    actionType: TodoConstants.TODO_CREATE,
    text: 'foo'
  }
};
callback(payload);
var all = TodoStore.getAll();
var keys = Object.keys(all);
expect(all[keys[0]].text).toEqual('foo');
```

## [](#putting-it-all-together)Putting it All Together

The example Flux TodoMVC application has been updated with an example test for the TodoStore, but let’s look at an abbreviated version of the entire test. The most important things to notice in this test are how we keep a reference to the store’s registered callback in the closure of the test, and how we recreate the store before every test so that we clear the state of the store entirely.

```
jest.dontMock('../TodoStore');
jest.dontMock('react/lib/merge');

describe('TodoStore', function() {

  var TodoConstants = require('../../constants/TodoConstants');

  // mock actions inside dispatch payloads
  var actionTodoCreate = {
    source: 'VIEW_ACTION',
    action: {
      actionType: TodoConstants.TODO_CREATE,
      text: 'foo'
    }
  };
  var actionTodoDestroy = {
    source: 'VIEW_ACTION',
    action: {
      actionType: TodoConstants.TODO_DESTROY,
      id: 'replace me in test'
    }
  };

  var AppDispatcher;
  var TodoStore;
  var callback;

  beforeEach(function() {
    AppDispatcher = require('../../dispatcher/AppDispatcher');
    TodoStore = require('../TodoStore');
    callback = AppDispatcher.register.mock.calls[0][0];
  });

  it('registers a callback with the dispatcher', function() {
    expect(AppDispatcher.register.mock.calls.length).toBe(1);
  });

  it('initializes with no to-do items', function() {
    var all = TodoStore.getAll();
    expect(all).toEqual({});
  });

  it('creates a to-do item', function() {
    callback(actionTodoCreate);
    var all = TodoStore.getAll();
    var keys = Object.keys(all);
    expect(keys.length).toBe(1);
    expect(all[keys[0]].text).toEqual('foo');
  });

  it('destroys a to-do item', function() {
    callback(actionTodoCreate);
    var all = TodoStore.getAll();
    var keys = Object.keys(all);
    expect(keys.length).toBe(1);
    actionTodoDestroy.action.id = keys[0];
    callback(actionTodoDestroy);
    expect(all[keys[0]]).toBeUndefined();
  });

});
```

You can take a look at all this code in the [TodoStore’s tests on GitHub](https://github.com/facebook/flux/tree/master/examples/flux-todomvc/js/stores/__tests__/TodoStore-test.js) as well.

## [](#mocking-data-derived-from-other-stores)Mocking Data Derived from Other Stores

Sometimes our stores rely on data from other stores. Because all of our modules are mocked, we’ll need to simulate the data that comes from the other store. We can do this by retrieving the mock function and adding a custom return value to it.

```
var MyOtherStore = require('../MyOtherStore');
MyOtherStore.getState.mockReturnValue({
  '123': {
    id: '123',
    text: 'foo'
  },
  '456': {
    id: '456',
    text: 'bar'
  }
});
```

Now we have a collection of objects that will come back from MyOtherStore whenever we call MyOtherStore.getState() in our tests. Any application state can be simulated with a combination of these custom return values and the previously shown technique of working with the store’s registered callback.

A brief example of this technique is up on GitHub within the Flux Chat example’s [UnreadThreadStore-test.js](https://github.com/facebook/flux/tree/master/examples/flux-chat/js/stores/__tests__/UnreadThreadStore-test.js).

For more information about the `mock` property of mocked methods or Jest’s ability to provide custom mock values, see Jest’s documentation on [mock functions](https://facebook.github.io/jest/docs/mock-functions.html).

## [](#moving-logic-from-react-to-stores)Moving Logic from React to Stores

What often starts as a little piece of seemingly benign logic in our React components often presents a problem while creating unit tests. We want to be able to write tests that read like a specification for our application’s behavior, and when application logic slips into our view layer, this becomes more difficult.

For example, when a user has marked each of their to-do items as complete, the TodoMVC specification dictates that we should also change the status of the “Mark all as complete” checkbox automatically. To create that logic, we might be tempted to write code like this in our MainSection’s `render()` method:

```
var allTodos = this.props.allTodos;
var allChecked = true;
for (var id in allTodos) {
  if (!allTodos[id].complete) {
    allChecked = false;
    break;
  }
}
...

return (
  <section id="main">
  <input
    id="toggle-all"
    type="checkbox"
    checked={allChecked ? 'checked' : ''}
  />
  ...
  </section>
);
```

While this seems like an easy, normal thing to do, this is an example of application logic slipping into the views, and it can’t be described in our spec-style TodoStore test. Let’s take that logic and move it to the store. First, we’ll create a public method on the store that will encapsulate that logic:

```
areAllComplete: function() {
  for (var id in _todos) {
    if (!_todos[id].complete) {
      return false;
    }
  }
  return true;
},
```

Now we have the application logic where it belongs, and we can write the following test:

```
it('determines whether all to-do items are complete', function() {
  var i = 0;
  for (; i < 3; i++) {
    callback(mockTodoCreate);
  }
  expect(TodoStore.areAllComplete()).toBe(false);

  var all = TodoStore.getAll();
  for (key in all) {
    callback({
      source: 'VIEW_ACTION',
      action: {
        actionType: TodoConstants.TODO_COMPLETE,
        id: key
      }
    });
  }
  expect(TodoStore.areAllComplete()).toBe(true);

  callback({
    source: 'VIEW_ACTION',
    action: {
      actionType: TodoConstants.TODO_UNDO_COMPLETE,
      id: key
    }
  });
  expect(TodoStore.areAllComplete()).toBe(false);
});
```

Finally, we revise our view layer. We’ll call for that data in the controller-view, TodoApp.js, and pass it down to the MainSection component.

```
function getTodoState() {
  return {
    allTodos: TodoStore.getAll(),
    areAllComplete: TodoStore.areAllComplete()
  };
}

var TodoApp = React.createClass({
...

  /**
   * @return {object}
   */
  render: function() {
    return (
      ...
      <MainSection
        allTodos={this.state.allTodos}
        areAllComplete={this.state.areAllComplete}
      />
      ...
    );
  },

  /**
   * Event handler for 'change' events coming from the TodoStore
   */
  _onChange: function() {
    this.setState(getTodoState());
  }

});
```

And then we’ll utilize that property for the rendering of the checkbox.

```
render: function() {
  ...

  return (
    <section id="main">
    <input
      id="toggle-all"
      type="checkbox"
      checked={this.props.areAllComplete ? 'checked' : ''}
    />
    ...
    </section>
  );
},
```

To learn how to test React components themselves, check out the [Jest tutorial for React](https://facebook.github.io/jest/docs/tutorial-react.html) and the [ReactTestUtils documentation](/docs/test-utils.html).

## [](#further-reading)Further Reading

* [Mocks Aren’t Stubs](http://martinfowler.com/articles/mocksArentStubs.html) by Martin Fowler
* [Jest API Reference](https://facebook.github.io/jest/docs/api.html)

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2014-09-24-testing-flux-applications.md)

----
url: https://legacy.reactjs.org/blog/2013/10/3/community-roundup-9.html
----

October 03, 2013 by [Vjeux](https://twitter.com/vjeux)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

We organized a React hackathon last week-end in the Facebook Seattle office. 50 people, grouped into 15 teams, came to hack for a day on React. It was a lot of fun and we’ll probably organize more in the future.

[](/static/16bbe4b6c8d5939f92e6a7c9afca22c2/6aca1/react-hackathon.jpg)

## [](#react-hackathon-winner)React Hackathon Winner

[Alex Swan](http://bold-it.com/) implemented [Qu.izti.me](http://qu.izti.me/), a multi-player quiz game. It is real-time via Web Socket and mobile friendly.

> The game itself is pretty simple. People join the “room” by going to [http://qu.izti.me](http://qu.izti.me/) on their device. Large displays will show a leaderboard along with the game, and small displays (such as phones) will act as personal gamepads. Users will see questions and a choice of answers. The faster you answer, the more points you earn.
>
> In my opinion, Socket.io and React go together like chocolate and peanut butter. The page was always an accurate representation of the game object.
>
> [](http://bold-it.com/javascript/facebook-react-example/)
>
> [Read More…](http://bold-it.com/javascript/facebook-react-example/)

## [](#jsconf-eu-talk-rethinking-best-practices)JSConf EU Talk: Rethinking Best Practices

[Pete Hunt](http://www.petehunt.net/) presented React at JSConf EU. He covers three controversial design decisions of React:

1. Build **components**, not templates
2. Re-render the whole app on every update
3. Virtual DOM

The video will be available soon on the [JSConf EU website](http://2013.jsconf.eu/speakers/pete-hunt-react-rethinking-best-practices.html), but in the meantime, here are Pete’s slides:

## [](#pump---clojure-bindings-for-react)Pump - Clojure bindings for React

[Alexander Solovyov](http://solovyov.net/) has been working on React bindings for ClojureScript. This is really exciting as it is using “native” ClojureScript data structures.

```
(ns your.app
  (:require-macros [pump.def-macros :refer [defr]])
  (:require [pump.core]))

(defr Component
  :get-initial-state #(identity {:some-value ""})

  [component props state]

  [:div {:class-name "test"} "hello"])
```

[Check it out on GitHub…](https://github.com/piranha/pump)

## [](#jsxhint)JSXHint

[Todd Kennedy](http://blog.selfassembled.org/) working at [Condé Nast](http://www.condenast.com/) implemented a wrapper on-top of [JSHint](http://www.jshint.com/) that first converts JSX files to JS.

> A wrapper around JSHint to allow linting of files containing JSX syntax. Accepts glob patterns. Respects your local .jshintrc file and .gitignore to filter your glob patterns.
>
> ```
> npm install -g jsxhint
> ```
>
> [Check it out on GitHub…](https://github.com/CondeNast/JSXHint)

## [](#turbo-react)Turbo React

[Ross Allen](https://twitter.com/ssorallen) working at [Mesosphere](http://mesosphere.io/) combined [Turbolinks](https://github.com/rails/turbolinks/), a library used by Ruby on Rails to speed up page transition, and React.

> “Re-request this page” is just a link to the current page. When you click it, Turbolinks intercepts the GET request and fetchs the full page via XHR.
>
> The panel is rendered with a random panel- class on each request, and the progress bar gets a random widthX class.
>
> With Turbolinks alone, the entire would be replaced, and transitions would not happen. In this little demo though, React adds and removes classes and text, and the attribute changes are animated with CSS transitions. The DOM is otherwise left intact.
>
> [](https://turbo-react.herokuapp.com/)
>
> [Check out the demo…](https://turbo-react.herokuapp.com/)

## [](#reactive-table)Reactive Table

[Stoyan Stefanov](http://www.phpied.com/) continues his series of blog posts about React. This one is an introduction tutorial on rendering a simple table with React.

> React is all about components. So let’s build one.
>
> Let’s call it Table (to avoid any confusion what the component is about).
>
> ```
> var Table = React.createClass({
>   /*stuff goeth here*/
> });
> ```
>
> You see that React components are defined using a regular JS object. Some properties and methods of the object such as render() have special meanings, the rest is upforgrabs.
>
> [Read the full article…](http://www.phpied.com/reactive-table/)

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2013-10-3-community-roundup-9.md)

----
url: https://react.dev/reference/rsc/server-components
----

[API Reference](/reference/react)

# Server Components[](#undefined "Link for this heading")

While React Server Components in React 19 are stable and will not break between minor versions, the underlying APIs used to implement a React Server Components bundler or framework do not follow semver and may break between minors in React 19.x.

To support React Server Components as a bundler or framework, we recommend pinning to a specific React version, or using the Canary release. We will continue working with bundlers and frameworks to stabilize the APIs used to implement React Server Components in the future.

### Server Components without a Server[](#server-components-without-a-server "Link for Server Components without a Server ")

Server components can run at build time to read from the filesystem or fetch static content, so a web server is not required. For example, you may want to read static data from a content management system.

Without Server Components, it’s common to fetch static data on the client with an Effect:

```
// bundle.js

import marked from 'marked'; // 35.9K (11.2K gzipped)

import sanitizeHtml from 'sanitize-html'; // 206K (63.3K gzipped)



function Page({page}) {

  const [content, setContent] = useState('');

  // NOTE: loads *after* first page render.

  useEffect(() => {

    fetch(`/api/content/${page}`).then((data) => {

      setContent(data.content);

    });

  }, [page]);



  return <div>{sanitizeHtml(marked(content))}</div>;

}
```

```
// api.js

app.get(`/api/content/:page`, async (req, res) => {

  const page = req.params.page;

  const content = await file.readFile(`${page}.md`);

  res.send({content});

});
```

This pattern means users need to download and parse an additional 75K (gzipped) of libraries, and wait for a second request to fetch the data after the page loads, just to render static content that will not change for the lifetime of the page.

With Server Components, you can render these components once at build time:

```
import marked from 'marked'; // Not included in bundle

import sanitizeHtml from 'sanitize-html'; // Not included in bundle



async function Page({page}) {

  // NOTE: loads *during* render, when the app is built.

  const content = await file.readFile(`${page}.md`);



  return <div>{sanitizeHtml(marked(content))}</div>;

}
```

The rendered output can then be server-side rendered (SSR) to HTML and uploaded to a CDN. When the app loads, the client will not see the original `Page` component, or the expensive libraries for rendering the markdown. The client will only see the rendered output:

```
<div><!-- html for markdown --></div>
```

This means the content is visible during first page load, and the bundle does not include the expensive libraries needed to render the static content.

### Note

You may notice that the Server Component above is an async function:

```
async function Page({page}) {

  //...

}
```

Async Components are a new feature of Server Components that allow you to `await` in render.

See [Async components with Server Components](#async-components-with-server-components) below.

### Server Components with a Server[](#server-components-with-a-server "Link for Server Components with a Server ")

Server Components can also run on a web server during a request for a page, letting you access your data layer without having to build an API. They are rendered before your application is bundled, and can pass data and JSX as props to Client Components.

Without Server Components, it’s common to fetch dynamic data on the client in an Effect:

```
// bundle.js

function Note({id}) {

  const [note, setNote] = useState('');

  // NOTE: loads *after* first render.

  useEffect(() => {

    fetch(`/api/notes/${id}`).then(data => {

      setNote(data.note);

    });

  }, [id]);



  return (

    <div>

      <Author id={note.authorId} />

      <p>{note}</p>

    </div>

  );

}



function Author({id}) {

  const [author, setAuthor] = useState('');

  // NOTE: loads *after* Note renders.

  // Causing an expensive client-server waterfall.

  useEffect(() => {

    fetch(`/api/authors/${id}`).then(data => {

      setAuthor(data.author);

    });

  }, [id]);



  return <span>By: {author.name}</span>;

}
```

```
// api

import db from './database';



app.get(`/api/notes/:id`, async (req, res) => {

  const note = await db.notes.get(id);

  res.send({note});

});



app.get(`/api/authors/:id`, async (req, res) => {

  const author = await db.authors.get(id);

  res.send({author});

});
```

With Server Components, you can read the data and render it in the component:

```
import db from './database';



async function Note({id}) {

  // NOTE: loads *during* render.

  const note = await db.notes.get(id);

  return (

    <div>

      <Author id={note.authorId} />

      <p>{note}</p>

    </div>

  );

}



async function Author({id}) {

  // NOTE: loads *after* Note,

  // but is fast if data is co-located.

  const author = await db.authors.get(id);

  return <span>By: {author.name}</span>;

}
```

The bundler then combines the data, rendered Server Components and dynamic Client Components into a bundle. Optionally, that bundle can then be server-side rendered (SSR) to create the initial HTML for the page. When the page loads, the browser does not see the original `Note` and `Author` components; only the rendered output is sent to the client:

```
<div>

  <span>By: The React Team</span>

  <p>React 19 is...</p>

</div>
```

Server Components can be made dynamic by re-fetching them from a server, where they can access the data and render again. This new application architecture combines the simple “request/response” mental model of server-centric Multi-Page Apps with the seamless interactivity of client-centric Single-Page Apps, giving you the best of both worlds.

### Adding interactivity to Server Components[](#adding-interactivity-to-server-components "Link for Adding interactivity to Server Components ")

Server Components are not sent to the browser, so they cannot use interactive APIs like `useState`. To add interactivity to Server Components, you can compose them with Client Component using the `"use client"` directive.

### Note

#### There is no directive for Server Components.[](#there-is-no-directive-for-server-components "Link for There is no directive for Server Components. ")

A common misunderstanding is that Server Components are denoted by `"use server"`, but there is no directive for Server Components. The `"use server"` directive is used for Server Functions.

For more info, see the docs for [Directives](/reference/rsc/directives).

In the following example, the `Notes` Server Component imports an `Expandable` Client Component that uses state to toggle its `expanded` state:

```
// Server Component

import Expandable from './Expandable';



async function Notes() {

  const notes = await db.notes.getAll();

  return (

    <div>

      {notes.map(note => (

        <Expandable key={note.id}>

          <p note={note} />

        </Expandable>

      ))}

    </div>

  )

}
```

```
// Client Component

"use client"



export default function Expandable({children}) {

  const [expanded, setExpanded] = useState(false);

  return (

    <div>

      <button

        onClick={() => setExpanded(!expanded)}

      >

        Toggle

      </button>

      {expanded && children}

    </div>

  )

}
```

This works by first rendering `Notes` as a Server Component, and then instructing the bundler to create a bundle for the Client Component `Expandable`. In the browser, the Client Components will see output of the Server Components passed as props:

```
<head>

  <!-- the bundle for Client Components -->

  <script src="bundle.js" />

</head>

<body>

  <div>

    <Expandable key={1}>

      <p>this is the first note</p>

    </Expandable>

    <Expandable key={2}>

      <p>this is the second note</p>

    </Expandable>

    <!--...-->

  </div>

</body>
```

### Async components with Server Components[](#async-components-with-server-components "Link for Async components with Server Components ")

Server Components introduce a new way to write Components using async/await. When you `await` in an async component, React will suspend and wait for the promise to resolve before resuming rendering. This works across server/client boundaries with streaming support for Suspense.

You can even create a promise on the server, and await it on the client:

```
// Server Component

import db from './database';



async function Page({id}) {

  // Will suspend the Server Component.

  const note = await db.notes.get(id);



  // NOTE: not awaited, will start here and await on the client.

  const commentsPromise = db.comments.get(note.id);

  return (

    <div>

      {note}

      <Suspense fallback={<p>Loading Comments...</p>}>

        <Comments commentsPromise={commentsPromise} />

      </Suspense>

    </div>

  );

}
```

```
// Client Component

"use client";

import {use} from 'react';



function Comments({commentsPromise}) {

  // NOTE: this will resume the promise from the server.

  // It will suspend until the data is available.

  const comments = use(commentsPromise);

  return comments.map(comment => <p>{comment}</p>);

}
```

The `note` content is important data for the page to render, so we `await` it on the server. The comments are below the fold and lower-priority, so we start the promise on the server, and wait for it on the client with the `use` API. This will Suspend on the client, without blocking the `note` content from rendering.

Since async components are not supported on the client, we await the promise with `use`.

[NextServer Functions](/reference/rsc/server-functions)

***

----
url: https://18.react.dev/reference/react-dom/preinit
----

[API Reference](/reference/react)

[APIs](/reference/react-dom)

# preinit[](#undefined "Link for this heading")

### Canary

The `preinit` function is currently only available in React’s Canary and experimental channels. Learn more about [React’s release channels here](/community/versioning-policy#all-release-channels).

### Note

[React-based frameworks](/learn/start-a-new-react-project) frequently handle resource loading for you, so you might not have to call this API yourself. Consult your framework’s documentation for details.

`preinit` lets you eagerly fetch and evaluate a stylesheet or external script.

```
preinit("https://example.com/script.js", {as: "script"});
```

* [Reference](#reference)
  * [`preinit(href, options)`](#preinit)

* [Usage](#usage)

  * [Preiniting when rendering](#preiniting-when-rendering)
  * [Preiniting in an event handler](#preiniting-in-an-event-handler)

***

## Reference[](#reference "Link for Reference ")

### `preinit(href, options)`[](#preinit "Link for this heading")

To preinit a script or stylesheet, call the `preinit` function from `react-dom`.

```
import { preinit } from 'react-dom';



function AppRoot() {

  preinit("https://example.com/script.js", {as: "script"});

  // ...

}
```

  * `crossOrigin`: a string. The [CORS policy](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/crossorigin) to use. Its possible values are `anonymous` and `use-credentials`. It is required when `as` is set to `"fetch"`.

***

## Usage[](#usage "Link for Usage ")

### Preiniting when rendering[](#preiniting-when-rendering "Link for Preiniting when rendering ")

Call `preinit` when rendering a component if you know that it or its children will use a specific resource, and you’re OK with the resource being evaluated and thereby taking effect immediately upon being downloaded.

#### Examples of preiniting[](#examples "Link for Examples of preiniting")

#### Example 1 of 2:Preiniting an external script[](#preiniting-an-external-script "Link for this heading")

```
import { preinit } from 'react-dom';



function AppRoot() {

  preinit("https://example.com/script.js", {as: "script"});

  return ...;

}
```

If you want the browser to download the script but not to execute it right away, use [`preload`](/reference/react-dom/preload) instead. If you want to load an ESM module, use [`preinitModule`](/reference/react-dom/preinitModule).

### Preiniting in an event handler[](#preiniting-in-an-event-handler "Link for Preiniting in an event handler ")

Call `preinit` in an event handler before transitioning to a page or state where external resources will be needed. This gets the process started earlier than if you call it during the rendering of the new page or state.

```
import { preinit } from 'react-dom';



function CallToAction() {

  const onClick = () => {

    preinit("https://example.com/wizardStyles.css", {as: "style"});

    startWizard();

  }

  return (

    <button onClick={onClick}>Start Wizard</button>

  );

}
```

[PreviousprefetchDNS](/reference/react-dom/prefetchDNS)

[NextpreinitModule](/reference/react-dom/preinitModule)

***

----
url: https://legacy.reactjs.org/blog/2016/04/08/react-v15.0.1.html
----

April 08, 2016 by [Paul O’Shannessy](https://twitter.com/zpao)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

Yesterday afternoon we shipped v15.0.0 and quickly got some feedback about a couple of issues. We apologize for these problems and we’ve been working since then to make sure we get fixes into your hands as quickly as possible.

The first of these issues is related to the removal of an undocumented API. This API was added to enable [JSX Spread Attributes](/docs/jsx-spread.html) in our JS compile tools (react-tools, JSXTransformer) before `Object.assign` was standard. When we stopped supporting these tools last year, we kept the API there to catch the longer tail of people using those tools. Meanwhile we moved to using Babel and encouraged others to do the same. Babel will typically compile the spread use to an `_extends` helper, which will use `Object.assign`. We did not properly research other compilation tools before deciding to remove the API in v15. Specifically, TypeScript and coffee-react are two popular packages using `React.__spread`, as well as reactify which still makes use react-tools. In order to make sure that code compiled with these tools is not broken, we will be restoring the `React.__spread` API and adding a warning. It will be removed in the future so if you maintain a project making using of it, we encourage you to compile to `Object.assign` directly or a similar helper function.

The second issue resulted in cursor position being lost in controlled inputs. We merged a pull request earlier this week to fix a separate regression from v0.14. Our goal was to target `<option>` elements but we ended up targeting all interactions with `value` properties. Unfortunately we didn’t test it as thoroughly as we thought. We backed out the offending change and fixed the issue in different way which doesn’t have the same problem.

We apologize if you installed 15.0.0 and have encountered these issues yourselves.

As usual, you can get install the `react` package via npm or download a browser bundle.

* **React**\
  Dev build with warnings: <https://fb.me/react-15.0.1.js>\
  Minified build for production: <https://fb.me/react-15.0.1.min.js>
* **React with Add-Ons**\
  Dev build with warnings: <https://fb.me/react-with-addons-15.0.1.js>\
  Minified build for production: <https://fb.me/react-with-addons-15.0.1.min.js>
* **React DOM** (include React in the page before React DOM)\
  Dev build with warnings: <https://fb.me/react-dom-15.0.1.js>\
  Minified build for production: <https://fb.me/react-dom-15.0.1.min.js>

## [](#changelog)Changelog

### [](#react)React

* Restore `React.__spread` API to unbreak code compiled with some tools making use of this undocumented API. It is now officially deprecated.\
  [@zpao](https://github.com/zpao) in [#6444](https://github.com/facebook/react/pull/6444)

### [](#reactdom)ReactDOM

* Fixed issue resulting in loss of cursor position in controlled inputs.\
  [@sophiebits](https://github.com/sophiebits) in [#6449](https://github.com/facebook/react/pull/6449)

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2016-04-08-react-v15.0.1.md)

----
url: https://legacy.reactjs.org/blog/2014/12/18/react-v0.12.2.html
----

December 18, 2014 by [Paul O’Shannessy](https://twitter.com/zpao)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

We just shipped React v0.12.2, bringing the 0.12 branch up to date with a few small fixes that landed in master over the past 2 months.

You may have noticed that we did not do an announcement for v0.12.1. That release was snuck out in anticipation of [Flow](http://flowtype.org/), with only transform-related changes. Namely we added a flag to the `jsx` executable which allowed you to safely transform Flow-based code to vanilla JS. If you didn’t update for that release, you can safely skip it and move directly to v0.12.2.

The release is available for download from the CDN:

* **React**\
  Dev build with warnings: <https://fb.me/react-0.12.2.js>\
  Minified build for production: <https://fb.me/react-0.12.2.min.js>
* **React with Add-Ons**\
  Dev build with warnings: <https://fb.me/react-with-addons-0.12.2.js>\
  Minified build for production: <https://fb.me/react-with-addons-0.12.2.min.js>
* **In-Browser JSX transformer**\
  <https://fb.me/JSXTransformer-0.12.2.js>

We’ve also published version `0.12.2` of the `react` and `react-tools` packages on npm and the `react` package on bower. `0.12.1` is also available in the same locations if need those.

Please try these builds out and [file an issue on GitHub](https://github.com/facebook/react/issues/new) if you see anything awry.

## [](#changelog)Changelog

### [](#react-core)React Core

* Added support for more HTML attributes: `formAction`, `formEncType`, `formMethod`, `formTarget`, `marginHeight`, `marginWidth`
* Added `strokeOpacity` to the list of unitless CSS properties
* Removed trailing commas (allows npm module to be bundled and used in IE8)
* Fixed bug resulting in error when passing `undefined` to `React.createElement` - now there is a useful warning

### [](#react-tools)React Tools

* JSX-related transforms now always use double quotes for props and `displayName`

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2014-12-18-react-v0.12.2.md)

----
url: https://react.dev/reference/rsc/directives
----

[API Reference](/reference/react)

# Directives[](#undefined "Link for this heading")

### React Server Components

Directives are for use in [React Server Components](/reference/rsc/server-components).

Directives provide instructions to [bundlers compatible with React Server Components](/learn/creating-a-react-app#full-stack-frameworks).

***

## Source code directives[](#source-code-directives "Link for Source code directives ")

* [`'use client'`](/reference/rsc/use-client) lets you mark what code runs on the client.
* [`'use server'`](/reference/rsc/use-server) marks server-side functions that can be called from client-side code.

[PreviousServer Functions](/reference/rsc/server-functions)

[Next'use client'](/reference/rsc/use-client)

***

----
url: https://18.react.dev/learn/rendering-lists
----

```
<ul>

  <li>Creola Katherine Johnson: mathematician</li>

  <li>Mario José Molina-Pasquel Henríquez: chemist</li>

  <li>Mohammad Abdus Salam: physicist</li>

  <li>Percy Lavon Julian: chemist</li>

  <li>Subrahmanyan Chandrasekhar: astrophysicist</li>

</ul>
```

The only difference among those list items is their contents, their data. You will often need to show several instances of the same component using different data when building interfaces: from lists of comments to galleries of profile images. In these situations, you can store that data in JavaScript objects and arrays and use methods like [`map()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) and [`filter()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/filter) to render lists of components from them.

Here’s a short example of how to generate a list of items from an array:

1. **Move** the data into an array:

```
const people = [

  'Creola Katherine Johnson: mathematician',

  'Mario José Molina-Pasquel Henríquez: chemist',

  'Mohammad Abdus Salam: physicist',

  'Percy Lavon Julian: chemist',

  'Subrahmanyan Chandrasekhar: astrophysicist'

];
```

2. **Map** the `people` members into a new array of JSX nodes, `listItems`:

```
const listItems = people.map(person => <li>{person}</li>);
```

3. **Return** `listItems` from your component wrapped in a `<ul>`:

```
return <ul>{listItems}</ul>;
```

Here is the result:

```
const people = [
  'Creola Katherine Johnson: mathematician',
  'Mario José Molina-Pasquel Henríquez: chemist',
  'Mohammad Abdus Salam: physicist',
  'Percy Lavon Julian: chemist',
  'Subrahmanyan Chandrasekhar: astrophysicist'
];

export default function List() {
  const listItems = people.map(person =>
    <li>{person}</li>
  );
  return <ul>{listItems}</ul>;
}
```

Notice the sandbox above displays a console error:

Console

Warning: Each child in a list should have a unique “key” prop.

You’ll learn how to fix this error later on this page. Before we get to that, let’s add some structure to your data.

## Filtering arrays of items[](#filtering-arrays-of-items "Link for Filtering arrays of items ")

This data can be structured even more.

```
const people = [{

  id: 0,

  name: 'Creola Katherine Johnson',

  profession: 'mathematician',

}, {

  id: 1,

  name: 'Mario José Molina-Pasquel Henríquez',

  profession: 'chemist',

}, {

  id: 2,

  name: 'Mohammad Abdus Salam',

  profession: 'physicist',

}, {

  id: 3,

  name: 'Percy Lavon Julian',

  profession: 'chemist',  

}, {

  id: 4,

  name: 'Subrahmanyan Chandrasekhar',

  profession: 'astrophysicist',

}];
```

Let’s say you want a way to only show people whose profession is `'chemist'`. You can use JavaScript’s `filter()` method to return just those people. This method takes an array of items, passes them through a “test” (a function that returns `true` or `false`), and returns a new array of only those items that passed the test (returned `true`).

You only want the items where `profession` is `'chemist'`. The “test” function for this looks like `(person) => person.profession === 'chemist'`. Here’s how to put it together:

1. **Create** a new array of just “chemist” people, `chemists`, by calling `filter()` on the `people` filtering by `person.profession === 'chemist'`:

```
const chemists = people.filter(person =>

  person.profession === 'chemist'

);
```

2. Now **map** over `chemists`:

```
const listItems = chemists.map(person =>

  <li>

     <img

       src={getImageUrl(person)}

       alt={person.name}

     />

     <p>

       <b>{person.name}:</b>

       {' ' + person.profession + ' '}

       known for {person.accomplishment}

     </p>

  </li>

);
```

3. Lastly, **return** the `listItems` from your component:

```
return <ul>{listItems}</ul>;
```

```
import { people } from './data.js';
import { getImageUrl } from './utils.js';

export default function List() {
  const chemists = people.filter(person =>
    person.profession === 'chemist'
  );
  const listItems = chemists.map(person =>
    <li>
      <img
        src={getImageUrl(person)}
        alt={person.name}
      />
      <p>
        <b>{person.name}:</b>
        {' ' + person.profession + ' '}
        known for {person.accomplishment}
      </p>
    </li>
  );
  return <ul>{listItems}</ul>;
}
```

### Pitfall

Arrow functions implicitly return the expression right after `=>`, so you didn’t need a `return` statement:

```
const listItems = chemists.map(person =>

  <li>...</li> // Implicit return!

);
```

However, **you must write `return` explicitly if your `=>` is followed by a `{` curly brace!**

```
const listItems = chemists.map(person => { // Curly brace

  return <li>...</li>;

});
```

Arrow functions containing `=> {` are said to have a [“block body”.](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions#function_body) They let you write more than a single line of code, but you *have to* write a `return` statement yourself. If you forget it, nothing gets returned!

## Keeping list items in order with `key`[](#keeping-list-items-in-order-with-key "Link for this heading")

Notice that all the sandboxes above show an error in the console:

Console

Warning: Each child in a list should have a unique “key” prop.

You need to give each array item a `key` — a string or a number that uniquely identifies it among other items in that array:

```
<li key={person.id}>...</li>
```

### Note

JSX elements directly inside a `map()` call always need keys!

Keys tell React which array item each component corresponds to, so that it can match them up later. This becomes important if your array items can move (e.g. due to sorting), get inserted, or get deleted. A well-chosen `key` helps React infer what exactly has happened, and make the correct updates to the DOM tree.

Rather than generating keys on the fly, you should include them in your data:

```
export const people = [{
  id: 0, // Used in JSX as a key
  name: 'Creola Katherine Johnson',
  profession: 'mathematician',
  accomplishment: 'spaceflight calculations',
  imageId: 'MK3eW3A'
}, {
  id: 1, // Used in JSX as a key
  name: 'Mario José Molina-Pasquel Henríquez',
  profession: 'chemist',
  accomplishment: 'discovery of Arctic ozone hole',
  imageId: 'mynHUSa'
}, {
  id: 2, // Used in JSX as a key
  name: 'Mohammad Abdus Salam',
  profession: 'physicist',
  accomplishment: 'electromagnetism theory',
  imageId: 'bE7W1ji'
}, {
  id: 3, // Used in JSX as a key
  name: 'Percy Lavon Julian',
  profession: 'chemist',
  accomplishment: 'pioneering cortisone drugs, steroids and birth control pills',
  imageId: 'IOjWm71'
}, {
  id: 4, // Used in JSX as a key
  name: 'Subrahmanyan Chandrasekhar',
  profession: 'astrophysicist',
  accomplishment: 'white dwarf star mass calculations',
  imageId: 'lrWQx8l'
}];
```

##### Deep Dive#### Displaying several DOM nodes for each list item[](#displaying-several-dom-nodes-for-each-list-item "Link for Displaying several DOM nodes for each list item ")

What do you do when each item needs to render not one, but several DOM nodes?

The short [`<>...</>` Fragment](/reference/react/Fragment) syntax won’t let you pass a key, so you need to either group them into a single `<div>`, or use the slightly longer and [more explicit `<Fragment>` syntax:](/reference/react/Fragment#rendering-a-list-of-fragments)

```
import { Fragment } from 'react';



// ...



const listItems = people.map(person =>

  <Fragment key={person.id}>

    <h1>{person.name}</h1>

    <p>{person.bio}</p>

  </Fragment>

);
```

```
import { people } from './data.js';
import { getImageUrl } from './utils.js';

export default function List() {
  const listItems = people.map(person =>
    <li key={person.id}>
      <img
        src={getImageUrl(person)}
        alt={person.name}
      />
      <p>
        <b>{person.name}:</b>
        {' ' + person.profession + ' '}
        known for {person.accomplishment}
      </p>
    </li>
  );
  return (
    <article>
      <h1>Scientists</h1>
      <ul>{listItems}</ul>
    </article>
  );
}
```

[PreviousConditional Rendering](/learn/conditional-rendering)

[NextKeeping Components Pure](/learn/keeping-components-pure)

***

----
url: https://18.react.dev/learn/thinking-in-react
----

```
[

  { category: "Fruits", price: "$1", stocked: true, name: "Apple" },

  { category: "Fruits", price: "$1", stocked: true, name: "Dragonfruit" },

  { category: "Fruits", price: "$2", stocked: false, name: "Passionfruit" },

  { category: "Vegetables", price: "$2", stocked: true, name: "Spinach" },

  { category: "Vegetables", price: "$4", stocked: false, name: "Pumpkin" },

  { category: "Vegetables", price: "$1", stocked: true, name: "Peas" }

]
```

The mockup looks like this:

To implement a UI in React, you will usually follow the same five steps.

## Step 1: Break the UI into a component hierarchy[](#step-1-break-the-ui-into-a-component-hierarchy "Link for Step 1: Break the UI into a component hierarchy ")

Start by drawing boxes around every component and subcomponent in the mockup and naming them. If you work with a designer, they may have already named these components in their design tool. Ask them!

Depending on your background, you can think about splitting up a design into components in different ways:

* **Programming**—use the same techniques for deciding if you should create a new function or object. One such technique is the [single responsibility principle](https://en.wikipedia.org/wiki/Single_responsibility_principle), that is, a component should ideally only do one thing. If it ends up growing, it should be decomposed into smaller subcomponents.

    * `ProductCategoryRow`
    * `ProductRow`

## Step 2: Build a static version in React[](#step-2-build-a-static-version-in-react "Link for Step 2: Build a static version in React ")

Now that you have your component hierarchy, it’s time to implement your app. The most straightforward approach is to build a version that renders the UI from your data model without adding any interactivity… yet! It’s often easier to build the static version first and add interactivity later. Building a static version requires a lot of typing and no thinking, but adding interactivity requires a lot of thinking and not a lot of typing.

To build a static version of your app that renders your data model, you’ll want to build [components](/learn/your-first-component) that reuse other components and pass data using [props.](/learn/passing-props-to-a-component) Props are a way of passing data from parent to child. (If you’re familiar with the concept of [state](/learn/state-a-components-memory), don’t use state at all to build this static version. State is reserved only for interactivity, that is, data that changes over time. Since this is a static version of the app, you don’t need it.)

You can either build “top down” by starting with building the components higher up in the hierarchy (like `FilterableProductTable`) or “bottom up” by working from components lower down (like `ProductRow`). In simpler examples, it’s usually easier to go top-down, and on larger projects, it’s easier to go bottom-up.

```
function ProductCategoryRow({ category }) {
  return (
    <tr>
      <th colSpan="2">
        {category}
      </th>
    </tr>
  );
}

function ProductRow({ product }) {
  const name = product.stocked ? product.name :
    <span style={{ color: 'red' }}>
      {product.name}
    </span>;

  return (
    <tr>
      <td>{name}</td>
      <td>{product.price}</td>
    </tr>
  );
}

function ProductTable({ products }) {
  const rows = [];
  let lastCategory = null;

  products.forEach((product) => {
    if (product.category !== lastCategory) {
      rows.push(
        <ProductCategoryRow
          category={product.category}
          key={product.category} />
      );
    }
    rows.push(
      <ProductRow
        product={product}
        key={product.name} />
    );
    lastCategory = product.category;
  });

  return (
    <table>
      <thead>
        <tr>
          <th>Name</th>
          <th>Price</th>
        </tr>
      </thead>
      <tbody>{rows}</tbody>
    </table>
  );
}

function SearchBar() {
  return (
    <form>
      <input type="text" placeholder="Search..." />
      <label>
        <input type="checkbox" />
        {' '}
        Only show products in stock
      </label>
    </form>
  );
}

function FilterableProductTable({ products }) {
  return (
    <div>
      <SearchBar />
      <ProductTable products={products} />
    </div>
  );
}

const PRODUCTS = [
  {category: "Fruits", price: "$1", stocked: true, name: "Apple"},
  {category: "Fruits", price: "$1", stocked: true, name: "Dragonfruit"},
  {category: "Fruits", price: "$2", stocked: false, name: "Passionfruit"},
  {category: "Vegetables", price: "$2", stocked: true, name: "Spinach"},
  {category: "Vegetables", price: "$4", stocked: false, name: "Pumpkin"},
  {category: "Vegetables", price: "$1", stocked: true, name: "Peas"}
];

export default function App() {
  return <FilterableProductTable products={PRODUCTS} />;
}
```

```
function FilterableProductTable({ products }) {

  const [filterText, setFilterText] = useState('');

  const [inStockOnly, setInStockOnly] = useState(false);
```

Then, pass `filterText` and `inStockOnly` to `ProductTable` and `SearchBar` as props:

```
<div>

  <SearchBar 

    filterText={filterText} 

    inStockOnly={inStockOnly} />

  <ProductTable 

    products={products}

    filterText={filterText}

    inStockOnly={inStockOnly} />

</div>
```

You can start seeing how your application will behave. Edit the `filterText` initial value from `useState('')` to `useState('fruit')` in the sandbox code below. You’ll see both the search input text and the table update:

```
import { useState } from 'react';

function FilterableProductTable({ products }) {
  const [filterText, setFilterText] = useState('');
  const [inStockOnly, setInStockOnly] = useState(false);

  return (
    <div>
      <SearchBar 
        filterText={filterText} 
        inStockOnly={inStockOnly} />
      <ProductTable 
        products={products}
        filterText={filterText}
        inStockOnly={inStockOnly} />
    </div>
  );
}

function ProductCategoryRow({ category }) {
  return (
    <tr>
      <th colSpan="2">
        {category}
      </th>
    </tr>
  );
}

function ProductRow({ product }) {
  const name = product.stocked ? product.name :
    <span style={{ color: 'red' }}>
      {product.name}
    </span>;

  return (
    <tr>
      <td>{name}</td>
      <td>{product.price}</td>
    </tr>
  );
}

function ProductTable({ products, filterText, inStockOnly }) {
  const rows = [];
  let lastCategory = null;

  products.forEach((product) => {
    if (
      product.name.toLowerCase().indexOf(
        filterText.toLowerCase()
      ) === -1
    ) {
      return;
    }
    if (inStockOnly && !product.stocked) {
      return;
    }
    if (product.category !== lastCategory) {
      rows.push(
        <ProductCategoryRow
          category={product.category}
          key={product.category} />
      );
    }
    rows.push(
      <ProductRow
        product={product}
        key={product.name} />
    );
    lastCategory = product.category;
  });

  return (
    <table>
      <thead>
        <tr>
          <th>Name</th>
          <th>Price</th>
        </tr>
      </thead>
      <tbody>{rows}</tbody>
    </table>
  );
}

function SearchBar({ filterText, inStockOnly }) {
  return (
    <form>
      <input 
        type="text" 
        value={filterText} 
        placeholder="Search..."/>
      <label>
        <input 
          type="checkbox" 
          checked={inStockOnly} />
        {' '}
        Only show products in stock
      </label>
    </form>
  );
}

const PRODUCTS = [
  {category: "Fruits", price: "$1", stocked: true, name: "Apple"},
  {category: "Fruits", price: "$1", stocked: true, name: "Dragonfruit"},
  {category: "Fruits", price: "$2", stocked: false, name: "Passionfruit"},
  {category: "Vegetables", price: "$2", stocked: true, name: "Spinach"},
  {category: "Vegetables", price: "$4", stocked: false, name: "Pumpkin"},
  {category: "Vegetables", price: "$1", stocked: true, name: "Peas"}
];

export default function App() {
  return <FilterableProductTable products={PRODUCTS} />;
}
```

Notice that editing the form doesn’t work yet. There is a console error in the sandbox above explaining why:

Console

You provided a \`value\` prop to a form field without an \`onChange\` handler. This will render a read-only field.

In the sandbox above, `ProductTable` and `SearchBar` read the `filterText` and `inStockOnly` props to render the table, the input, and the checkbox. For example, here is how `SearchBar` populates the input value:

```
function SearchBar({ filterText, inStockOnly }) {

  return (

    <form>

      <input 

        type="text" 

        value={filterText} 

        placeholder="Search..."/>
```

However, you haven’t added any code to respond to the user actions like typing yet. This will be your final step.

## Step 5: Add inverse data flow[](#step-5-add-inverse-data-flow "Link for Step 5: Add inverse data flow ")

Currently your app renders correctly with props and state flowing down the hierarchy. But to change the state according to user input, you will need to support data flowing the other way: the form components deep in the hierarchy need to update the state in `FilterableProductTable`.

React makes this data flow explicit, but it requires a little more typing than two-way data binding. If you try to type or check the box in the example above, you’ll see that React ignores your input. This is intentional. By writing `<input value={filterText} />`, you’ve set the `value` prop of the `input` to always be equal to the `filterText` state passed in from `FilterableProductTable`. Since `filterText` state is never set, the input never changes.

You want to make it so whenever the user changes the form inputs, the state updates to reflect those changes. The state is owned by `FilterableProductTable`, so only it can call `setFilterText` and `setInStockOnly`. To let `SearchBar` update the `FilterableProductTable`’s state, you need to pass these functions down to `SearchBar`:

```
function FilterableProductTable({ products }) {

  const [filterText, setFilterText] = useState('');

  const [inStockOnly, setInStockOnly] = useState(false);



  return (

    <div>

      <SearchBar 

        filterText={filterText} 

        inStockOnly={inStockOnly}

        onFilterTextChange={setFilterText}

        onInStockOnlyChange={setInStockOnly} />
```

Inside the `SearchBar`, you will add the `onChange` event handlers and set the parent state from them:

```
function SearchBar({

  filterText,

  inStockOnly,

  onFilterTextChange,

  onInStockOnlyChange

}) {

  return (

    <form>

      <input

        type="text"

        value={filterText}

        placeholder="Search..."

        onChange={(e) => onFilterTextChange(e.target.value)}

      />

      <label>

        <input

          type="checkbox"

          checked={inStockOnly}

          onChange={(e) => onInStockOnlyChange(e.target.checked)}
```

Now the application fully works!

```
import { useState } from 'react';

function FilterableProductTable({ products }) {
  const [filterText, setFilterText] = useState('');
  const [inStockOnly, setInStockOnly] = useState(false);

  return (
    <div>
      <SearchBar 
        filterText={filterText} 
        inStockOnly={inStockOnly} 
        onFilterTextChange={setFilterText} 
        onInStockOnlyChange={setInStockOnly} />
      <ProductTable 
        products={products} 
        filterText={filterText}
        inStockOnly={inStockOnly} />
    </div>
  );
}

function ProductCategoryRow({ category }) {
  return (
    <tr>
      <th colSpan="2">
        {category}
      </th>
    </tr>
  );
}

function ProductRow({ product }) {
  const name = product.stocked ? product.name :
    <span style={{ color: 'red' }}>
      {product.name}
    </span>;

  return (
    <tr>
      <td>{name}</td>
      <td>{product.price}</td>
    </tr>
  );
}

function ProductTable({ products, filterText, inStockOnly }) {
  const rows = [];
  let lastCategory = null;

  products.forEach((product) => {
    if (
      product.name.toLowerCase().indexOf(
        filterText.toLowerCase()
      ) === -1
    ) {
      return;
    }
    if (inStockOnly && !product.stocked) {
      return;
    }
    if (product.category !== lastCategory) {
      rows.push(
        <ProductCategoryRow
          category={product.category}
          key={product.category} />
      );
    }
    rows.push(
      <ProductRow
        product={product}
        key={product.name} />
    );
    lastCategory = product.category;
  });

  return (
    <table>
      <thead>
        <tr>
          <th>Name</th>
          <th>Price</th>
        </tr>
      </thead>
      <tbody>{rows}</tbody>
    </table>
  );
}

function SearchBar({
  filterText,
  inStockOnly,
  onFilterTextChange,
  onInStockOnlyChange
}) {
  return (
    <form>
      <input 
        type="text" 
        value={filterText} placeholder="Search..." 
        onChange={(e) => onFilterTextChange(e.target.value)} />
      <label>
        <input 
          type="checkbox" 
          checked={inStockOnly} 
          onChange={(e) => onInStockOnlyChange(e.target.checked)} />
        {' '}
        Only show products in stock
      </label>
    </form>
  );
}

const PRODUCTS = [
  {category: "Fruits", price: "$1", stocked: true, name: "Apple"},
  {category: "Fruits", price: "$1", stocked: true, name: "Dragonfruit"},
  {category: "Fruits", price: "$2", stocked: false, name: "Passionfruit"},
  {category: "Vegetables", price: "$2", stocked: true, name: "Spinach"},
  {category: "Vegetables", price: "$4", stocked: false, name: "Pumpkin"},
  {category: "Vegetables", price: "$1", stocked: true, name: "Peas"}
];

export default function App() {
  return <FilterableProductTable products={PRODUCTS} />;
}
```

You can learn all about handling events and updating state in the [Adding Interactivity](/learn/adding-interactivity) section.

## Where to go from here[](#where-to-go-from-here "Link for Where to go from here ")

This was a very brief introduction to how to think about building components and applications with React. You can [start a React project](/learn/installation) right now or [dive deeper on all the syntax](/learn/describing-the-ui) used in this tutorial.

[PreviousTutorial: Tic-Tac-Toe](/learn/tutorial-tic-tac-toe)

[NextInstallation](/learn/installation)

***

----
url: https://legacy.reactjs.org/docs/faq-build.html
----

### [](#do-i-need-to-use-jsx-with-react)Do I need to use JSX with React?

No! Check out [“React Without JSX”](/docs/react-without-jsx.html) to learn more.

### [](#do-i-need-to-use-es6--with-react)Do I need to use ES6 (+) with React?

No! Check out [“React Without ES6”](/docs/react-without-es6.html) to learn more.

### [](#how-can-i-write-comments-in-jsx)How can I write comments in JSX?

```
<div>
  {/* Comment goes here */}
  Hello, {name}!
</div>
```

```
<div>
  {/* It also works 
  for multi-line comments. */}
  Hello, {name}! 
</div>
```

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/faq-build.md)

----
url: https://legacy.reactjs.org/blog/2013/06/27/community-roundup-3.html
----

June 27, 2013 by [Vjeux](https://twitter.com/vjeux)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

The highlight of this week is that an interaction-heavy app has been ported to React. React components are solving issues they had with nested views.

## [](#moving-from-backbone-to-react)Moving From Backbone To React

[Clay Allsopp](https://twitter.com/clayallsopp) successfully ported [Propeller](http://usepropeller.com/blog/posts/from-backbone-to-react/), a fairly big, interaction-heavy JavaScript app, to React.

> [](http://usepropeller.com/blog/posts/from-backbone-to-react/)Subviews involve a lot of easy-to-forget boilerplate that Backbone (by design) doesn’t automate. Libraries like Backbone.Marionette offer more abstractions to make view nesting easier, but they’re all limited by the fact that Backbone delegates how and went view-document attachment occurs to the application code.
>
> React, on the other hand, manages the DOM and only exposes real nodes at select points in its API. The “elements” you code in React are actually objects which wrap DOM nodes, not the actual objects which get inserted into the DOM. Internally, React converts those abstractions into actual DOMElements and fills out the document accordingly. \[…]
>
> We moved about 20 different Backbone view classes to React over the past few weeks, including the live-preview pane that you see in our little iOS demo. Most importantly, it’s allowed us to put energy into making each component work great on its own, instead of spending extra cycles to ensure they function in unison. For that reason, we think React is a more scalable way to build view-intensive apps than Backbone alone, and it doesn’t require you to drop-everything-and-refactor like a move to Ember or Angular would demand.
>
> [Read the full post…](http://usepropeller.com/blog/posts/from-backbone-to-react/)

## [](#grunt-task-for-jsx)Grunt Task for JSX

[Eric Clemmons](https://ericclemmons.github.io/) wrote a task for [Grunt](http://gruntjs.com/) that applies the JSX transformation to your JavaScript files. It also works with [Browserify](http://browserify.org/) if you want all your files to be concatenated and minified together.

> Grunt task for compiling Facebook React’s .jsx templates into .js
>
> ```
> grunt.initConfig({
>   react: {
>     app: {
>       options: { extension: 'js' },
>       files: { 'path/to/output/dir': 'path/to/jsx/templates/dir' }
> ```
>
> It also works great with `grunt-browserify`!
>
> ```
> browserify: {
>   options: {
>     transform: [ require('grunt-react').browserify ]
>   },
>   app: {
>     src: 'path/to/source/main.js',
>     dest: 'path/to/target/output.js'
> ```
>
> [Check out the project …](https://github.com/ericclemmons/grunt-react)

## [](#backbonehandlebars-nested-views)Backbone/Handlebars Nested Views

[Joel Burget](http://joelburget.com/) wrote a blog post talking about the way we would write React-like components in Backbone and Handlebars.

> The problem here is that we’re trying to manipulate a tree, but there’s a textual layer we have to go through. Our views are represented as a tree - the subviews are children of CommentCollectionView - and they end up as part of a tree in the DOM. But there’s a Handlebars layer in the middle (which deals in flat strings), so the hierarchy must be destructed and rebuilt when we render.
>
> What does it take to render a collection view? In the Backbone/Handlebars view of the world you have to render the template (with stubs), render each subview which replaces a stub, and keep a reference to each subview (or anything within the view that could change in the future).
>
> So while our view is conceptually hierarchical, due to the fact that it has to go through a flat textual representation, we need to do a lot of extra work to reassemble that structure after rendering.
>
> [Read the full post…](http://joelburget.com/react/)

## [](#jsromandie-meetup)JSRomandie Meetup

[Renault John Lecoultre](https://twitter.com/renajohn/) from [BugBuster](http://www.bugbuster.com) did a React introduction talk at a JS meetup called [JS Romandie](https://twitter.com/jsromandie) last week.

## [](#coffeescript-integration)CoffeeScript integration

[Vjeux](http://blog.vjeux.com/) used the fact that JSX is just a syntactic sugar on-top of regular JS to rewrite the React front-page examples in CoffeeScript.

> Multiple people asked what’s the story about JSX and CoffeeScript. There is no JSX pre-processor for CoffeeScript and I’m not aware of anyone working on it. Fortunately, CoffeeScript is pretty expressive and we can play around the syntax to come up with something that is usable.
>
> ```
> {div, h3, textarea} = React.DOM
> (div {className: 'MarkdownEditor'}, [
>   (h3 {}, 'Input'),
>   (textarea {onKeyUp: @handleKeyUp, ref: 'textarea'},
>     @state.value
>   )
> ])
> ```
>
> [Read the full post…](http://blog.vjeux.com/2013/javascript/react-coffeescript.html)

## [](#tutorial-in-plain-javascript)Tutorial in Plain JavaScript

We’ve seen a lot of people comparing React with various frameworks. [Ricardo Tomasi](http://ricardo.cc/) decided to re-implement the tutorial without any framework, just plain JavaScript.

> Facebook & Instagram launched the React framework and an accompanying tutorial. Developer Vlad Yazhbin decided to rewrite that using AngularJS. The end result is pretty neat, but if you’re like me you will not actually appreciate the HTML speaking for itself and doing all the hard work. So let’s see what that looks like in plain javascript.
>
> [Read the full post…](http://ricardo.cc/2013/06/07/react-tutorial-rewritten-in-plain-javascript.html)

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2013-06-27-community-roundup-3.md)

----
url: https://react.dev/learn/queueing-a-series-of-state-updates
----

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function Counter() {
  const [number, setNumber] = useState(0);

  return (
    <>
      <h1>{number}</h1>
      <button onClick={() => {
        setNumber(number + 1);
        setNumber(number + 1);
        setNumber(number + 1);
      }}>+3</button>
    </>
  )
}
```

However, as you might recall from the previous section, [each render’s state values are fixed](/learn/state-as-a-snapshot#rendering-takes-a-snapshot-in-time), so the value of `number` inside the first render’s event handler is always `0`, no matter how many times you call `setNumber(1)`:

```
setNumber(0 + 1);

setNumber(0 + 1);

setNumber(0 + 1);
```

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function Counter() {
  const [number, setNumber] = useState(0);

  return (
    <>
      <h1>{number}</h1>
      <button onClick={() => {
        setNumber(n => n + 1);
        setNumber(n => n + 1);
        setNumber(n => n + 1);
      }}>+3</button>
    </>
  )
}
```

Here, `n => n + 1` is called an **updater function.** When you pass it to a state setter:

1. React queues this function to be processed after all the other code in the event handler has run.
2. During the next render, React goes through the queue and gives you the final updated state.

```
setNumber(n => n + 1);

setNumber(n => n + 1);

setNumber(n => n + 1);
```

Here’s how React works through these lines of code while executing the event handler:

1. `setNumber(n => n + 1)`: `n => n + 1` is a function. React adds it to a queue.
2. `setNumber(n => n + 1)`: `n => n + 1` is a function. React adds it to a queue.
3. `setNumber(n => n + 1)`: `n => n + 1` is a function. React adds it to a queue.

When you call `useState` during the next render, React goes through the queue. The previous `number` state was `0`, so that’s what React passes to the first updater function as the `n` argument. Then React takes the return value of your previous updater function and passes it to the next updater as `n`, and so on:

| queued update | `n` | returns     |
| ------------- | --- | ----------- |
| `n => n + 1`  | `0` | `0 + 1 = 1` |
| `n => n + 1`  | `1` | `1 + 1 = 2` |
| `n => n + 1`  | `2` | `2 + 1 = 3` |

React stores `3` as the final result and returns it from `useState`.

This is why clicking “+3” in the above example correctly increments the value by 3.

### What happens if you update state after replacing it[](#what-happens-if-you-update-state-after-replacing-it "Link for What happens if you update state after replacing it ")

What about this event handler? What do you think `number` will be in the next render?

```
<button onClick={() => {

  setNumber(number + 5);

  setNumber(n => n + 1);

}}>
```

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function Counter() {
  const [number, setNumber] = useState(0);

  return (
    <>
      <h1>{number}</h1>
      <button onClick={() => {
        setNumber(number + 5);
        setNumber(n => n + 1);
      }}>Increase the number</button>
    </>
  )
}
```

Here’s what this event handler tells React to do:

1. `setNumber(number + 5)`: `number` is `0`, so `setNumber(0 + 5)`. React adds *“replace with `5`”* to its queue.
2. `setNumber(n => n + 1)`: `n => n + 1` is an updater function. React adds *that function* to its queue.

During the next render, React goes through the state queue:

| queued update      | `n`          | returns     |
| ------------------ | ------------ | ----------- |
| ”replace with `5`” | `0` (unused) | `5`         |
| `n => n + 1`       | `5`          | `5 + 1 = 6` |

React stores `6` as the final result and returns it from `useState`.

### Note

You may have noticed that `setState(5)` actually works like `setState(n => 5)`, but `n` is unused!

### What happens if you replace state after updating it[](#what-happens-if-you-replace-state-after-updating-it "Link for What happens if you replace state after updating it ")

Let’s try one more example. What do you think `number` will be in the next render?

```
<button onClick={() => {

  setNumber(number + 5);

  setNumber(n => n + 1);

  setNumber(42);

}}>
```

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function Counter() {
  const [number, setNumber] = useState(0);

  return (
    <>
      <h1>{number}</h1>
      <button onClick={() => {
        setNumber(number + 5);
        setNumber(n => n + 1);
        setNumber(42);
      }}>Increase the number</button>
    </>
  )
}
```

Here’s how React works through these lines of code while executing this event handler:

1. `setNumber(number + 5)`: `number` is `0`, so `setNumber(0 + 5)`. React adds *“replace with `5`”* to its queue.
2. `setNumber(n => n + 1)`: `n => n + 1` is an updater function. React adds *that function* to its queue.
3. `setNumber(42)`: React adds *“replace with `42`”* to its queue.

During the next render, React goes through the state queue:

| queued update       | `n`          | returns     |
| ------------------- | ------------ | ----------- |
| ”replace with `5`”  | `0` (unused) | `5`         |
| `n => n + 1`        | `5`          | `5 + 1 = 6` |
| ”replace with `42`” | `6` (unused) | `42`        |

```
setEnabled(e => !e);

setLastName(ln => ln.reverse());

setFriendCount(fc => fc * 2);
```

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function RequestTracker() {
  const [pending, setPending] = useState(0);
  const [completed, setCompleted] = useState(0);

  async function handleClick() {
    setPending(pending + 1);
    await delay(3000);
    setPending(pending - 1);
    setCompleted(completed + 1);
  }

  return (
    <>
      <h3>
        Pending: {pending}
      </h3>
      <h3>
        Completed: {completed}
      </h3>
      <button onClick={handleClick}>
        Buy
      </button>
    </>
  );
}

function delay(ms) {
  return new Promise(resolve => {
    setTimeout(resolve, ms);
  });
}
```

[PreviousState as a Snapshot](/learn/state-as-a-snapshot)

[NextUpdating Objects in State](/learn/updating-objects-in-state)

***

----
url: https://react.dev/learn/referencing-values-with-refs
----

```
import { useRef } from 'react';
```

Inside your component, call the `useRef` Hook and pass the initial value that you want to reference as the only argument. For example, here is a ref to the value `0`:

```
const ref = useRef(0);
```

`useRef` returns an object like this:

```
{

  current: 0 // The value you passed to useRef

}
```

Illustrated by [Rachel Lee Nabors](https://nearestnabors.com/)

You can access the current value of that ref through the `ref.current` property. This value is intentionally mutable, meaning you can both read and write to it. It’s like a secret pocket of your component that React doesn’t track. (This is what makes it an “escape hatch” from React’s one-way data flow—more on that below!)

Here, a button will increment `ref.current` on every click:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useRef } from 'react';

export default function Counter() {
  let ref = useRef(0);

  function handleClick() {
    ref.current = ref.current + 1;
    alert('You clicked ' + ref.current + ' times!');
  }

  return (
    <button onClick={handleClick}>
      Click me!
    </button>
  );
}
```

The ref points to a number, but, like [state](/learn/state-a-components-memory), you could point to anything: a string, an object, or even a function. Unlike state, ref is a plain JavaScript object with the `current` property that you can read and modify.

Note that **the component doesn’t re-render with every increment.** Like state, refs are retained by React between re-renders. However, setting state re-renders a component. Changing a ref does not!

## Example: building a stopwatch[](#example-building-a-stopwatch "Link for Example: building a stopwatch ")

You can combine refs and state in a single component. For example, let’s make a stopwatch that the user can start or stop by pressing a button. In order to display how much time has passed since the user pressed “Start”, you will need to keep track of when the Start button was pressed and what the current time is. **This information is used for rendering, so you’ll keep it in state:**

```
const [startTime, setStartTime] = useState(null);

const [now, setNow] = useState(null);
```

When the user presses “Start”, you’ll use [`setInterval`](https://developer.mozilla.org/docs/Web/API/setInterval) in order to update the time every 10 milliseconds:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function Stopwatch() {
  const [startTime, setStartTime] = useState(null);
  const [now, setNow] = useState(null);

  function handleStart() {
    // Start counting.
    setStartTime(Date.now());
    setNow(Date.now());

    setInterval(() => {
      // Update the current time every 10ms.
      setNow(Date.now());
    }, 10);
  }

  let secondsPassed = 0;
  if (startTime != null && now != null) {
    secondsPassed = (now - startTime) / 1000;
  }

  return (
    <>
      <h1>Time passed: {secondsPassed.toFixed(3)}</h1>
      <button onClick={handleStart}>
        Start
      </button>
    </>
  );
}
```

When the “Stop” button is pressed, you need to cancel the existing interval so that it stops updating the `now` state variable. You can do this by calling [`clearInterval`](https://developer.mozilla.org/en-US/docs/Web/API/clearInterval), but you need to give it the interval ID that was previously returned by the `setInterval` call when the user pressed Start. You need to keep the interval ID somewhere. **Since the interval ID is not used for rendering, you can keep it in a ref:**

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useRef } from 'react';

export default function Stopwatch() {
  const [startTime, setStartTime] = useState(null);
  const [now, setNow] = useState(null);
  const intervalRef = useRef(null);

  function handleStart() {
    setStartTime(Date.now());
    setNow(Date.now());

    clearInterval(intervalRef.current);
    intervalRef.current = setInterval(() => {
      setNow(Date.now());
    }, 10);
  }

  function handleStop() {
    clearInterval(intervalRef.current);
  }

  let secondsPassed = 0;
  if (startTime != null && now != null) {
    secondsPassed = (now - startTime) / 1000;
  }

  return (
    <>
      <h1>Time passed: {secondsPassed.toFixed(3)}</h1>
      <button onClick={handleStart}>
        Start
      </button>
      <button onClick={handleStop}>
        Stop
      </button>
    </>
  );
}
```

When a piece of information is used for rendering, keep it in state. When a piece of information is only needed by event handlers and changing it doesn’t require a re-render, using a ref may be more efficient.

## Differences between refs and state[](#differences-between-refs-and-state "Link for Differences between refs and state ")

Perhaps you’re thinking refs seem less “strict” than state—you can mutate them instead of always having to use a state setting function, for instance. But in most cases, you’ll want to use state. Refs are an “escape hatch” you won’t need often. Here’s how state and refs compare:

| refs                                                                                  | state                                                                                                                                   |
| ------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| `useRef(initialValue)` returns `{ current: initialValue }`                            | `useState(initialValue)` returns the current value of a state variable and a state setter function ( `[value, setValue]`)               |
| Doesn’t trigger re-render when you change it.                                         | Triggers re-render when you change it.                                                                                                  |
| Mutable—you can modify and update `current`’s value outside of the rendering process. | ”Immutable”—you must use the state setting function to modify state variables to queue a re-render.                                     |
| You shouldn’t read (or write) the `current` value during rendering.                   | You can read state at any time. However, each render has its own [snapshot](/learn/state-as-a-snapshot) of state which does not change. |

Here is a counter button that’s implemented with state:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function Counter() {
  const [count, setCount] = useState(0);

  function handleClick() {
    setCount(count + 1);
  }

  return (
    <button onClick={handleClick}>
      You clicked {count} times
    </button>
  );
}
```

Because the `count` value is displayed, it makes sense to use a state value for it. When the counter’s value is set with `setCount()`, React re-renders the component and the screen updates to reflect the new count.

If you tried to implement this with a ref, React would never re-render the component, so you’d never see the count change! See how clicking this button **does not update its text**:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useRef } from 'react';

export default function Counter() {
  let countRef = useRef(0);

  function handleClick() {
    // This doesn't re-render the component!
    countRef.current = countRef.current + 1;
  }

  return (
    <button onClick={handleClick}>
      You clicked {countRef.current} times
    </button>
  );
}
```

This is why reading `ref.current` during render leads to unreliable code. If you need that, use state instead.

##### Deep Dive#### How does useRef work inside?[](#how-does-use-ref-work-inside "Link for How does useRef work inside? ")

Although both `useState` and `useRef` are provided by React, in principle `useRef` could be implemented *on top of* `useState`. You can imagine that inside of React, `useRef` is implemented like this:

```
// Inside of React

function useRef(initialValue) {

  const [ref, unused] = useState({ current: initialValue });

  return ref;

}
```

```
ref.current = 5;

console.log(ref.current); // 5
```

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function Chat() {
  const [text, setText] = useState('');
  const [isSending, setIsSending] = useState(false);
  let timeoutID = null;

  function handleSend() {
    setIsSending(true);
    timeoutID = setTimeout(() => {
      alert('Sent!');
      setIsSending(false);
    }, 3000);
  }

  function handleUndo() {
    setIsSending(false);
    clearTimeout(timeoutID);
  }

  return (
    <>
      <input
        disabled={isSending}
        value={text}
        onChange={e => setText(e.target.value)}
      />
      <button
        disabled={isSending}
        onClick={handleSend}>
        {isSending ? 'Sending...' : 'Send'}
      </button>
      {isSending &&
        <button onClick={handleUndo}>
          Undo
        </button>
      }
    </>
  );
}
```

[PreviousEscape Hatches](/learn/escape-hatches)

[NextManipulating the DOM with Refs](/learn/manipulating-the-dom-with-refs)

***

----
url: https://legacy.reactjs.org/docs/rendering-elements.html
----

> These docs are old and won’t be updated. Go to [react.dev](https://react.dev/) for the new React docs.
>
> These new documentation pages teach how to write JSX and show it on an HTML page:
>
> * [Writing Markup with JSX](https://react.dev/learn/writing-markup-with-jsx)
> * [Add React to an Existing Project](https://react.dev/learn/add-react-to-an-existing-project#step-2-render-react-components-anywhere-on-the-page)

Elements are the smallest building blocks of React apps.

An element describes what you want to see on the screen:

```
const element = <h1>Hello, world</h1>;
```

Unlike browser DOM elements, React elements are plain objects, and are cheap to create. React DOM takes care of updating the DOM to match the React elements.

> **Note:**
>
> One might confuse elements with a more widely known concept of “components”. We will introduce components in the [next section](/docs/components-and-props.html). Elements are what components are “made of”, and we encourage you to read this section before jumping ahead.

## [](#rendering-an-element-into-the-dom)Rendering an Element into the DOM

Let’s say there is a `<div>` somewhere in your HTML file:

```
<div id="root"></div>
```

We call this a “root” DOM node because everything inside it will be managed by React DOM.

Applications built with just React usually have a single root DOM node. If you are integrating React into an existing app, you may have as many isolated root DOM nodes as you like.

To render a React element, first pass the DOM element to [`ReactDOM.createRoot()`](/docs/react-dom-client.html#createroot), then pass the React element to `root.render()`:

```
const root = ReactDOM.createRoot(
  document.getElementById('root')
);
const element = <h1>Hello, world</h1>;
root.render(element);
```

**[Try it on CodePen](https://codepen.io/gaearon/pen/ZpvBNJ?editors=1010)**

It displays “Hello, world” on the page.

## [](#updating-the-rendered-element)Updating the Rendered Element

React elements are [immutable](https://en.wikipedia.org/wiki/Immutable_object). Once you create an element, you can’t change its children or attributes. An element is like a single frame in a movie: it represents the UI at a certain point in time.

With our knowledge so far, the only way to update the UI is to create a new element, and pass it to `root.render()`.

Consider this ticking clock example:

```
const root = ReactDOM.createRoot(
  document.getElementById('root')
);

function tick() {
  const element = (
    <div>
      <h1>Hello, world!</h1>
      <h2>It is {new Date().toLocaleTimeString()}.</h2>
    </div>
  );
  root.render(element);}

setInterval(tick, 1000);
```

**[Try it on CodePen](https://codepen.io/gaearon/pen/gwoJZk?editors=1010)**

It calls [`root.render()`](/docs/react-dom.html#render) every second from a [`setInterval()`](https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setInterval) callback.

> **Note:**
>
> In practice, most React apps only call `root.render()` once. In the next sections we will learn how such code gets encapsulated into [stateful components](/docs/state-and-lifecycle.html).
>
> We recommend that you don’t skip topics because they build on each other.

## [](#react-only-updates-whats-necessary)React Only Updates What’s Necessary

React DOM compares the element and its children to the previous one, and only applies the DOM updates necessary to bring the DOM to the desired state.

You can verify by inspecting the [last example](https://codepen.io/gaearon/pen/gwoJZk?editors=1010) with the browser tools:

Even though we create an element describing the whole UI tree on every tick, only the text node whose contents have changed gets updated by React DOM.

In our experience, thinking about how the UI should look at any given moment, rather than how to change it over time, eliminates a whole class of bugs.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/rendering-elements.md)

* Previous article

  [Introducing JSX](/docs/introducing-jsx.html)

* Next article

  [Components and Props](/docs/components-and-props.html)

----
url: https://react.dev/reference/react/useReducer
----

[API Reference](/reference/react)

[Hooks](/reference/react/hooks)

# useReducer[](#undefined "Link for this heading")

`useReducer` is a React Hook that lets you add a [reducer](/learn/extracting-state-logic-into-a-reducer) to your component.

```
const [state, dispatch] = useReducer(reducer, initialArg, init?)
```

***

## Reference[](#reference "Link for Reference ")

### `useReducer(reducer, initialArg, init?)`[](#usereducer "Link for this heading")

Call `useReducer` at the top level of your component to manage its state with a [reducer.](/learn/extracting-state-logic-into-a-reducer)

```
import { useReducer } from 'react';



function reducer(state, action) {

  // ...

}



function MyComponent() {

  const [state, dispatch] = useReducer(reducer, { age: 42 });

  // ...
```

***

### `dispatch` function[](#dispatch "Link for this heading")

The `dispatch` function returned by `useReducer` lets you update the state to a different value and trigger a re-render. You need to pass the action as the only argument to the `dispatch` function:

```
const [state, dispatch] = useReducer(reducer, { age: 42 });



function handleClick() {

  dispatch({ type: 'incremented_age' });

  // ...
```

***

## Usage[](#usage "Link for Usage ")

### Adding a reducer to a component[](#adding-a-reducer-to-a-component "Link for Adding a reducer to a component ")

Call `useReducer` at the top level of your component to manage state with a [reducer.](/learn/extracting-state-logic-into-a-reducer)

```
import { useReducer } from 'react';



function reducer(state, action) {

  // ...

}



function MyComponent() {

  const [state, dispatch] = useReducer(reducer, { age: 42 });

  // ...
```

`useReducer` returns an array with exactly two items:

1. The current state of this state variable, initially set to the initial state you provided.
2. The `dispatch` function that lets you change it in response to interaction.

To update what’s on the screen, call `dispatch` with an object representing what the user did, called an *action*:

```
function handleClick() {

  dispatch({ type: 'incremented_age' });

}
```

React will pass the current state and the action to your reducer function. Your reducer will calculate and return the next state. React will store that next state, render your component with it, and update the UI.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useReducer } from 'react';

function reducer(state, action) {
  if (action.type === 'incremented_age') {
    return {
      age: state.age + 1
    };
  }
  throw Error('Unknown action.');
}

export default function Counter() {
  const [state, dispatch] = useReducer(reducer, { age: 42 });

  return (
    <>
      <button onClick={() => {
        dispatch({ type: 'incremented_age' })
      }}>
        Increment age
      </button>
      <p>Hello! You are {state.age}.</p>
    </>
  );
}
```

`useReducer` is very similar to [`useState`](/reference/react/useState), but it lets you move the state update logic from event handlers into a single function outside of your component. Read more about [choosing between `useState` and `useReducer`.](/learn/extracting-state-logic-into-a-reducer#comparing-usestate-and-usereducer)

***

### Writing the reducer function[](#writing-the-reducer-function "Link for Writing the reducer function ")

A reducer function is declared like this:

```
function reducer(state, action) {

  // ...

}
```

Then you need to fill in the code that will calculate and return the next state. By convention, it is common to write it as a [`switch` statement.](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/switch) For each `case` in the `switch`, calculate and return some next state.

```
function reducer(state, action) {

  switch (action.type) {

    case 'incremented_age': {

      return {

        name: state.name,

        age: state.age + 1

      };

    }

    case 'changed_name': {

      return {

        name: action.nextName,

        age: state.age

      };

    }

  }

  throw Error('Unknown action: ' + action.type);

}
```

Actions can have any shape. By convention, it’s common to pass objects with a `type` property identifying the action. It should include the minimal necessary information that the reducer needs to compute the next state.

```
function Form() {

  const [state, dispatch] = useReducer(reducer, { name: 'Taylor', age: 42 });



  function handleButtonClick() {

    dispatch({ type: 'incremented_age' });

  }



  function handleInputChange(e) {

    dispatch({

      type: 'changed_name',

      nextName: e.target.value

    });

  }

  // ...
```

The action type names are local to your component. [Each action describes a single interaction, even if that leads to multiple changes in data.](/learn/extracting-state-logic-into-a-reducer#writing-reducers-well) The shape of the state is arbitrary, but usually it’ll be an object or an array.

Read [extracting state logic into a reducer](/learn/extracting-state-logic-into-a-reducer) to learn more.

### Pitfall

State is read-only. Don’t modify any objects or arrays in state:

```
function reducer(state, action) {

  switch (action.type) {

    case 'incremented_age': {

      // 🚩 Don't mutate an object in state like this:

      state.age = state.age + 1;

      return state;

    }
```

Instead, always return new objects from your reducer:

```
function reducer(state, action) {

  switch (action.type) {

    case 'incremented_age': {

      // ✅ Instead, return a new object

      return {

        ...state,

        age: state.age + 1

      };

    }
```

Read [updating objects in state](/learn/updating-objects-in-state) and [updating arrays in state](/learn/updating-arrays-in-state) to learn more.

#### Basic useReducer examples[](#examples-basic "Link for Basic useReducer examples")

#### Example 1 of 3:Form (object)[](#form-object "Link for this heading")

In this example, the reducer manages a state object with two fields: `name` and `age`.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useReducer } from 'react';

function reducer(state, action) {
  switch (action.type) {
    case 'incremented_age': {
      return {
        name: state.name,
        age: state.age + 1
      };
    }
    case 'changed_name': {
      return {
        name: action.nextName,
        age: state.age
      };
    }
  }
  throw Error('Unknown action: ' + action.type);
}

const initialState = { name: 'Taylor', age: 42 };

export default function Form() {
  const [state, dispatch] = useReducer(reducer, initialState);

  function handleButtonClick() {
    dispatch({ type: 'incremented_age' });
  }

  function handleInputChange(e) {
    dispatch({
      type: 'changed_name',
      nextName: e.target.value
    });
  }

  return (
    <>
      <input
        value={state.name}
        onChange={handleInputChange}
      />
      <button onClick={handleButtonClick}>
        Increment age
      </button>
      <p>Hello, {state.name}. You are {state.age}.</p>
    </>
  );
}
```

***

### Avoiding recreating the initial state[](#avoiding-recreating-the-initial-state "Link for Avoiding recreating the initial state ")

React saves the initial state once and ignores it on the next renders.

```
function createInitialState(username) {

  // ...

}



function TodoList({ username }) {

  const [state, dispatch] = useReducer(reducer, createInitialState(username));

  // ...
```

Although the result of `createInitialState(username)` is only used for the initial render, you’re still calling this function on every render. This can be wasteful if it’s creating large arrays or performing expensive calculations.

To solve this, you may **pass it as an *initializer* function** to `useReducer` as the third argument instead:

```
function createInitialState(username) {

  // ...

}



function TodoList({ username }) {

  const [state, dispatch] = useReducer(reducer, username, createInitialState);

  // ...
```

Notice that you’re passing `createInitialState`, which is the *function itself*, and not `createInitialState()`, which is the result of calling it. This way, the initial state does not get re-created after initialization.

In the above example, `createInitialState` takes a `username` argument. If your initializer doesn’t need any information to compute the initial state, you may pass `null` as the second argument to `useReducer`.

#### The difference between passing an initializer and passing the initial state directly[](#examples-initializer "Link for The difference between passing an initializer and passing the initial state directly")

#### Example 1 of 2:Passing the initializer function[](#passing-the-initializer-function "Link for this heading")

This example passes the initializer function, so the `createInitialState` function only runs during initialization. It does not run when component re-renders, such as when you type into the input.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useReducer } from 'react';

function createInitialState(username) {
  const initialTodos = [];
  for (let i = 0; i < 50; i++) {
    initialTodos.push({
      id: i,
      text: username + "'s task #" + (i + 1)
    });
  }
  return {
    draft: '',
    todos: initialTodos,
  };
}

function reducer(state, action) {
  switch (action.type) {
    case 'changed_draft': {
      return {
        draft: action.nextDraft,
        todos: state.todos,
      };
    };
    case 'added_todo': {
      return {
        draft: '',
        todos: [{
          id: state.todos.length,
          text: state.draft
        }, ...state.todos]
      }
    }
  }
  throw Error('Unknown action: ' + action.type);
}

export default function TodoList({ username }) {
  const [state, dispatch] = useReducer(
    reducer,
    username,
    createInitialState
  );
  return (
    <>
      <input
        value={state.draft}
        onChange={e => {
          dispatch({
            type: 'changed_draft',
            nextDraft: e.target.value
          })
        }}
      />
      <button onClick={() => {
        dispatch({ type: 'added_todo' });
      }}>Add</button>
      <ul>
        {state.todos.map(item => (
          <li key={item.id}>
            {item.text}
          </li>
        ))}
      </ul>
    </>
  );
}
```

***

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### I’ve dispatched an action, but logging gives me the old state value[](#ive-dispatched-an-action-but-logging-gives-me-the-old-state-value "Link for I’ve dispatched an action, but logging gives me the old state value ")

Calling the `dispatch` function **does not change state in the running code**:

```
function handleClick() {

  console.log(state.age);  // 42



  dispatch({ type: 'incremented_age' }); // Request a re-render with 43

  console.log(state.age);  // Still 42!



  setTimeout(() => {

    console.log(state.age); // Also 42!

  }, 5000);

}
```

This is because [states behaves like a snapshot.](/learn/state-as-a-snapshot) Updating state requests another render with the new state value, but does not affect the `state` JavaScript variable in your already-running event handler.

If you need to guess the next state value, you can calculate it manually by calling the reducer yourself:

```
const action = { type: 'incremented_age' };

dispatch(action);



const nextState = reducer(state, action);

console.log(state);     // { age: 42 }

console.log(nextState); // { age: 43 }
```

***

### I’ve dispatched an action, but the screen doesn’t update[](#ive-dispatched-an-action-but-the-screen-doesnt-update "Link for I’ve dispatched an action, but the screen doesn’t update ")

React will **ignore your update if the next state is equal to the previous state,** as determined by an [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) comparison. This usually happens when you change an object or an array in state directly:

```
function reducer(state, action) {

  switch (action.type) {

    case 'incremented_age': {

      // 🚩 Wrong: mutating existing object

      state.age++;

      return state;

    }

    case 'changed_name': {

      // 🚩 Wrong: mutating existing object

      state.name = action.nextName;

      return state;

    }

    // ...

  }

}
```

You mutated an existing `state` object and returned it, so React ignored the update. To fix this, you need to ensure that you’re always [updating objects in state](/learn/updating-objects-in-state) and [updating arrays in state](/learn/updating-arrays-in-state) instead of mutating them:

```
function reducer(state, action) {

  switch (action.type) {

    case 'incremented_age': {

      // ✅ Correct: creating a new object

      return {

        ...state,

        age: state.age + 1

      };

    }

    case 'changed_name': {

      // ✅ Correct: creating a new object

      return {

        ...state,

        name: action.nextName

      };

    }

    // ...

  }

}
```

***

### A part of my reducer state becomes undefined after dispatching[](#a-part-of-my-reducer-state-becomes-undefined-after-dispatching "Link for A part of my reducer state becomes undefined after dispatching ")

Make sure that every `case` branch **copies all of the existing fields** when returning the new state:

```
function reducer(state, action) {

  switch (action.type) {

    case 'incremented_age': {

      return {

        ...state, // Don't forget this!

        age: state.age + 1

      };

    }

    // ...
```

Without `...state` above, the returned next state would only contain the `age` field and nothing else.

***

### My entire reducer state becomes undefined after dispatching[](#my-entire-reducer-state-becomes-undefined-after-dispatching "Link for My entire reducer state becomes undefined after dispatching ")

If your state unexpectedly becomes `undefined`, you’re likely forgetting to `return` state in one of the cases, or your action type doesn’t match any of the `case` statements. To find why, throw an error outside the `switch`:

```
function reducer(state, action) {

  switch (action.type) {

    case 'incremented_age': {

      // ...

    }

    case 'edited_name': {

      // ...

    }

  }

  throw Error('Unknown action: ' + action.type);

}
```

You can also use a static type checker like TypeScript to catch such mistakes.

***

### I’m getting an error: “Too many re-renders”[](#im-getting-an-error-too-many-re-renders "Link for I’m getting an error: “Too many re-renders” ")

You might get an error that says: `Too many re-renders. React limits the number of renders to prevent an infinite loop.` Typically, this means that you’re unconditionally dispatching an action *during render*, so your component enters a loop: render, dispatch (which causes a render), render, dispatch (which causes a render), and so on. Very often, this is caused by a mistake in specifying an event handler:

```
// 🚩 Wrong: calls the handler during render

return <button onClick={handleClick()}>Click me</button>



// ✅ Correct: passes down the event handler

return <button onClick={handleClick}>Click me</button>



// ✅ Correct: passes down an inline function

return <button onClick={(e) => handleClick(e)}>Click me</button>
```

If you can’t find the cause of this error, click on the arrow next to the error in the console and look through the JavaScript stack to find the specific `dispatch` function call responsible for the error.

***

### My reducer or initializer function runs twice[](#my-reducer-or-initializer-function-runs-twice "Link for My reducer or initializer function runs twice ")

In [Strict Mode](/reference/react/StrictMode), React will call your reducer and initializer functions twice. This shouldn’t break your code.

This **development-only** behavior helps you [keep components pure.](/learn/keeping-components-pure) React uses the result of one of the calls, and ignores the result of the other call. As long as your component, initializer, and reducer functions are pure, this shouldn’t affect your logic. However, if they are accidentally impure, this helps you notice the mistakes.

For example, this impure reducer function mutates an array in state:

```
function reducer(state, action) {

  switch (action.type) {

    case 'added_todo': {

      // 🚩 Mistake: mutating state

      state.todos.push({ id: nextId++, text: action.text });

      return state;

    }

    // ...

  }

}
```

Because React calls your reducer function twice, you’ll see the todo was added twice, so you’ll know that there is a mistake. In this example, you can fix the mistake by [replacing the array instead of mutating it](/learn/updating-arrays-in-state#adding-to-an-array):

```
function reducer(state, action) {

  switch (action.type) {

    case 'added_todo': {

      // ✅ Correct: replacing with new state

      return {

        ...state,

        todos: [

          ...state.todos,

          { id: nextId++, text: action.text }

        ]

      };

    }

    // ...

  }

}
```

Now that this reducer function is pure, calling it an extra time doesn’t make a difference in behavior. This is why React calling it twice helps you find mistakes. **Only component, initializer, and reducer functions need to be pure.** Event handlers don’t need to be pure, so React will never call your event handlers twice.

Read [keeping components pure](/learn/keeping-components-pure) to learn more.

[PrevioususeOptimistic](/reference/react/useOptimistic)

[NextuseRef](/reference/react/useRef)

***

----
url: https://18.react.dev/reference/react/act
----

[API Reference](/reference/react)

[APIs](/reference/react/apis)

# act[](#undefined "Link for this heading")

`act` is a test helper to apply pending React updates before making assertions.

```
await act(async actFn)
```

  * [I’m getting an error: “The current testing environment is not configured to support act”(…)”](#error-the-current-testing-environment-is-not-configured-to-support-act)

***

## Reference[](#reference "Link for Reference ")

### `await act(async actFn)`[](#await-act-async-actfn "Link for this heading")

When writing UI tests, tasks like rendering, user events, or data fetching can be considered as “units” of interaction with a user interface. React provides a helper called `act()` that makes sure all updates related to these “units” have been processed and applied to the DOM before you make any assertions.

The name `act` comes from the [Arrange-Act-Assert](https://wiki.c2.com/?ArrangeActAssert) pattern.

```
it ('renders with button disabled', async () => {

  await act(async () => {

    root.render(<TestComponent />)

  });

  expect(container.querySelector('button')).toBeDisabled();

});
```

```
function Counter() {

  const [count, setCount] = useState(0);

  const handleClick = () => {

    setCount(prev => prev + 1);

  }



  useEffect(() => {

    document.title = `You clicked ${this.state.count} times`;

  }, [count]);



  return (

    <div>

      <p>You clicked {this.state.count} times</p>

      <button onClick={this.handleClick}>

        Click me

      </button>

    </div>

  )

}
```

### Rendering components in tests[](#rendering-components-in-tests "Link for Rendering components in tests ")

To test the render output of a component, wrap the render inside `act()`:

```
import {act} from 'react';

import ReactDOMClient from 'react-dom/client';

import Counter from './Counter';



it('can render and update a counter', async () => {

  container = document.createElement('div');

  document.body.appendChild(container);

  

  // ✅ Render the component inside act().

  await act(() => {

    ReactDOMClient.createRoot(container).render(<Counter />);

  });

  

  const button = container.querySelector('button');

  const label = container.querySelector('p');

  expect(label.textContent).toBe('You clicked 0 times');

  expect(document.title).toBe('You clicked 0 times');

});
```

Here, we create a container, append it to the document, and render the `Counter` component inside `act()`. This ensures that the component is rendered and its effects are applied before making assertions.

Using `act` ensures that all updates have been applied before we make assertions.

### Dispatching events in tests[](#dispatching-events-in-tests "Link for Dispatching events in tests ")

To test events, wrap the event dispatch inside `act()`:

```
import {act} from 'react';

import ReactDOMClient from 'react-dom/client';

import Counter from './Counter';



it.only('can render and update a counter', async () => {

  const container = document.createElement('div');

  document.body.appendChild(container);

  

  await act( async () => {

    ReactDOMClient.createRoot(container).render(<Counter />);

  });

  

  // ✅ Dispatch the event inside act().

  await act(async () => {

    button.dispatchEvent(new MouseEvent('click', { bubbles: true }));

  });



  const button = container.querySelector('button');

  const label = container.querySelector('p');

  expect(label.textContent).toBe('You clicked 1 times');

  expect(document.title).toBe('You clicked 1 times');

});
```

Here, we render the component with `act`, and then dispatch the event inside another `act()`. This ensures that all updates from the event are applied before making assertions.

### Pitfall

Don’t forget that dispatching DOM events only works when the DOM container is added to the document. You can use a library like [React Testing Library](https://testing-library.com/docs/react-testing-library/intro) to reduce the boilerplate code.

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### I’m getting an error: “The current testing environment is not configured to support act”(…)”[](#error-the-current-testing-environment-is-not-configured-to-support-act "Link for I’m getting an error: “The current testing environment is not configured to support act”(…)” ")

Using `act` requires setting `global.IS_REACT_ACT_ENVIRONMENT=true` in your test environment. This is to ensure that `act` is only used in the correct environment.

If you don’t set the global, you will see an error like this:

Console

Warning: The current testing environment is not configured to support act(…)

To fix, add this to your global setup file for React tests:

```
global.IS_REACT_ACT_ENVIRONMENT=true
```

### Note

In testing frameworks like [React Testing Library](https://testing-library.com/docs/react-testing-library/intro), `IS_REACT_ACT_ENVIRONMENT` is already set for you.

[PreviousAPIs](/reference/react/apis)

[Nextcache](/reference/react/cache)

***

----
url: https://18.react.dev/reference/react/experimental_useEffectEvent
----

[API Reference](/reference/react)

# experimental\_useEffectEvent[](#undefined "Link for this heading")

### Under Construction

**This API is experimental and is not available in a stable version of React yet.**

You can try it by upgrading React packages to the most recent experimental version:

* `react@experimental`
* `react-dom@experimental`
* `eslint-plugin-react-hooks@experimental`

Experimental versions of React may contain bugs. Don’t use them in production.

`useEffectEvent` is a React Hook that lets you extract non-reactive logic into an [Effect Event.](/learn/separating-events-from-effects#declaring-an-effect-event)

```
const onSomething = useEffectEvent(callback)
```

***

----
url: https://legacy.reactjs.org/docs/typechecking-with-proptypes.html
----

> These docs are old and won’t be updated. Go to [react.dev](https://react.dev/) for the new React docs.
>
> PropTypes aren’t commonly used in modern React. Use TypeScript for static type checking.

> Note:
>
> `React.PropTypes` has moved into a different package since React v15.5. Please use [the `prop-types` library instead](https://www.npmjs.com/package/prop-types).
>
> We provide [a codemod script](/blog/2017/04/07/react-v15.5.0.html#migrating-from-reactproptypes) to automate the conversion.

As your app grows, you can catch a lot of bugs with typechecking. For some applications, you can use JavaScript extensions like [Flow](https://flow.org/) or [TypeScript](https://www.typescriptlang.org/) to typecheck your whole application. But even if you don’t use those, React has some built-in typechecking abilities. To run typechecking on the props for a component, you can assign the special `propTypes` property:

```
import PropTypes from 'prop-types';

class Greeting extends React.Component {
  render() {
    return (
      <h1>Hello, {this.props.name}</h1>
    );
  }
}

Greeting.propTypes = {
  name: PropTypes.string
};
```

In this example, we are using a class component, but the same functionality could also be applied to function components, or components created by [`React.memo`](/docs/react-api.html#reactmemo) or [`React.forwardRef`](/docs/react-api.html#reactforwardref).

`PropTypes` exports a range of validators that can be used to make sure the data you receive is valid. In this example, we’re using `PropTypes.string`. When an invalid value is provided for a prop, a warning will be shown in the JavaScript console. For performance reasons, `propTypes` is only checked in development mode.

### [](#proptypes)PropTypes

Here is an example documenting the different validators provided:

```
import PropTypes from 'prop-types';

MyComponent.propTypes = {
  // You can declare that a prop is a specific JS type. By default, these
  // are all optional.
  optionalArray: PropTypes.array,
  optionalBool: PropTypes.bool,
  optionalFunc: PropTypes.func,
  optionalNumber: PropTypes.number,
  optionalObject: PropTypes.object,
  optionalString: PropTypes.string,
  optionalSymbol: PropTypes.symbol,

  // Anything that can be rendered: numbers, strings, elements or an array
  // (or fragment) containing these types.
  optionalNode: PropTypes.node,

  // A React element.
  optionalElement: PropTypes.element,

  // A React element type (ie. MyComponent).
  optionalElementType: PropTypes.elementType,

  // You can also declare that a prop is an instance of a class. This uses
  // JS's instanceof operator.
  optionalMessage: PropTypes.instanceOf(Message),

  // You can ensure that your prop is limited to specific values by treating
  // it as an enum.
  optionalEnum: PropTypes.oneOf(['News', 'Photos']),

  // An object that could be one of many types
  optionalUnion: PropTypes.oneOfType([
    PropTypes.string,
    PropTypes.number,
    PropTypes.instanceOf(Message)
  ]),

  // An array of a certain type
  optionalArrayOf: PropTypes.arrayOf(PropTypes.number),

  // An object with property values of a certain type
  optionalObjectOf: PropTypes.objectOf(PropTypes.number),

  // An object taking on a particular shape
  optionalObjectWithShape: PropTypes.shape({
    color: PropTypes.string,
    fontSize: PropTypes.number
  }),

  // An object with warnings on extra properties
  optionalObjectWithStrictShape: PropTypes.exact({
    name: PropTypes.string,
    quantity: PropTypes.number
  }),   

  // You can chain any of the above with `isRequired` to make sure a warning
  // is shown if the prop isn't provided.
  requiredFunc: PropTypes.func.isRequired,

  // A required value of any data type
  requiredAny: PropTypes.any.isRequired,

  // You can also specify a custom validator. It should return an Error
  // object if the validation fails. Don't `console.warn` or throw, as this
  // won't work inside `oneOfType`.
  customProp: function(props, propName, componentName) {
    if (!/matchme/.test(props[propName])) {
      return new Error(
        'Invalid prop `' + propName + '` supplied to' +
        ' `' + componentName + '`. Validation failed.'
      );
    }
  },

  // You can also supply a custom validator to `arrayOf` and `objectOf`.
  // It should return an Error object if the validation fails. The validator
  // will be called for each key in the array or object. The first two
  // arguments of the validator are the array or object itself, and the
  // current item's key.
  customArrayProp: PropTypes.arrayOf(function(propValue, key, componentName, location, propFullName) {
    if (!/matchme/.test(propValue[key])) {
      return new Error(
        'Invalid prop `' + propFullName + '` supplied to' +
        ' `' + componentName + '`. Validation failed.'
      );
    }
  })
};
```

### [](#requiring-single-child)Requiring Single Child

With `PropTypes.element` you can specify that only a single child can be passed to a component as children.

```
import PropTypes from 'prop-types';

class MyComponent extends React.Component {
  render() {
    // This must be exactly one element or it will warn.
    const children = this.props.children;
    return (
      <div>
        {children}
      </div>
    );
  }
}

MyComponent.propTypes = {
  children: PropTypes.element.isRequired
};
```

### [](#default-prop-values)Default Prop Values

You can define default values for your `props` by assigning to the special `defaultProps` property:

```
class Greeting extends React.Component {
  render() {
    return (
      <h1>Hello, {this.props.name}</h1>
    );
  }
}

// Specifies the default values for props:
Greeting.defaultProps = {
  name: 'Stranger'
};

// Renders "Hello, Stranger":
const root = ReactDOM.createRoot(document.getElementById('example')); 
root.render(<Greeting />);
```

Since ES2022 you can also declare `defaultProps` as static property within a React component class. For more information, see the [class public static fields](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Public_class_fields#public_static_fields). This modern syntax will require a compilation step to work within older browsers.

```
class Greeting extends React.Component {
  static defaultProps = {
    name: 'stranger'
  }

  render() {
    return (
      <div>Hello, {this.props.name}</div>
    )
  }
}
```

The `defaultProps` will be used to ensure that `this.props.name` will have a value if it was not specified by the parent component. The `propTypes` typechecking happens after `defaultProps` are resolved, so typechecking will also apply to the `defaultProps`.

### [](#function-components)Function Components

If you are using function components in your regular development, you may want to make some small changes to allow PropTypes to be properly applied.

Let’s say you have a component like this:

```
export default function HelloWorldComponent({ name }) {
  return (
    <div>Hello, {name}</div>
  )
}
```

To add PropTypes, you may want to declare the component in a separate function before exporting, like this:

```
function HelloWorldComponent({ name }) {
  return (
    <div>Hello, {name}</div>
  )
}

export default HelloWorldComponent
```

Then, you can add PropTypes directly to the `HelloWorldComponent`:

```
import PropTypes from 'prop-types'

function HelloWorldComponent({ name }) {
  return (
    <div>Hello, {name}</div>
  )
}

HelloWorldComponent.propTypes = {
  name: PropTypes.string
}

export default HelloWorldComponent
```

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/typechecking-with-proptypes.md)

----
url: https://react.dev/blog/2025/10/16/react-conf-2025-recap
----

[Blog](/blog)

# React Conf 2025 Recap[](#undefined "Link for this heading")

Oct 16, 2025 by [Matt Carroll](https://x.com/mattcarrollcode) and [Ricky Hanlon](https://bsky.app/profile/ricky.fm)

***

Last week we hosted React Conf 2025 where we announced the [React Foundation](/blog/2025/10/07/introducing-the-react-foundation) and showcased new features coming to React and React Native.

***

React Conf 2025 was held on October 7-8, 2025, in Henderson, Nevada.

The entire [day 1](https://www.youtube.com/watch?v=zyVRg2QR6LA\&t=1067s) and [day 2](https://www.youtube.com/watch?v=p9OcztRyDl0\&t=2299s) streams are available online, and you can view photos from the event [here](https://conf.react.dev/photos).

In this post, we’ll summarize the talks and announcements from the event.

## Day 1 Keynote[](#day-1-keynote "Link for Day 1 Keynote ")

*Watch the full day 1 stream [here.](https://www.youtube.com/watch?v=zyVRg2QR6LA\&t=1067s)*

In the day 1 keynote, Joe Savona shared the updates from the team and community since the last React Conf and highlights from React 19.0 and 19.1.

Mofei Zhang highlighted the new features in React 19.2 including:

* [`<Activity />`](https://react.dev/reference/react/Activity) — a new component to manage visibility.
* [`useEffectEvent`](https://react.dev/reference/react/useEffectEvent) to fire events from Effects.
* [Performance Tracks](https://react.dev/reference/dev-tools/react-performance-tracks) — a new profiling tool in DevTools.
* [Partial Pre-Rendering](https://react.dev/blog/2025/10/01/react-19-2#partial-pre-rendering) to pre-render part of an app ahead of time, and resume rendering it later.

Jack Pope announced new features in Canary including:

* [`<ViewTransition />`](https://react.dev/reference/react/ViewTransition) — a new component to animate page transitions.
* [Fragment Refs](https://react.dev/reference/react/Fragment#fragmentinstance) — a new way to interact with the DOM nodes wrapped by a Fragment.

Lauren Tan announced [React Compiler v1.0](https://react.dev/blog/2025/10/07/react-compiler-1) and recommended all apps use React Compiler for benefits like:

* [Automatic memoization](/learn/react-compiler/introduction#what-does-react-compiler-do) that understands React code.
* [New lint rules](/learn/react-compiler/installation#eslint-integration) powered by React Compiler to teach best practices.
* [Default support](/learn/react-compiler/installation#basic-setup) for new apps in Vite, Next.js, and Expo.
* [Migration guides](/learn/react-compiler/incremental-adoption) for existing apps migrating to React Compiler.

Finally, Seth Webster announced the [React Foundation](/blog/2025/10/07/introducing-the-react-foundation) to steward React’s open source development and community.

Watch day 1 here:

## Day 2 Keynote[](#day-2-keynote "Link for Day 2 Keynote ")

*Watch the full day 2 stream [here.](https://www.youtube.com/watch?v=p9OcztRyDl0\&t=2299s)*

Jorge Cohen and Nicola Corti kicked off day 2 highlighting React Native’s incredible growth with 4M weekly downloads (100% growth YoY), and some notable app migrations from Shopify, Zalando, and HelloFresh, award-winning apps like RISE, RUNNA, and Partyful, and AI apps from Mistral, Replit, and v0.

Riccardo Cipolleschi shared two major announcements for React Native:

* [React Native 0.82 will be New Architecture only](https://reactnative.dev/blog/2025/10/08/react-native-0.82#new-architecture-only)
* [Experimental Hermes V1 support](https://reactnative.dev/blog/2025/10/08/react-native-0.82#experimental-hermes-v1)

Ruben Norte and Alex Hunt finished out the keynote by announcing:

* [New web-aligned DOM APIs](https://reactnative.dev/blog/2025/10/08/react-native-0.82#dom-node-apis) for improved compatibility with React on the web.
* [New Performance APIs](https://reactnative.dev/blog/2025/10/08/react-native-0.82#web-performance-apis-canary) with a new network panel and desktop app.

Watch day 2 here:

## React team talks[](#react-team-talks "Link for React team talks ")

Throughout the conference, there were talks from the React team including:

* [Async React Part I](https://www.youtube.com/watch?v=zyVRg2QR6LA\&t=10907s) and [Part II](https://www.youtube.com/watch?v=p9OcztRyDl0\&t=29073s) [(Ricky Hanlon)](https://x.com/rickhanlonii) showed what’s possible using the last 10 years of innovation.
* [Exploring React Performance](https://www.youtube.com/watch?v=zyVRg2QR6LA\&t=20274s) [(Joe Savona)](https://x.com/en_js) showed the results of our React performance research.
* [Reimagining Lists in React Native](https://www.youtube.com/watch?v=p9OcztRyDl0\&t=10382s) [(Luna Wei)](https://x.com/lunaleaps) introduced Virtual View, a new primitive for lists that manages visibility with mode-based rendering (hidden/pre-render/visible).
* [Profiling with React Performance tracks](https://www.youtube.com/watch?v=zyVRg2QR6LA\&t=8276s) [(Ruslan Lesiutin)](https://x.com/ruslanlesiutin) showed how to use the new React Performance Tracks to debug performance issues and build great apps.
* [React Strict DOM](https://www.youtube.com/watch?v=p9OcztRyDl0\&t=9026s) [(Nicolas Gallagher)](https://nicolasgallagher.com/) talked about Meta’s approach to using web code on native.
* [View Transitions and Activity](https://www.youtube.com/watch?v=zyVRg2QR6LA\&t=4870s) [(Chance Strickland)](https://x.com/chancethedev) — Chance worked with the React team to showcase how to use `<Activity />` and `<ViewTransition />` to build fast, native-feeling animations.
* [In case you missed the memo](https://www.youtube.com/watch?v=zyVRg2QR6LA\&t=9525s) [(Cody Olsen)](https://bsky.app/profile/codey.bsky.social) - Cody worked with the React team to adopt the Compiler at Sanity Studio, and shared how it went.

## React framework talks[](#react-framework-talks "Link for React framework talks ")

The second half of day 2 had a series of talks from React Framework teams including:

* [React Native, Amplified](https://www.youtube.com/watch?v=p9OcztRyDl0\&t=5737s) by [Giovanni Laquidara](https://x.com/giolaq) and [Eric Fahsl](https://x.com/efahsl).
* [React Everywhere: Bringing React Into Native Apps](https://www.youtube.com/watch?v=p9OcztRyDl0\&t=18213s) by [Mike Grabowski](https://x.com/grabbou).
* [How Parcel Bundles React Server Components](https://www.youtube.com/watch?v=p9OcztRyDl0\&t=19538s) by [Devon Govett](https://x.com/devonovett).
* [Designing Page Transitions](https://www.youtube.com/watch?v=p9OcztRyDl0\&t=20640s) by [Delba de Oliveira](https://x.com/delba_oliveira).
* [Build Fast, Deploy Faster — Expo in 2025](https://www.youtube.com/watch?v=p9OcztRyDl0\&t=21350s) by [Evan Bacon](https://x.com/baconbrix).
* [The React Router’s take on RSC](https://www.youtube.com/watch?v=p9OcztRyDl0\&t=22367s) by [Kent C. Dodds](https://x.com/kentcdodds).
* [RedwoodSDK: Web Standards Meet Full-Stack React](https://www.youtube.com/watch?v=p9OcztRyDl0\&t=24992s) by [Peter Pistorius](https://x.com/appfactory) and [Aurora Scharff](https://x.com/aurorascharff).
* [TanStack Start](https://www.youtube.com/watch?v=p9OcztRyDl0\&t=26065s) by [Tanner Linsley](https://x.com/tannerlinsley).

## Q\&A[](#q-and-a "Link for Q\&A ")

There were three Q\&A panels during the conference:

* [React Team at Meta Q\&A](https://www.youtube.com/watch?v=zyVRg2QR6LA\&t=26304s) hosted by [Shruti Kapoor](https://x.com/shrutikapoor08)
* [React Frameworks Q\&A](https://www.youtube.com/watch?v=p9OcztRyDl0\&t=26812s) hosted by [Jack Herrington](https://x.com/jherr)
* [React and AI Panel](https://www.youtube.com/watch?v=zyVRg2QR6LA\&t=18741s) hosted by [Lee Robinson](https://x.com/leerob)

## And more…[](#and-more "Link for And more… ")

We also heard talks from the community including:

* [Building an MCP Server](https://www.youtube.com/watch?v=zyVRg2QR6LA\&t=24204s) by [James Swinton](https://x.com/JamesSwintonDev) ([AG Grid](https://www.ag-grid.com/?utm_source=react-conf\&utm_medium=react-conf-homepage\&utm_campaign=react-conf-sponsorship-2025))
* [Modern Emails using React](https://www.youtube.com/watch?v=zyVRg2QR6LA\&t=25521s) by [Zeno Rocha](https://x.com/zenorocha) ([Resend](https://resend.com/))
* [Why React Native Apps Make All the Money](https://www.youtube.com/watch?v=zyVRg2QR6LA\&t=24917s) by [Perttu Lähteenlahti](https://x.com/plahteenlahti) ([RevenueCat](https://www.revenuecat.com/))
* [The invisible craft of great UX](https://www.youtube.com/watch?v=zyVRg2QR6LA\&t=23400s) by [Michał Dudak](https://x.com/michaldudak) ([MUI](https://mui.com/))

## Thanks[](#thanks "Link for Thanks ")

Thank you to all the staff, speakers, and participants, who made React Conf 2025 possible. There are too many to list, but we want to thank a few in particular.

Thank you to [Matt Carroll](https://x.com/mattcarrollcode) for planning the entire event and building the conference website.

Thank you to [Michael Chan](https://x.com/chantastic) for MCing React Conf with incredible dedication and energy, delivering thoughtful speaker intros, fun jokes, and genuine enthusiasm throughout the event. Thank you to [Jorge Cohen](https://x.com/JorgeWritesCode) for hosting the livestream, interviewing each speaker, and bringing the in-person React Conf experience online.

Thank you to [Mateusz Kornacki](https://x.com/mat_kornacki), [Mike Grabowski](https://x.com/grabbou), [Kris Lis](https://www.linkedin.com/in/krzysztoflisakakris/) and the team at [Callstack](https://www.callstack.com/) for co-organizing React Conf and providing design, engineering, and marketing support. Thank you to the [ZeroSlope team](https://zeroslopeevents.com/contact-us/): Sunny Leggett, Tracey Harrison, Tara Larish, Whitney Pogue, and Brianne Smythia for helping to organize the event.

Thank you to [Jorge Cabiedes Acosta](https://github.com/jorge-cab), [Gijs Weterings](https://x.com/gweterings), [Tim Yung](https://x.com/yungsters), and [Jason Bonta](https://x.com/someextent) for bringing questions from the Discord to the livestream. Thank you to [Lynn Yu](https://github.com/lynnshaoyu) for leading the moderation of the Discord. Thank you to [Seth Webster](https://x.com/sethwebster) for welcoming us each day; and to [Christopher Chedeau](https://x.com/vjeux), [Kevin Gozali](https://x.com/fkgozali), and [Pieter De Baets](https://x.com/Javache) for joining us with a special message during the after-party.

Thank you to [Kadi Kraman](https://x.com/kadikraman), [Beto](https://x.com/betomoedano) and [Nicolas Solerieu](https://www.linkedin.com/in/nicolas-solerieu/) for building the conference mobile app. Thank you [Wojtek Szafraniec](https://x.com/wojteg1337) for help with the conference website. Thank you to [Mustache](https://www.mustachepower.com/) & [Cornerstone](https://cornerstoneav.com/) for the visuals, stage, and sound; and to the Westin Hotel for hosting us.

Thank you to all the sponsors who made the event possible: [Amazon](https://www.developer.amazon.com), [MUI](https://mui.com/), [Vercel](https://vercel.com/), [Expo](https://expo.dev/), [RedwoodSDK](https://rwsdk.com), [Ag Grid](https://www.ag-grid.com), [RevenueCat](https://www.revenuecat.com/), [Resend](https://resend.com), [Mux](https://www.mux.com/), [Old Mission](https://www.oldmissioncapital.com/), [Arcjet](https://arcjet.com), [Infinite Red](https://infinite.red/), and [RenderATL](https://renderatl.com).

Thank you to all the speakers who shared their knowledge and experience with the community.

Finally, thank you to everyone who attended in person and online to show what makes React, React. React is more than a library, it is a community, and it was inspiring to see everyone come together to share and learn together.

See you next time!

[PreviousCritical Security Vulnerability in React Server Components](/blog/2025/12/03/critical-security-vulnerability-in-react-server-components)

[NextReact Compiler v1.0](/blog/2025/10/07/react-compiler-1)

***

----
url: https://react.dev/reference/react-dom/hooks/useFormStatus
----

[API Reference](/reference/react)

[Hooks](/reference/react-dom/hooks)

# useFormStatus[](#undefined "Link for this heading")

`useFormStatus` is a Hook that gives you status information of the last form submission.

```
const { pending, data, method, action } = useFormStatus();
```

***

## Reference[](#reference "Link for Reference ")

### `useFormStatus()`[](#use-form-status "Link for this heading")

The `useFormStatus` Hook provides status information of the last form submission.

```
import { useFormStatus } from "react-dom";

import action from './actions';



function Submit() {

  const status = useFormStatus();

  return <button disabled={status.pending}>Submit</button>

}



export default function App() {

  return (

    <form action={action}>

      <Submit />

    </form>

  );

}
```

***

## Usage[](#usage "Link for Usage ")

### Display a pending state during form submission[](#display-a-pending-state-during-form-submission "Link for Display a pending state during form submission ")

To display a pending state while a form is submitting, you can call the `useFormStatus` Hook in a component rendered in a `<form>` and read the `pending` property returned.

Here, we use the `pending` property to indicate the form is submitting.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useFormStatus } from "react-dom";
import { submitForm } from "./actions.js";

function Submit() {
  const { pending } = useFormStatus();
  return (
    <button type="submit" disabled={pending}>
      {pending ? "Submitting..." : "Submit"}
    </button>
  );
}

function Form({ action }) {
  return (
    <form action={action}>
      <Submit />
    </form>
  );
}

export default function App() {
  return <Form action={submitForm} />;
}
```

### Pitfall

##### `useFormStatus` will not return status information for a `<form>` rendered in the same component.[](#useformstatus-will-not-return-status-information-for-a-form-rendered-in-the-same-component "Link for this heading")

The `useFormStatus` Hook only returns status information for a parent `<form>` and not for any `<form>` rendered in the same component calling the Hook, or child components.

```
function Form() {

  // 🚩 `pending` will never be true

  // useFormStatus does not track the form rendered in this component

  const { pending } = useFormStatus();

  return <form action={submit}></form>;

}
```

Instead call `useFormStatus` from inside a component that is located inside `<form>`.

```
function Submit() {

  // ✅ `pending` will be derived from the form that wraps the Submit component

  const { pending } = useFormStatus();

  return <button disabled={pending}>...</button>;

}



function Form() {

  // This is the <form> `useFormStatus` tracks

  return (

    <form action={submit}>

      <Submit />

    </form>

  );

}
```

### Read the form data being submitted[](#read-form-data-being-submitted "Link for Read the form data being submitted ")

You can use the `data` property of the status information returned from `useFormStatus` to display what data is being submitted by the user.

Here, we have a form where users can request a username. We can use `useFormStatus` to display a temporary status message confirming what username they have requested.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import {useState, useMemo, useRef} from 'react';
import {useFormStatus} from 'react-dom';

export default function UsernameForm() {
  const {pending, data} = useFormStatus();

  return (
    <div>
      <h3>Request a Username: </h3>
      <input type="text" name="username" disabled={pending}/>
      <button type="submit" disabled={pending}>
        Submit
      </button>
      <br />
      <p>{data ? `Requesting ${data?.get("username")}...`: ''}</p>
    </div>
  );
}
```

***

***

----
url: https://18.react.dev/reference/react/StrictMode
----

[API Reference](/reference/react)

[Components](/reference/react/components)

# \<StrictMode>[](#undefined "Link for this heading")

`<StrictMode>` lets you find common bugs in your components early during development.

```
<StrictMode>

  <App />

</StrictMode>
```

  * [Fixing deprecation warnings enabled by Strict Mode](#fixing-deprecation-warnings-enabled-by-strict-mode)

***

## Reference[](#reference "Link for Reference ")

### `<StrictMode>`[](#strictmode "Link for this heading")

Use `StrictMode` to enable additional development behaviors and warnings for the component tree inside:

```
import { StrictMode } from 'react';

import { createRoot } from 'react-dom/client';



const root = createRoot(document.getElementById('root'));

root.render(

  <StrictMode>

    <App />

  </StrictMode>

);
```

[See more examples below.](#usage)

Strict Mode enables the following development-only behaviors:

* Your components will [re-render an extra time](#fixing-bugs-found-by-double-rendering-in-development) to find bugs caused by impure rendering.
* Your components will [re-run Effects an extra time](#fixing-bugs-found-by-re-running-effects-in-development) to find bugs caused by missing Effect cleanup.
* Your components will [be checked for usage of deprecated APIs.](#fixing-deprecation-warnings-enabled-by-strict-mode)

#### Props[](#props "Link for Props ")

`StrictMode` accepts no props.

#### Caveats[](#caveats "Link for Caveats ")

* There is no way to opt out of Strict Mode inside a tree wrapped in `<StrictMode>`. This gives you confidence that all components inside `<StrictMode>` are checked. If two teams working on a product disagree whether they find the checks valuable, they need to either reach consensus or move `<StrictMode>` down in the tree.

***

## Usage[](#usage "Link for Usage ")

### Enabling Strict Mode for entire app[](#enabling-strict-mode-for-entire-app "Link for Enabling Strict Mode for entire app ")

Strict Mode enables extra development-only checks for the entire component tree inside the `<StrictMode>` component. These checks help you find common bugs in your components early in the development process.

To enable Strict Mode for your entire app, wrap your root component with `<StrictMode>` when you render it:

```
import { StrictMode } from 'react';

import { createRoot } from 'react-dom/client';



const root = createRoot(document.getElementById('root'));

root.render(

  <StrictMode>

    <App />

  </StrictMode>

);
```

We recommend wrapping your entire app in Strict Mode, especially for newly created apps. If you use a framework that calls [`createRoot`](/reference/react-dom/client/createRoot) for you, check its documentation for how to enable Strict Mode.

Although the Strict Mode checks **only run in development,** they help you find bugs that already exist in your code but can be tricky to reliably reproduce in production. Strict Mode lets you fix bugs before your users report them.

### Note

Strict Mode enables the following checks in development:

* Your components will [re-render an extra time](#fixing-bugs-found-by-double-rendering-in-development) to find bugs caused by impure rendering.
* Your components will [re-run Effects an extra time](#fixing-bugs-found-by-re-running-effects-in-development) to find bugs caused by missing Effect cleanup.
* Your components will [be checked for usage of deprecated APIs.](#fixing-deprecation-warnings-enabled-by-strict-mode)

**All of these checks are development-only and do not impact the production build.**

***

### Enabling Strict Mode for a part of the app[](#enabling-strict-mode-for-a-part-of-the-app "Link for Enabling Strict Mode for a part of the app ")

You can also enable Strict Mode for any part of your application:

```
import { StrictMode } from 'react';



function App() {

  return (

    <>

      <Header />

      <StrictMode>

        <main>

          <Sidebar />

          <Content />

        </main>

      </StrictMode>

      <Footer />

    </>

  );

}
```

In this example, Strict Mode checks will not run against the `Header` and `Footer` components. However, they will run on `Sidebar` and `Content`, as well as all of the components inside them, no matter how deep.

***

```
export default function StoryTray({ stories }) {
  const items = stories;
  items.push({ id: 'create', label: 'Create Story' });
  return (
    <ul>
      {items.map(story => (
        <li key={story.id}>
          {story.label}
        </li>
      ))}
    </ul>
  );
}
```

There is a mistake in the code above. However, it is easy to miss because the initial output appears correct.

This mistake will become more noticeable if the `StoryTray` component re-renders multiple times. For example, let’s make the `StoryTray` re-render with a different background color whenever you hover over it:

```
import { useState } from 'react';

export default function StoryTray({ stories }) {
  const [isHover, setIsHover] = useState(false);
  const items = stories;
  items.push({ id: 'create', label: 'Create Story' });
  return (
    <ul
      onPointerEnter={() => setIsHover(true)}
      onPointerLeave={() => setIsHover(false)}
      style={{
        backgroundColor: isHover ? '#ddd' : '#fff'
      }}
    >
      {items.map(story => (
        <li key={story.id}>
          {story.label}
        </li>
      ))}
    </ul>
  );
}
```

Notice how every time you hover over the `StoryTray` component, “Create Story” gets added to the list again. The intention of the code was to add it once at the end. But `StoryTray` directly modifies the `stories` array from the props. Every time `StoryTray` renders, it adds “Create Story” again at the end of the same array. In other words, `StoryTray` is not a pure function—running it multiple times produces different results.

To fix this problem, you can make a copy of the array, and modify that copy instead of the original one:

```
export default function StoryTray({ stories }) {

  const items = stories.slice(); // Clone the array

  // ✅ Good: Pushing into a new array

  items.push({ id: 'create', label: 'Create Story' });
```

This would [make the `StoryTray` function pure.](/learn/keeping-components-pure) Each time it is called, it would only modify a new copy of the array, and would not affect any external objects or variables. This solves the bug, but you had to make the component re-render more often before it became obvious that something is wrong with its behavior.

**In the original example, the bug wasn’t obvious. Now let’s wrap the original (buggy) code in `<StrictMode>`:**

```
export default function StoryTray({ stories }) {
  const items = stories;
  items.push({ id: 'create', label: 'Create Story' });
  return (
    <ul>
      {items.map(story => (
        <li key={story.id}>
          {story.label}
        </li>
      ))}
    </ul>
  );
}
```

**Strict Mode *always* calls your rendering function twice, so you can see the mistake right away** (“Create Story” appears twice). This lets you notice such mistakes early in the process. When you fix your component to render in Strict Mode, you *also* fix many possible future production bugs like the hover functionality from before:

```
import { useState } from 'react';

export default function StoryTray({ stories }) {
  const [isHover, setIsHover] = useState(false);
  const items = stories.slice(); // Clone the array
  items.push({ id: 'create', label: 'Create Story' });
  return (
    <ul
      onPointerEnter={() => setIsHover(true)}
      onPointerLeave={() => setIsHover(false)}
      style={{
        backgroundColor: isHover ? '#ddd' : '#fff'
      }}
    >
      {items.map(story => (
        <li key={story.id}>
          {story.label}
        </li>
      ))}
    </ul>
  );
}
```

Without Strict Mode, it was easy to miss the bug until you added more re-renders. Strict Mode made the same bug appear right away. Strict Mode helps you find bugs before you push them to your team and to your users.

[Read more about keeping components pure.](/learn/keeping-components-pure)

### Note

If you have [React DevTools](/learn/react-developer-tools) installed, any `console.log` calls during the second render call will appear slightly dimmed. React DevTools also offers a setting (off by default) to suppress them completely.

***

### Fixing bugs found by re-running Effects in development[](#fixing-bugs-found-by-re-running-effects-in-development "Link for Fixing bugs found by re-running Effects in development ")

Strict Mode can also help find bugs in [Effects.](/learn/synchronizing-with-effects)

Every Effect has some setup code and may have some cleanup code. Normally, React calls setup when the component *mounts* (is added to the screen) and calls cleanup when the component *unmounts* (is removed from the screen). React then calls cleanup and setup again if its dependencies changed since the last render.

When Strict Mode is on, React will also run **one extra setup+cleanup cycle in development for every Effect.** This may feel surprising, but it helps reveal subtle bugs that are hard to catch manually.

**Here is an example to illustrate how re-running Effects in Strict Mode helps you find bugs early.**

Consider this example that connects a component to a chat:

```
import { createRoot } from 'react-dom/client';
import './styles.css';

import App from './App';

const root = createRoot(document.getElementById("root"));
root.render(<App />);
```

There is an issue with this code, but it might not be immediately clear.

To make the issue more obvious, let’s implement a feature. In the example below, `roomId` is not hardcoded. Instead, the user can select the `roomId` that they want to connect to from a dropdown. Click “Open chat” and then select different chat rooms one by one. Keep track of the number of active connections in the console:

```
import { createRoot } from 'react-dom/client';
import './styles.css';

import App from './App';

const root = createRoot(document.getElementById("root"));
root.render(<App />);
```

You’ll notice that the number of open connections always keeps growing. In a real app, this would cause performance and network problems. The issue is that [your Effect is missing a cleanup function:](/learn/synchronizing-with-effects#step-3-add-cleanup-if-needed)

```
  useEffect(() => {

    const connection = createConnection(serverUrl, roomId);

    connection.connect();

    return () => connection.disconnect();

  }, [roomId]);
```

Now that your Effect “cleans up” after itself and destroys the outdated connections, the leak is solved. However, notice that the problem did not become visible until you’ve added more features (the select box).

**In the original example, the bug wasn’t obvious. Now let’s wrap the original (buggy) code in `<StrictMode>`:**

```
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import './styles.css';

import App from './App';

const root = createRoot(document.getElementById("root"));
root.render(
  <StrictMode>
    <App />
  </StrictMode>
);
```

**With Strict Mode, you immediately see that there is a problem** (the number of active connections jumps to 2). Strict Mode runs an extra setup+cleanup cycle for every Effect. This Effect has no cleanup logic, so it creates an extra connection but doesn’t destroy it. This is a hint that you’re missing a cleanup function.

Strict Mode lets you notice such mistakes early in the process. When you fix your Effect by adding a cleanup function in Strict Mode, you *also* fix many possible future production bugs like the select box from before:

```
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import './styles.css';

import App from './App';

const root = createRoot(document.getElementById("root"));
root.render(
  <StrictMode>
    <App />
  </StrictMode>
);
```

Notice how the active connection count in the console doesn’t keep growing anymore.

Without Strict Mode, it was easy to miss that your Effect needed cleanup. By running *setup → cleanup → setup* instead of *setup* for your Effect in development, Strict Mode made the missing cleanup logic more noticeable.

[Read more about implementing Effect cleanup.](/learn/synchronizing-with-effects#how-to-handle-the-effect-firing-twice-in-development)

***

### Fixing deprecation warnings enabled by Strict Mode[](#fixing-deprecation-warnings-enabled-by-strict-mode "Link for Fixing deprecation warnings enabled by Strict Mode ")

React warns if some component anywhere inside a `<StrictMode>` tree uses one of these deprecated APIs:

* [`findDOMNode`](/reference/react-dom/findDOMNode). [See alternatives.](https://reactjs.org/docs/strict-mode.html#warning-about-deprecated-finddomnode-usage)
* `UNSAFE_` class lifecycle methods like [`UNSAFE_componentWillMount`](/reference/react/Component#unsafe_componentwillmount). [See alternatives.](https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html#migrating-from-legacy-lifecycles)
* Legacy context ([`childContextTypes`](/reference/react/Component#static-childcontexttypes), [`contextTypes`](/reference/react/Component#static-contexttypes), and [`getChildContext`](/reference/react/Component#getchildcontext)). [See alternatives.](/reference/react/createContext)
* Legacy string refs ([`this.refs`](/reference/react/Component#refs)). [See alternatives.](https://reactjs.org/docs/strict-mode.html#warning-about-legacy-string-ref-api-usage)

These APIs are primarily used in older [class components](/reference/react/Component) so they rarely appear in modern apps.

[Previous\<Profiler>](/reference/react/Profiler)

[Next\<Suspense>](/reference/react/Suspense)

***

----
url: https://react.dev/blog/2022/06/15/react-labs-what-we-have-been-working-on-june-2022
----

[Blog](/blog)

# React Labs: What We've Been Working On – June 2022[](#undefined "Link for this heading")

June 15, 2022 by [Andrew Clark](https://twitter.com/acdlite), [Dan Abramov](https://bsky.app/profile/danabra.mov), [Jan Kassens](https://twitter.com/kassens), [Joseph Savona](https://twitter.com/en_JS), [Josh Story](https://twitter.com/joshcstory), [Lauren Tan](https://twitter.com/potetotes), [Luna Ruan](https://twitter.com/lunaruan), [Mengdi Chen](https://twitter.com/mengdi_en), [Rick Hanlon](https://twitter.com/rickhanlonii), [Robert Zhang](https://twitter.com/jiaxuanzhang01), [Sathya Gunasekaran](https://twitter.com/_gsathya), [Sebastian Markbåge](https://twitter.com/sebmarkbage), and [Xuan Huang](https://twitter.com/Huxpro)

***

[React 18](/blog/2022/03/29/react-v18) was years in the making, and with it brought valuable lessons for the React team. Its release was the result of many years of research and exploring many paths. Some of those paths were successful; many more were dead-ends that led to new insights. One lesson we’ve learned is that it’s frustrating for the community to wait for new features without having insight into these paths that we’re exploring.

***

We typically have a number of projects being worked on at any time, ranging from the more experimental to the clearly defined. Looking ahead, we’d like to start regularly sharing more about what we’ve been working on with the community across these projects.

To set expectations, this is not a roadmap with clear timelines. Many of these projects are under active research and are difficult to put concrete ship dates on. They may possibly never even ship in their current iteration depending on what we learn. Instead, we want to share with you the problem spaces we’re actively thinking about, and what we’ve learned so far.

## Server Components[](#server-components "Link for Server Components ")

We announced an [experimental demo of React Server Components](https://legacy.reactjs.org/blog/2020/12/21/data-fetching-with-react-server-components.html) (RSC) in December 2020. Since then we’ve been finishing up its dependencies in React 18, and working on changes inspired by experimental feedback.

In particular, we’re abandoning the idea of having forked I/O libraries (eg react-fetch), and instead adopting an async/await model for better compatibility. This doesn’t technically block RSC’s release because you can also use routers for data fetching. Another change is that we’re also moving away from the file extension approach in favor of [annotating boundaries](https://github.com/reactjs/rfcs/pull/189#issuecomment-1116482278).

We’re working together with Vercel and Shopify to unify bundler support for shared semantics in both webpack and Vite. Before launch, we want to make sure that the semantics of RSCs are the same across the whole React ecosystem. This is the major blocker for reaching stable.

## Asset Loading[](#asset-loading "Link for Asset Loading ")

Currently, assets like scripts, external styles, fonts, and images are typically preloaded and loaded using external systems. This can make it tricky to coordinate across new environments like streaming, Server Components, and more. We’re looking at adding APIs to preload and load deduplicated external assets through React APIs that work in all React environments.

We’re also looking at having these support Suspense so you can have images, CSS, and fonts that block display until they’re loaded but don’t block streaming and concurrent rendering. This can help avoid [“popcorning“](https://twitter.com/sebmarkbage/status/1516852731251724293) as the visuals pop and layout shifts.

## Static Server Rendering Optimizations[](#static-server-rendering-optimizations "Link for Static Server Rendering Optimizations ")

Static Site Generation (SSG) and Incremental Static Regeneration (ISR) are great ways to get performance for cacheable pages, but we think we can add features to improve performance of dynamic Server Side Rendering (SSR) – especially when most but not all of the content is cacheable. We’re exploring ways to optimize server rendering utilizing compilation and static passes.

## React Optimizing Compiler[](#react-compiler "Link for React Optimizing Compiler ")

We gave an [early preview](https://www.youtube.com/watch?v=lGEMwh32soc) of React Forget at React Conf 2021. It’s a compiler that automatically generates the equivalent of `useMemo` and `useCallback` calls to minimize the cost of re-rendering, while retaining React’s programming model.

Recently, we finished a rewrite of the compiler to make it more reliable and capable. This new architecture allows us to analyze and memoize more complex patterns such as the use of [local mutations](/learn/keeping-components-pure#local-mutation-your-components-little-secret), and opens up many new compile-time optimization opportunities beyond just being on par with memoization Hooks.

We’re also working on a playground for exploring many aspects of the compiler. While the goal of the playground is to make development of the compiler easier, we think that it will make it easier to try it out and build intuition for what the compiler does. It reveals various insights into how it works under the hood, and live renders the compiler’s outputs as you type. This will be shipped together with the compiler when it’s released.

## Offscreen[](#offscreen "Link for Offscreen ")

## Transition Tracing[](#transition-tracing "Link for Transition Tracing ")

Currently, React has two profiling tools. The [original Profiler](https://legacy.reactjs.org/blog/2018/09/10/introducing-the-react-profiler.html) shows an overview of all the commits in a profiling session. For each commit, it also shows all components that rendered and the amount of time it took for them to render. We also have a beta version of a [Timeline Profiler](https://github.com/reactwg/react-18/discussions/76) introduced in React 18 that shows when components schedule updates and when React works on these updates. Both of these profilers help developers identify performance problems in their code.

We’ve realized that developers don’t find knowing about individual slow commits or components out of context that useful. It’s more useful to know about what actually causes the slow commits. And that developers want to be able to track specific interactions (eg a button click, an initial load, or a page navigation) to watch for performance regressions and to understand why an interaction was slow and how to fix it.

We previously tried to solve this issue by creating an [Interaction Tracing API](https://gist.github.com/bvaughn/8de925562903afd2e7a12554adcdda16), but it had some fundamental design flaws that reduced the accuracy of tracking why an interaction was slow and sometimes resulted in interactions never ending. We ended up [removing this API](https://github.com/facebook/react/pull/20037) because of these issues.

We are working on a new version for the Interaction Tracing API (tentatively called Transition Tracing because it is initiated via `startTransition`) that solves these problems.

## New React Docs[](#new-react-docs "Link for New React Docs ")

Last year, we announced the beta version of the new React documentation website ([later shipped as react.dev](/blog/2023/03/16/introducing-react-dev)) of the new React documentation website. The new learning materials teach Hooks first and has new diagrams, illustrations, as well as many interactive examples and challenges. We took a break from that work to focus on the React 18 release, but now that React 18 is out, we’re actively working to finish and ship the new documentation.

We are currently writing a detailed section about effects, as we’ve heard that is one of the more challenging topics for both new and experienced React users. [Synchronizing with Effects](/learn/synchronizing-with-effects) is the first published page in the series, and there are more to come in the following weeks. When we first started writing a detailed section about effects, we’ve realized that many common effect patterns can be simplified by adding a new primitive to React. We’ve shared some initial thoughts on that in the [useEvent RFC](https://github.com/reactjs/rfcs/pull/220). It is currently in early research, and we are still iterating on the idea. We appreciate the community’s comments on the RFC so far, as well as the [feedback](https://github.com/reactjs/react.dev/issues/3308) and contributions to the ongoing documentation rewrite. We’d specifically like to thank [Harish Kumar](https://github.com/harish-sethuraman) for submitting and reviewing many improvements to the new website implementation.

*Thanks to [Sophie Alpert](https://twitter.com/sophiebits) for reviewing this blog post!*

[PreviousIntroducing react.dev](/blog/2023/03/16/introducing-react-dev)

[NextReact v18.0](/blog/2022/03/29/react-v18)

***

----
url: https://18.react.dev/reference/react-dom/server/renderToString
----

[API Reference](/reference/react)

[Server APIs](/reference/react-dom/server)

# renderToString[](#undefined "Link for this heading")

### Pitfall

`renderToString` does not support streaming or waiting for data. [See the alternatives.](#alternatives)

`renderToString` renders a React tree to an HTML string.

```
const html = renderToString(reactNode, options?)
```

* [Reference](#reference)
  * [`renderToString(reactNode, options?)`](#rendertostring)

* [Usage](#usage)
  * [Rendering a React tree as HTML to a string](#rendering-a-react-tree-as-html-to-a-string)

* [Alternatives](#alternatives)

  * [Migrating from `renderToString` to a streaming method on the server](#migrating-from-rendertostring-to-a-streaming-method-on-the-server)
  * [Removing `renderToString` from the client code](#removing-rendertostring-from-the-client-code)

* [Troubleshooting](#troubleshooting)
  * [When a component suspends, the HTML always contains a fallback](#when-a-component-suspends-the-html-always-contains-a-fallback)

***

## Reference[](#reference "Link for Reference ")

### `renderToString(reactNode, options?)`[](#rendertostring "Link for this heading")

On the server, call `renderToString` to render your app to HTML.

```
import { renderToString } from 'react-dom/server';



const html = renderToString(<App />);
```

***

## Usage[](#usage "Link for Usage ")

### Rendering a React tree as HTML to a string[](#rendering-a-react-tree-as-html-to-a-string "Link for Rendering a React tree as HTML to a string ")

Call `renderToString` to render your app to an HTML string which you can send with your server response:

```
import { renderToString } from 'react-dom/server';



// The route handler syntax depends on your backend framework

app.use('/', (request, response) => {

  const html = renderToString(<App />);

  response.send(html);

});
```

This will produce the initial non-interactive HTML output of your React components. On the client, you will need to call [`hydrateRoot`](/reference/react-dom/client/hydrateRoot) to *hydrate* that server-generated HTML and make it interactive.

### Pitfall

`renderToString` does not support streaming or waiting for data. [See the alternatives.](#alternatives)

***

## Alternatives[](#alternatives "Link for Alternatives ")

### Migrating from `renderToString` to a streaming method on the server[](#migrating-from-rendertostring-to-a-streaming-method-on-the-server "Link for this heading")

`renderToString` returns a string immediately, so it does not support streaming or waiting for data.

When possible, we recommend using these fully-featured alternatives:

* If you use Node.js, use [`renderToPipeableStream`.](/reference/react-dom/server/renderToPipeableStream)
* If you use Deno or a modern edge runtime with [Web Streams](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API), use [`renderToReadableStream`.](/reference/react-dom/server/renderToReadableStream)

You can continue using `renderToString` if your server environment does not support streams.

***

### Removing `renderToString` from the client code[](#removing-rendertostring-from-the-client-code "Link for this heading")

Sometimes, `renderToString` is used on the client to convert some component to HTML.

```
// 🚩 Unnecessary: using renderToString on the client

import { renderToString } from 'react-dom/server';



const html = renderToString(<MyIcon />);

console.log(html); // For example, "<svg>...</svg>"
```

Importing `react-dom/server` **on the client** unnecessarily increases your bundle size and should be avoided. If you need to render some component to HTML in the browser, use [`createRoot`](/reference/react-dom/client/createRoot) and read HTML from the DOM:

```
import { createRoot } from 'react-dom/client';

import { flushSync } from 'react-dom';



const div = document.createElement('div');

const root = createRoot(div);

flushSync(() => {

  root.render(<MyIcon />);

});

console.log(div.innerHTML); // For example, "<svg>...</svg>"
```

The [`flushSync`](/reference/react-dom/flushSync) call is necessary so that the DOM is updated before reading its [`innerHTML`](https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML) property.

***

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### When a component suspends, the HTML always contains a fallback[](#when-a-component-suspends-the-html-always-contains-a-fallback "Link for When a component suspends, the HTML always contains a fallback ")

`renderToString` does not fully support Suspense.

If some component suspends (for example, because it’s defined with [`lazy`](/reference/react/lazy) or fetches data), `renderToString` will not wait for its content to resolve. Instead, `renderToString` will find the closest [`<Suspense>`](/reference/react/Suspense) boundary above it and render its `fallback` prop in the HTML. The content will not appear until the client code loads.

To solve this, use one of the [recommended streaming solutions.](#migrating-from-rendertostring-to-a-streaming-method-on-the-server) They can stream content in chunks as it resolves on the server so that the user sees the page being progressively filled in before the client code loads.

[PreviousrenderToStaticNodeStream](/reference/react-dom/server/renderToStaticNodeStream)

***

----
url: https://18.react.dev/learn/you-might-not-need-an-effect
----

You *do* need Effects to [synchronize](/learn/synchronizing-with-effects#what-are-effects-and-how-are-they-different-from-events) with external systems. For example, you can write an Effect that keeps a jQuery widget synchronized with the React state. You can also fetch data with Effects: for example, you can synchronize the search results with the current search query. Keep in mind that modern [frameworks](/learn/start-a-new-react-project#production-grade-react-frameworks) provide more efficient built-in data fetching mechanisms than writing Effects directly in your components.

To help you gain the right intuition, let’s look at some common concrete examples!

### Updating state based on props or state[](#updating-state-based-on-props-or-state "Link for Updating state based on props or state ")

Suppose you have a component with two state variables: `firstName` and `lastName`. You want to calculate a `fullName` from them by concatenating them. Moreover, you’d like `fullName` to update whenever `firstName` or `lastName` change. Your first instinct might be to add a `fullName` state variable and update it in an Effect:

```
function Form() {

  const [firstName, setFirstName] = useState('Taylor');

  const [lastName, setLastName] = useState('Swift');



  // 🔴 Avoid: redundant state and unnecessary Effect

  const [fullName, setFullName] = useState('');

  useEffect(() => {

    setFullName(firstName + ' ' + lastName);

  }, [firstName, lastName]);

  // ...

}
```

This is more complicated than necessary. It is inefficient too: it does an entire render pass with a stale value for `fullName`, then immediately re-renders with the updated value. Remove the state variable and the Effect:

```
function Form() {

  const [firstName, setFirstName] = useState('Taylor');

  const [lastName, setLastName] = useState('Swift');

  // ✅ Good: calculated during rendering

  const fullName = firstName + ' ' + lastName;

  // ...

}
```

**When something can be calculated from the existing props or state, [don’t put it in state.](/learn/choosing-the-state-structure#avoid-redundant-state) Instead, calculate it during rendering.** This makes your code faster (you avoid the extra “cascading” updates), simpler (you remove some code), and less error-prone (you avoid bugs caused by different state variables getting out of sync with each other). If this approach feels new to you, [Thinking in React](/learn/thinking-in-react#step-3-find-the-minimal-but-complete-representation-of-ui-state) explains what should go into state.

### Caching expensive calculations[](#caching-expensive-calculations "Link for Caching expensive calculations ")

This component computes `visibleTodos` by taking the `todos` it receives by props and filtering them according to the `filter` prop. You might feel tempted to store the result in state and update it from an Effect:

```
function TodoList({ todos, filter }) {

  const [newTodo, setNewTodo] = useState('');



  // 🔴 Avoid: redundant state and unnecessary Effect

  const [visibleTodos, setVisibleTodos] = useState([]);

  useEffect(() => {

    setVisibleTodos(getFilteredTodos(todos, filter));

  }, [todos, filter]);



  // ...

}
```

Like in the earlier example, this is both unnecessary and inefficient. First, remove the state and the Effect:

```
function TodoList({ todos, filter }) {

  const [newTodo, setNewTodo] = useState('');

  // ✅ This is fine if getFilteredTodos() is not slow.

  const visibleTodos = getFilteredTodos(todos, filter);

  // ...

}
```

Usually, this code is fine! But maybe `getFilteredTodos()` is slow or you have a lot of `todos`. In that case you don’t want to recalculate `getFilteredTodos()` if some unrelated state variable like `newTodo` has changed.

You can cache (or [“memoize”](https://en.wikipedia.org/wiki/Memoization)) an expensive calculation by wrapping it in a [`useMemo`](/reference/react/useMemo) Hook:

```
import { useMemo, useState } from 'react';



function TodoList({ todos, filter }) {

  const [newTodo, setNewTodo] = useState('');

  const visibleTodos = useMemo(() => {

    // ✅ Does not re-run unless todos or filter change

    return getFilteredTodos(todos, filter);

  }, [todos, filter]);

  // ...

}
```

Or, written as a single line:

```
import { useMemo, useState } from 'react';



function TodoList({ todos, filter }) {

  const [newTodo, setNewTodo] = useState('');

  // ✅ Does not re-run getFilteredTodos() unless todos or filter change

  const visibleTodos = useMemo(() => getFilteredTodos(todos, filter), [todos, filter]);

  // ...

}
```

**This tells React that you don’t want the inner function to re-run unless either `todos` or `filter` have changed.** React will remember the return value of `getFilteredTodos()` during the initial render. During the next renders, it will check if `todos` or `filter` are different. If they’re the same as last time, `useMemo` will return the last result it has stored. But if they are different, React will call the inner function again (and store its result).

The function you wrap in [`useMemo`](/reference/react/useMemo) runs during rendering, so this only works for [pure calculations.](/learn/keeping-components-pure)

##### Deep Dive#### How to tell if a calculation is expensive?[](#how-to-tell-if-a-calculation-is-expensive "Link for How to tell if a calculation is expensive? ")

In general, unless you’re creating or looping over thousands of objects, it’s probably not expensive. If you want to get more confidence, you can add a console log to measure the time spent in a piece of code:

```
console.time('filter array');

const visibleTodos = getFilteredTodos(todos, filter);

console.timeEnd('filter array');
```

Perform the interaction you’re measuring (for example, typing into the input). You will then see logs like `filter array: 0.15ms` in your console. If the overall logged time adds up to a significant amount (say, `1ms` or more), it might make sense to memoize that calculation. As an experiment, you can then wrap the calculation in `useMemo` to verify whether the total logged time has decreased for that interaction or not:

```
console.time('filter array');

const visibleTodos = useMemo(() => {

  return getFilteredTodos(todos, filter); // Skipped if todos and filter haven't changed

}, [todos, filter]);

console.timeEnd('filter array');
```

`useMemo` won’t make the *first* render faster. It only helps you skip unnecessary work on updates.

Keep in mind that your machine is probably faster than your users’ so it’s a good idea to test the performance with an artificial slowdown. For example, Chrome offers a [CPU Throttling](https://developer.chrome.com/blog/new-in-devtools-61/#throttling) option for this.

Also note that measuring performance in development will not give you the most accurate results. (For example, when [Strict Mode](/reference/react/StrictMode) is on, you will see each component render twice rather than once.) To get the most accurate timings, build your app for production and test it on a device like your users have.

### Resetting all state when a prop changes[](#resetting-all-state-when-a-prop-changes "Link for Resetting all state when a prop changes ")

This `ProfilePage` component receives a `userId` prop. The page contains a comment input, and you use a `comment` state variable to hold its value. One day, you notice a problem: when you navigate from one profile to another, the `comment` state does not get reset. As a result, it’s easy to accidentally post a comment on a wrong user’s profile. To fix the issue, you want to clear out the `comment` state variable whenever the `userId` changes:

```
export default function ProfilePage({ userId }) {

  const [comment, setComment] = useState('');



  // 🔴 Avoid: Resetting state on prop change in an Effect

  useEffect(() => {

    setComment('');

  }, [userId]);

  // ...

}
```

This is inefficient because `ProfilePage` and its children will first render with the stale value, and then render again. It is also complicated because you’d need to do this in *every* component that has some state inside `ProfilePage`. For example, if the comment UI is nested, you’d want to clear out nested comment state too.

Instead, you can tell React that each user’s profile is conceptually a *different* profile by giving it an explicit key. Split your component in two and pass a `key` attribute from the outer component to the inner one:

```
export default function ProfilePage({ userId }) {

  return (

    <Profile

      userId={userId}

      key={userId}

    />

  );

}



function Profile({ userId }) {

  // ✅ This and any other state below will reset on key change automatically

  const [comment, setComment] = useState('');

  // ...

}
```

Normally, React preserves the state when the same component is rendered in the same spot. **By passing `userId` as a `key` to the `Profile` component, you’re asking React to treat two `Profile` components with different `userId` as two different components that should not share any state.** Whenever the key (which you’ve set to `userId`) changes, React will recreate the DOM and [reset the state](/learn/preserving-and-resetting-state#option-2-resetting-state-with-a-key) of the `Profile` component and all of its children. Now the `comment` field will clear out automatically when navigating between profiles.

Note that in this example, only the outer `ProfilePage` component is exported and visible to other files in the project. Components rendering `ProfilePage` don’t need to pass the key to it: they pass `userId` as a regular prop. The fact `ProfilePage` passes it as a `key` to the inner `Profile` component is an implementation detail.

### Adjusting some state when a prop changes[](#adjusting-some-state-when-a-prop-changes "Link for Adjusting some state when a prop changes ")

Sometimes, you might want to reset or adjust a part of the state on a prop change, but not all of it.

This `List` component receives a list of `items` as a prop, and maintains the selected item in the `selection` state variable. You want to reset the `selection` to `null` whenever the `items` prop receives a different array:

```
function List({ items }) {

  const [isReverse, setIsReverse] = useState(false);

  const [selection, setSelection] = useState(null);



  // 🔴 Avoid: Adjusting state on prop change in an Effect

  useEffect(() => {

    setSelection(null);

  }, [items]);

  // ...

}
```

This, too, is not ideal. Every time the `items` change, the `List` and its child components will render with a stale `selection` value at first. Then React will update the DOM and run the Effects. Finally, the `setSelection(null)` call will cause another re-render of the `List` and its child components, restarting this whole process again.

Start by deleting the Effect. Instead, adjust the state directly during rendering:

```
function List({ items }) {

  const [isReverse, setIsReverse] = useState(false);

  const [selection, setSelection] = useState(null);



  // Better: Adjust the state while rendering

  const [prevItems, setPrevItems] = useState(items);

  if (items !== prevItems) {

    setPrevItems(items);

    setSelection(null);

  }

  // ...

}
```

[Storing information from previous renders](/reference/react/useState#storing-information-from-previous-renders) like this can be hard to understand, but it’s better than updating the same state in an Effect. In the above example, `setSelection` is called directly during a render. React will re-render the `List` *immediately* after it exits with a `return` statement. React has not rendered the `List` children or updated the DOM yet, so this lets the `List` children skip rendering the stale `selection` value.

When you update a component during rendering, React throws away the returned JSX and immediately retries rendering. To avoid very slow cascading retries, React only lets you update the *same* component’s state during a render. If you update another component’s state during a render, you’ll see an error. A condition like `items !== prevItems` is necessary to avoid loops. You may adjust state like this, but any other side effects (like changing the DOM or setting timeouts) should stay in event handlers or Effects to [keep components pure.](/learn/keeping-components-pure)

**Although this pattern is more efficient than an Effect, most components shouldn’t need it either.** No matter how you do it, adjusting state based on props or other state makes your data flow more difficult to understand and debug. Always check whether you can [reset all state with a key](#resetting-all-state-when-a-prop-changes) or [calculate everything during rendering](#updating-state-based-on-props-or-state) instead. For example, instead of storing (and resetting) the selected *item*, you can store the selected *item ID:*

```
function List({ items }) {

  const [isReverse, setIsReverse] = useState(false);

  const [selectedId, setSelectedId] = useState(null);

  // ✅ Best: Calculate everything during rendering

  const selection = items.find(item => item.id === selectedId) ?? null;

  // ...

}
```

Now there is no need to “adjust” the state at all. If the item with the selected ID is in the list, it remains selected. If it’s not, the `selection` calculated during rendering will be `null` because no matching item was found. This behavior is different, but arguably better because most changes to `items` preserve the selection.

### Sharing logic between event handlers[](#sharing-logic-between-event-handlers "Link for Sharing logic between event handlers ")

Let’s say you have a product page with two buttons (Buy and Checkout) that both let you buy that product. You want to show a notification whenever the user puts the product in the cart. Calling `showNotification()` in both buttons’ click handlers feels repetitive so you might be tempted to place this logic in an Effect:

```
function ProductPage({ product, addToCart }) {

  // 🔴 Avoid: Event-specific logic inside an Effect

  useEffect(() => {

    if (product.isInCart) {

      showNotification(`Added ${product.name} to the shopping cart!`);

    }

  }, [product]);



  function handleBuyClick() {

    addToCart(product);

  }



  function handleCheckoutClick() {

    addToCart(product);

    navigateTo('/checkout');

  }

  // ...

}
```

This Effect is unnecessary. It will also most likely cause bugs. For example, let’s say that your app “remembers” the shopping cart between the page reloads. If you add a product to the cart once and refresh the page, the notification will appear again. It will keep appearing every time you refresh that product’s page. This is because `product.isInCart` will already be `true` on the page load, so the Effect above will call `showNotification()`.

**When you’re not sure whether some code should be in an Effect or in an event handler, ask yourself *why* this code needs to run. Use Effects only for code that should run *because* the component was displayed to the user.** In this example, the notification should appear because the user *pressed the button*, not because the page was displayed! Delete the Effect and put the shared logic into a function called from both event handlers:

```
function ProductPage({ product, addToCart }) {

  // ✅ Good: Event-specific logic is called from event handlers

  function buyProduct() {

    addToCart(product);

    showNotification(`Added ${product.name} to the shopping cart!`);

  }



  function handleBuyClick() {

    buyProduct();

  }



  function handleCheckoutClick() {

    buyProduct();

    navigateTo('/checkout');

  }

  // ...

}
```

This both removes the unnecessary Effect and fixes the bug.

### Sending a POST request[](#sending-a-post-request "Link for Sending a POST request ")

This `Form` component sends two kinds of POST requests. It sends an analytics event when it mounts. When you fill in the form and click the Submit button, it will send a POST request to the `/api/register` endpoint:

```
function Form() {

  const [firstName, setFirstName] = useState('');

  const [lastName, setLastName] = useState('');



  // ✅ Good: This logic should run because the component was displayed

  useEffect(() => {

    post('/analytics/event', { eventName: 'visit_form' });

  }, []);



  // 🔴 Avoid: Event-specific logic inside an Effect

  const [jsonToSubmit, setJsonToSubmit] = useState(null);

  useEffect(() => {

    if (jsonToSubmit !== null) {

      post('/api/register', jsonToSubmit);

    }

  }, [jsonToSubmit]);



  function handleSubmit(e) {

    e.preventDefault();

    setJsonToSubmit({ firstName, lastName });

  }

  // ...

}
```

Let’s apply the same criteria as in the example before.

The analytics POST request should remain in an Effect. This is because the *reason* to send the analytics event is that the form was displayed. (It would fire twice in development, but [see here](/learn/synchronizing-with-effects#sending-analytics) for how to deal with that.)

However, the `/api/register` POST request is not caused by the form being *displayed*. You only want to send the request at one specific moment in time: when the user presses the button. It should only ever happen *on that particular interaction*. Delete the second Effect and move that POST request into the event handler:

```
function Form() {

  const [firstName, setFirstName] = useState('');

  const [lastName, setLastName] = useState('');



  // ✅ Good: This logic runs because the component was displayed

  useEffect(() => {

    post('/analytics/event', { eventName: 'visit_form' });

  }, []);



  function handleSubmit(e) {

    e.preventDefault();

    // ✅ Good: Event-specific logic is in the event handler

    post('/api/register', { firstName, lastName });

  }

  // ...

}
```

When you choose whether to put some logic into an event handler or an Effect, the main question you need to answer is *what kind of logic* it is from the user’s perspective. If this logic is caused by a particular interaction, keep it in the event handler. If it’s caused by the user *seeing* the component on the screen, keep it in the Effect.

### Chains of computations[](#chains-of-computations "Link for Chains of computations ")

Sometimes you might feel tempted to chain Effects that each adjust a piece of state based on other state:

```
function Game() {

  const [card, setCard] = useState(null);

  const [goldCardCount, setGoldCardCount] = useState(0);

  const [round, setRound] = useState(1);

  const [isGameOver, setIsGameOver] = useState(false);



  // 🔴 Avoid: Chains of Effects that adjust the state solely to trigger each other

  useEffect(() => {

    if (card !== null && card.gold) {

      setGoldCardCount(c => c + 1);

    }

  }, [card]);



  useEffect(() => {

    if (goldCardCount > 3) {

      setRound(r => r + 1)

      setGoldCardCount(0);

    }

  }, [goldCardCount]);



  useEffect(() => {

    if (round > 5) {

      setIsGameOver(true);

    }

  }, [round]);



  useEffect(() => {

    alert('Good game!');

  }, [isGameOver]);



  function handlePlaceCard(nextCard) {

    if (isGameOver) {

      throw Error('Game already ended.');

    } else {

      setCard(nextCard);

    }

  }



  // ...
```

There are two problems with this code.

The first problem is that it is very inefficient: the component (and its children) have to re-render between each `set` call in the chain. In the example above, in the worst case (`setCard` → render → `setGoldCardCount` → render → `setRound` → render → `setIsGameOver` → render) there are three unnecessary re-renders of the tree below.

The second problem is that even if it weren’t slow, as your code evolves, you will run into cases where the “chain” you wrote doesn’t fit the new requirements. Imagine you are adding a way to step through the history of the game moves. You’d do it by updating each state variable to a value from the past. However, setting the `card` state to a value from the past would trigger the Effect chain again and change the data you’re showing. Such code is often rigid and fragile.

In this case, it’s better to calculate what you can during rendering, and adjust the state in the event handler:

```
function Game() {

  const [card, setCard] = useState(null);

  const [goldCardCount, setGoldCardCount] = useState(0);

  const [round, setRound] = useState(1);



  // ✅ Calculate what you can during rendering

  const isGameOver = round > 5;



  function handlePlaceCard(nextCard) {

    if (isGameOver) {

      throw Error('Game already ended.');

    }



    // ✅ Calculate all the next state in the event handler

    setCard(nextCard);

    if (nextCard.gold) {

      if (goldCardCount <= 3) {

        setGoldCardCount(goldCardCount + 1);

      } else {

        setGoldCardCount(0);

        setRound(round + 1);

        if (round === 5) {

          alert('Good game!');

        }

      }

    }

  }



  // ...
```

This is a lot more efficient. Also, if you implement a way to view game history, now you will be able to set each state variable to a move from the past without triggering the Effect chain that adjusts every other value. If you need to reuse logic between several event handlers, you can [extract a function](#sharing-logic-between-event-handlers) and call it from those handlers.

Remember that inside event handlers, [state behaves like a snapshot.](/learn/state-as-a-snapshot) For example, even after you call `setRound(round + 1)`, the `round` variable will reflect the value at the time the user clicked the button. If you need to use the next value for calculations, define it manually like `const nextRound = round + 1`.

In some cases, you *can’t* calculate the next state directly in the event handler. For example, imagine a form with multiple dropdowns where the options of the next dropdown depend on the selected value of the previous dropdown. Then, a chain of Effects is appropriate because you are synchronizing with network.

### Initializing the application[](#initializing-the-application "Link for Initializing the application ")

Some logic should only run once when the app loads.

You might be tempted to place it in an Effect in the top-level component:

```
function App() {

  // 🔴 Avoid: Effects with logic that should only ever run once

  useEffect(() => {

    loadDataFromLocalStorage();

    checkAuthToken();

  }, []);

  // ...

}
```

However, you’ll quickly discover that it [runs twice in development.](/learn/synchronizing-with-effects#how-to-handle-the-effect-firing-twice-in-development) This can cause issues—for example, maybe it invalidates the authentication token because the function wasn’t designed to be called twice. In general, your components should be resilient to being remounted. This includes your top-level `App` component.

Although it may not ever get remounted in practice in production, following the same constraints in all components makes it easier to move and reuse code. If some logic must run *once per app load* rather than *once per component mount*, add a top-level variable to track whether it has already executed:

```
let didInit = false;



function App() {

  useEffect(() => {

    if (!didInit) {

      didInit = true;

      // ✅ Only runs once per app load

      loadDataFromLocalStorage();

      checkAuthToken();

    }

  }, []);

  // ...

}
```

You can also run it during module initialization and before the app renders:

```
if (typeof window !== 'undefined') { // Check if we're running in the browser.

   // ✅ Only runs once per app load

  checkAuthToken();

  loadDataFromLocalStorage();

}



function App() {

  // ...

}
```

Code at the top level runs once when your component is imported—even if it doesn’t end up being rendered. To avoid slowdown or surprising behavior when importing arbitrary components, don’t overuse this pattern. Keep app-wide initialization logic to root component modules like `App.js` or in your application’s entry point.

### Notifying parent components about state changes[](#notifying-parent-components-about-state-changes "Link for Notifying parent components about state changes ")

Let’s say you’re writing a `Toggle` component with an internal `isOn` state which can be either `true` or `false`. There are a few different ways to toggle it (by clicking or dragging). You want to notify the parent component whenever the `Toggle` internal state changes, so you expose an `onChange` event and call it from an Effect:

```
function Toggle({ onChange }) {

  const [isOn, setIsOn] = useState(false);



  // 🔴 Avoid: The onChange handler runs too late

  useEffect(() => {

    onChange(isOn);

  }, [isOn, onChange])



  function handleClick() {

    setIsOn(!isOn);

  }



  function handleDragEnd(e) {

    if (isCloserToRightEdge(e)) {

      setIsOn(true);

    } else {

      setIsOn(false);

    }

  }



  // ...

}
```

Like earlier, this is not ideal. The `Toggle` updates its state first, and React updates the screen. Then React runs the Effect, which calls the `onChange` function passed from a parent component. Now the parent component will update its own state, starting another render pass. It would be better to do everything in a single pass.

Delete the Effect and instead update the state of *both* components within the same event handler:

```
function Toggle({ onChange }) {

  const [isOn, setIsOn] = useState(false);



  function updateToggle(nextIsOn) {

    // ✅ Good: Perform all updates during the event that caused them

    setIsOn(nextIsOn);

    onChange(nextIsOn);

  }



  function handleClick() {

    updateToggle(!isOn);

  }



  function handleDragEnd(e) {

    if (isCloserToRightEdge(e)) {

      updateToggle(true);

    } else {

      updateToggle(false);

    }

  }



  // ...

}
```

With this approach, both the `Toggle` component and its parent component update their state during the event. React [batches updates](/learn/queueing-a-series-of-state-updates) from different components together, so there will only be one render pass.

You might also be able to remove the state altogether, and instead receive `isOn` from the parent component:

```
// ✅ Also good: the component is fully controlled by its parent

function Toggle({ isOn, onChange }) {

  function handleClick() {

    onChange(!isOn);

  }



  function handleDragEnd(e) {

    if (isCloserToRightEdge(e)) {

      onChange(true);

    } else {

      onChange(false);

    }

  }



  // ...

}
```

[“Lifting state up”](/learn/sharing-state-between-components) lets the parent component fully control the `Toggle` by toggling the parent’s own state. This means the parent component will have to contain more logic, but there will be less state overall to worry about. Whenever you try to keep two different state variables synchronized, try lifting state up instead!

### Passing data to the parent[](#passing-data-to-the-parent "Link for Passing data to the parent ")

This `Child` component fetches some data and then passes it to the `Parent` component in an Effect:

```
function Parent() {

  const [data, setData] = useState(null);

  // ...

  return <Child onFetched={setData} />;

}



function Child({ onFetched }) {

  const data = useSomeAPI();

  // 🔴 Avoid: Passing data to the parent in an Effect

  useEffect(() => {

    if (data) {

      onFetched(data);

    }

  }, [onFetched, data]);

  // ...

}
```

In React, data flows from the parent components to their children. When you see something wrong on the screen, you can trace where the information comes from by going up the component chain until you find which component passes the wrong prop or has the wrong state. When child components update the state of their parent components in Effects, the data flow becomes very difficult to trace. Since both the child and the parent need the same data, let the parent component fetch that data, and *pass it down* to the child instead:

```
function Parent() {

  const data = useSomeAPI();

  // ...

  // ✅ Good: Passing data down to the child

  return <Child data={data} />;

}



function Child({ data }) {

  // ...

}
```

This is simpler and keeps the data flow predictable: the data flows down from the parent to the child.

### Subscribing to an external store[](#subscribing-to-an-external-store "Link for Subscribing to an external store ")

Sometimes, your components may need to subscribe to some data outside of the React state. This data could be from a third-party library or a built-in browser API. Since this data can change without React’s knowledge, you need to manually subscribe your components to it. This is often done with an Effect, for example:

```
function useOnlineStatus() {

  // Not ideal: Manual store subscription in an Effect

  const [isOnline, setIsOnline] = useState(true);

  useEffect(() => {

    function updateState() {

      setIsOnline(navigator.onLine);

    }



    updateState();



    window.addEventListener('online', updateState);

    window.addEventListener('offline', updateState);

    return () => {

      window.removeEventListener('online', updateState);

      window.removeEventListener('offline', updateState);

    };

  }, []);

  return isOnline;

}



function ChatIndicator() {

  const isOnline = useOnlineStatus();

  // ...

}
```

Here, the component subscribes to an external data store (in this case, the browser `navigator.onLine` API). Since this API does not exist on the server (so it can’t be used for the initial HTML), initially the state is set to `true`. Whenever the value of that data store changes in the browser, the component updates its state.

Although it’s common to use Effects for this, React has a purpose-built Hook for subscribing to an external store that is preferred instead. Delete the Effect and replace it with a call to [`useSyncExternalStore`](/reference/react/useSyncExternalStore):

```
function subscribe(callback) {

  window.addEventListener('online', callback);

  window.addEventListener('offline', callback);

  return () => {

    window.removeEventListener('online', callback);

    window.removeEventListener('offline', callback);

  };

}



function useOnlineStatus() {

  // ✅ Good: Subscribing to an external store with a built-in Hook

  return useSyncExternalStore(

    subscribe, // React won't resubscribe for as long as you pass the same function

    () => navigator.onLine, // How to get the value on the client

    () => true // How to get the value on the server

  );

}



function ChatIndicator() {

  const isOnline = useOnlineStatus();

  // ...

}
```

This approach is less error-prone than manually syncing mutable data to React state with an Effect. Typically, you’ll write a custom Hook like `useOnlineStatus()` above so that you don’t need to repeat this code in the individual components. [Read more about subscribing to external stores from React components.](/reference/react/useSyncExternalStore)

### Fetching data[](#fetching-data "Link for Fetching data ")

Many apps use Effects to kick off data fetching. It is quite common to write a data fetching Effect like this:

```
function SearchResults({ query }) {

  const [results, setResults] = useState([]);

  const [page, setPage] = useState(1);



  useEffect(() => {

    // 🔴 Avoid: Fetching without cleanup logic

    fetchResults(query, page).then(json => {

      setResults(json);

    });

  }, [query, page]);



  function handleNextPageClick() {

    setPage(page + 1);

  }

  // ...

}
```

You *don’t* need to move this fetch to an event handler.

This might seem like a contradiction with the earlier examples where you needed to put the logic into the event handlers! However, consider that it’s not *the typing event* that’s the main reason to fetch. Search inputs are often prepopulated from the URL, and the user might navigate Back and Forward without touching the input.

It doesn’t matter where `page` and `query` come from. While this component is visible, you want to keep `results` [synchronized](/learn/synchronizing-with-effects) with data from the network for the current `page` and `query`. This is why it’s an Effect.

However, the code above has a bug. Imagine you type `"hello"` fast. Then the `query` will change from `"h"`, to `"he"`, `"hel"`, `"hell"`, and `"hello"`. This will kick off separate fetches, but there is no guarantee about which order the responses will arrive in. For example, the `"hell"` response may arrive *after* the `"hello"` response. Since it will call `setResults()` last, you will be displaying the wrong search results. This is called a [“race condition”](https://en.wikipedia.org/wiki/Race_condition): two different requests “raced” against each other and came in a different order than you expected.

**To fix the race condition, you need to [add a cleanup function](/learn/synchronizing-with-effects#fetching-data) to ignore stale responses:**

```
function SearchResults({ query }) {

  const [results, setResults] = useState([]);

  const [page, setPage] = useState(1);

  useEffect(() => {

    let ignore = false;

    fetchResults(query, page).then(json => {

      if (!ignore) {

        setResults(json);

      }

    });

    return () => {

      ignore = true;

    };

  }, [query, page]);



  function handleNextPageClick() {

    setPage(page + 1);

  }

  // ...

}
```

This ensures that when your Effect fetches data, all responses except the last requested one will be ignored.

Handling race conditions is not the only difficulty with implementing data fetching. You might also want to think about caching responses (so that the user can click Back and see the previous screen instantly), how to fetch data on the server (so that the initial server-rendered HTML contains the fetched content instead of a spinner), and how to avoid network waterfalls (so that a child can fetch data without waiting for every parent).

**These issues apply to any UI library, not just React. Solving them is not trivial, which is why modern [frameworks](/learn/start-a-new-react-project#production-grade-react-frameworks) provide more efficient built-in data fetching mechanisms than fetching data in Effects.**

If you don’t use a framework (and don’t want to build your own) but would like to make data fetching from Effects more ergonomic, consider extracting your fetching logic into a custom Hook like in this example:

```
function SearchResults({ query }) {

  const [page, setPage] = useState(1);

  const params = new URLSearchParams({ query, page });

  const results = useData(`/api/search?${params}`);



  function handleNextPageClick() {

    setPage(page + 1);

  }

  // ...

}



function useData(url) {

  const [data, setData] = useState(null);

  useEffect(() => {

    let ignore = false;

    fetch(url)

      .then(response => response.json())

      .then(json => {

        if (!ignore) {

          setData(json);

        }

      });

    return () => {

      ignore = true;

    };

  }, [url]);

  return data;

}
```

```
import { useState, useEffect } from 'react';
import { initialTodos, createTodo } from './todos.js';

export default function TodoList() {
  const [todos, setTodos] = useState(initialTodos);
  const [showActive, setShowActive] = useState(false);
  const [activeTodos, setActiveTodos] = useState([]);
  const [visibleTodos, setVisibleTodos] = useState([]);
  const [footer, setFooter] = useState(null);

  useEffect(() => {
    setActiveTodos(todos.filter(todo => !todo.completed));
  }, [todos]);

  useEffect(() => {
    setVisibleTodos(showActive ? activeTodos : todos);
  }, [showActive, todos, activeTodos]);

  useEffect(() => {
    setFooter(
      <footer>
        {activeTodos.length} todos left
      </footer>
    );
  }, [activeTodos]);

  return (
    <>
      <label>
        <input
          type="checkbox"
          checked={showActive}
          onChange={e => setShowActive(e.target.checked)}
        />
        Show only active todos
      </label>
      <NewTodo onAdd={newTodo => setTodos([...todos, newTodo])} />
      <ul>
        {visibleTodos.map(todo => (
          <li key={todo.id}>
            {todo.completed ? <s>{todo.text}</s> : todo.text}
          </li>
        ))}
      </ul>
      {footer}
    </>
  );
}

function NewTodo({ onAdd }) {
  const [text, setText] = useState('');

  function handleAddClick() {
    setText('');
    onAdd(createTodo(text));
  }

  return (
    <>
      <input value={text} onChange={e => setText(e.target.value)} />
      <button onClick={handleAddClick}>
        Add
      </button>
    </>
  );
}
```

[PreviousSynchronizing with Effects](/learn/synchronizing-with-effects)

[NextLifecycle of Reactive Effects](/learn/lifecycle-of-reactive-effects)

***

----
url: https://legacy.reactjs.org/blog/2018/05/23/react-v-16-4.html
----

May 23, 2018 by [Andrew Clark](https://twitter.com/acdlite)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

The latest minor release adds support for an oft-requested feature: pointer events!

It also includes a bugfix for `getDerivedStateFromProps`. Check out the full [changelog](#changelog) below.

## [](#pointer-events)Pointer Events

The following event types are now available in React DOM:

* `onPointerDown`
* `onPointerMove`
* `onPointerUp`
* `onPointerCancel`
* `onGotPointerCapture`
* `onLostPointerCapture`
* `onPointerEnter`
* `onPointerLeave`
* `onPointerOver`
* `onPointerOut`

Please note that these events will only work in browsers that support the [Pointer Events](https://developer.mozilla.org/en-US/docs/Web/API/Pointer_events) specification. (At the time of this writing, this includes the latest versions of Chrome, Firefox, Edge, and Internet Explorer.) If your application depends on pointer events, we recommend using a third-party pointer events polyfill. We have opted not to include such a polyfill in React DOM, to avoid an increase in bundle size.

[Check out this example on CodeSandbox.](https://codesandbox.io/api/v1/sandboxes/define?parameters=N4IgZglgNgpgziAXKADgQwMYGs0HMYB0AVnAPYB2SoGFALjObVSACYwoNvkYTxUC-AGhABbNBEqIQARgBsAWgAs8gE4xYaODHkAjKKVzyUpOLQD0xifRXyYANwa04tgB5oRKWMQT8hICWwuBAAWtCJQzDSMjkggADwsEHYABBAsALwAOiAqpKS02QB8cWaJdoUgfnJKquowmtp6BkYm5pbRNvaOzjBuHl4kkXQxUhAepCq0yQBK9RhTYLkiyQDkapi0KwDcmeRjxpMzc7QAIgDyALLJi6TLa8fyLLfbu7tRpskAwgCS058AMgBRAD6AGVvgAtQHJdLJAAcAFYduQ3lBNHBkicVHgAEKkFzJXr0cgsDGzDYET63YzkRzJYC7ZLJUxoegw-mMpnJYKaT5oFC0ACuakQ1zQUC0gk5TJ4KgwsH-MDAtFFcIADFLyFzkrL5TAACqkFCqjWc_jIpkQOBYvC4CS4dlgcVaC3JFBqOwQUiCuCK5XstWu932L0-w0oAPIzkUE6kADuWthXUYMMKHK1XNowStBCtNtwdvIDthtBUgpgrqZydoBFoaBU-BrWloAAVSFYYCo-QLhTAABTVgjtazfFgASijGaZZjMyQA6jBmbQJous4uJBBaBBxTq8ipEuRWfBksvkjpF2g9KvSDrxRhBWi2WudTyi_BpckZ8lH53khQCB-WY5kS2LzG2cCbl65AnOodYDg4jATmak5MhQFykA47LVqm6bahAYDJH2ACEQFwLm1rYgW9pjrh2rJGoQoqOQlbJPwH7vFMwCwMqggnka_DsqRBAgRs4GQTGsFoPBjhISiU4ntmZHNqCdb0H2fbALqCpKrQvFaQa_E0ekaYaR-MoQHK2nKqK-l-lMADU346ZqdE6hZerhjZ7mwOGySOcuKAuVy_BjrJTLmq8GYUAAqhGSYIVMxmEUJeaUYWxZihKMBhX-5AAOL5N2jGLvFdJJUJymqf2wA8nARW9qKpbliFroUP8rT1WoWEJamgGKQQlVHhptWdTAopOllLWRVWLilqJJjidBkndWVaYMvJHFOf6pWMEOeAwAAGixm0BStu3oPgACax0UB8bBQHW7Lra53EqltUzyApObBp63q-s5Zl8caQPJJ9Qk_aGcDhkF4UseDHqQ3Z7KvXD_UQ39vklkaLEMcKWr3XWroRXJTJqCSnZ9jRz1cptNW8vyxV6d5MB2UzlkGSgAklv1LL0ChNO3VMOj4ipACesBPYDwv7p2oorNIKAEmQUBpMkADELAAJxa1rKww1yYgNhIcvSGqivJGqyQAExmy4euAyIEgABIwBAuChKKihqqa8lMnGaRZib3sAKT277boLVuFBy2oj5JDAYfasT7GC257NixLsLU9q_ssIHXy_ACILglC-tMsErvu29Px_ECYKQoCZdnhMbAqNMaCJD6oo10X9dQp-1tN8YEFR-QcuXsrgr0IndGvV57Os4DAXzx5RpNzomBYLguSCiSVL6CooojQzvbJAA_KsejlisyRy9vMAMDP2rLoKGDBAAgvMUFy-QFAJ_ryd5K4yYoRQGCQkhLnFjAdIwBhYuAzjAfghRAZMnAXYFBXJTBQJgfpBBbFw7agoG2DsKhYwJhgUJGM8ZyD4NcoQ8gxCOjoQcBQ_qaEMKIIwahBh7YOixVYTmGKnMuG5UYdYPk3B1ACLIkI2hdDuEFVbLw8RJ81DSIIBQRRo05HyLaq0MRnZRrqL0aYbRGCzDIPDiUMoljtQ5Xwfg3Y5J5jnAuAQMmrc-ycjiPmPEBILFBSePeEQjgCCNkBLAEJjAcSi1HH2NYeRNhjl2LJSovggA)

Huge thanks to [Philipp Spiess](https://github.com/philipp-spiess) for contributing this change!

## [](#bugfix-for-getderivedstatefromprops)Bugfix for `getDerivedStateFromProps`

`getDerivedStateFromProps` is now called every time a component is rendered, regardless of the cause of the update. Previously, it was only called if the component was re-rendered by its parent, and would not fire as the result of a local `setState`. This was an oversight in the initial implementation that has now been corrected. The previous behavior was more similar to `componentWillReceiveProps`, but the improved behavior ensures compatibility with React’s upcoming asynchronous rendering mode.

**This bug fix will not affect most apps**, but it may cause issues with a small fraction of components. The rare cases where it does matter fall into one of two categories:

### [](#1-avoid-side-effects-in-getderivedstatefromprops)1. Avoid Side Effects in `getDerivedStateFromProps`

Like the render method, `getDerivedStateFromProps` should be a pure function of props and state. Side effects in `getDerivedStateFromProps` were never supported, but since it now fires more often than it used to, the recent change may expose previously undiscovered bugs.

Side effectful code should be moved to other methods: for example, Flux dispatches typically belong inside the originating event handler, and manual DOM mutations belong inside componentDidMount or componentDidUpdate. You can read more about this in our recent post about [preparing for asynchronous rendering](/blog/2018/03/27/update-on-async-rendering.html).

### [](#2-compare-incoming-props-to-previous-props-when-computing-controlled-values)2. Compare Incoming Props to Previous Props When Computing Controlled Values

The following code assumes `getDerivedStateFromProps` only fires on prop changes:

```
static getDerivedStateFromProps(props, state) {
  if (props.value !== state.controlledValue) {
    return {
      // Since this method fires on both props and state changes, local updates
      // to the controlled value will be ignored, because the props version
      // always overrides it. Oops!
      controlledValue: props.value,
    };
  }
  return null;
}
```

One possible way to fix this is to compare the incoming value to the previous value by storing the previous props in state:

```
static getDerivedStateFromProps(props, state) {
  const prevProps = state.prevProps || {};
  // Compare the incoming prop to previous prop
  const controlledValue =
    prevProps.value !== props.value
      ? props.value
      : state.controlledValue;
  return {
    // Store the previous props in state
    prevProps: props,
    controlledValue,
  };
}
```

However, **code that “mirrors” props in state usually contains bugs**, whether you use the newer `getDerivedStateFromProps` or the legacy `componentWillReceiveProps`. We published a follow-up blog post that explains these problems in more detail, and suggests [simpler solutions that don’t involve `getDerivedStateFromProps()`](/blog/2018/06/07/you-probably-dont-need-derived-state.html).

## [](#installation)Installation

React v16.4.0 is available on the npm registry.

To install React 16 with Yarn, run:

```
yarn add react@^16.4.0 react-dom@^16.4.0
```

To install React 16 with npm, run:

```
npm install --save react@^16.4.0 react-dom@^16.4.0
```

We also provide UMD builds of React via a CDN:

```
<script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
```

Refer to the documentation for [detailed installation instructions](/docs/installation.html).

## [](#changelog)Changelog

### [](#react)React

* Add a new [experimental](https://github.com/reactjs/rfcs/pull/51) `React.unstable_Profiler` component for measuring performance. ([@bvaughn](https://github.com/bvaughn) in [#12745](https://github.com/facebook/react/pull/12745))

### [](#react-dom)React DOM

* Add support for the Pointer Events specification. ([@philipp-spiess](https://github.com/philipp-spiess) in [#12507](https://github.com/facebook/react/pull/12507))
* Properly call `getDerivedStateFromProps()` regardless of the reason for re-rendering. ([@acdlite](https://github.com/acdlite) in [#12600](https://github.com/facebook/react/pull/12600) and [#12802](https://github.com/facebook/react/pull/12802))
* Fix a bug that prevented context propagation in some cases. ([@gaearon](https://github.com/gaearon) in [#12708](https://github.com/facebook/react/pull/12708))
* Fix re-rendering of components using `forwardRef()` on a deeper `setState()`. ([@gaearon](https://github.com/gaearon) in [#12690](https://github.com/facebook/react/pull/12690))
* Fix some attributes incorrectly getting removed from custom element nodes. ([@airamrguez](https://github.com/airamrguez) in [#12702](https://github.com/facebook/react/pull/12702))
* Fix context providers to not bail out on children if there’s a legacy context provider above. ([@gaearon](https://github.com/gaearon) in [#12586](https://github.com/facebook/react/pull/12586))
* Add the ability to specify `propTypes` on a context provider component. ([@nicolevy](https://github.com/nicolevy) in [#12658](https://github.com/facebook/react/pull/12658))
* Fix a false positive warning when using `react-lifecycles-compat` in `<StrictMode>`. ([@bvaughn](https://github.com/bvaughn) in [#12644](https://github.com/facebook/react/pull/12644))
* Warn when the `forwardRef()` render function has `propTypes` or `defaultProps`. ([@bvaughn](https://github.com/bvaughn) in [#12644](https://github.com/facebook/react/pull/12644))
* Improve how `forwardRef()` and context consumers are displayed in the component stack. ([@sophiebits](https://github.com/sophiebits) in [#12777](https://github.com/facebook/react/pull/12777))
* Change internal event names. This can break third-party packages that rely on React internals in unsupported ways. ([@philipp-spiess](https://github.com/philipp-spiess) in [#12629](https://github.com/facebook/react/pull/12629))

### [](#react-test-renderer)React Test Renderer

* Fix the `getDerivedStateFromProps()` support to match the new React DOM behavior. ([@koba04](https://github.com/koba04) in [#12676](https://github.com/facebook/react/pull/12676))
* Fix a `testInstance.parent` crash when the parent is a fragment or another special node. ([@gaearon](https://github.com/gaearon) in [#12813](https://github.com/facebook/react/pull/12813))
* `forwardRef()` components are now discoverable by the test renderer traversal methods. ([@gaearon](https://github.com/gaearon) in [#12725](https://github.com/facebook/react/pull/12725))
* Shallow renderer now ignores `setState()` updaters that return `null` or `undefined`. ([@koba04](https://github.com/koba04) in [#12756](https://github.com/facebook/react/pull/12756))

### [](#react-art)React ART

* Fix reading context provided from the tree managed by React DOM. ([@acdlite](https://github.com/acdlite) in [#12779](https://github.com/facebook/react/pull/12779))

### [](#react-call-return-experimental)React Call Return (Experimental)

* This experiment was deleted because it was affecting the bundle size and the API wasn’t good enough. It’s likely to come back in the future in some other form. ([@gaearon](https://github.com/gaearon) in [#12820](https://github.com/facebook/react/pull/12820))

### [](#react-reconciler-experimental)React Reconciler (Experimental)

* The [new host config shape](https://github.com/facebook/react/blob/c601f7a64640290af85c9f0e33c78480656b46bc/packages/react-noop-renderer/src/createReactNoop.js#L82-L285) is flat and doesn’t use nested objects. ([@gaearon](https://github.com/gaearon) in [#12792](https://github.com/facebook/react/pull/12792))

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2018-05-23-react-v-16-4.md)

----
url: https://react.dev/reference/react/useActionState
----

[API Reference](/reference/react)

[Hooks](/reference/react/hooks)

# useActionState[](#undefined "Link for this heading")

`useActionState` is a React Hook that lets you update state with side effects using [Actions](/reference/react/useTransition#functions-called-in-starttransition-are-called-actions).

```
const [state, dispatchAction, isPending] = useActionState(reducerAction, initialState, permalink?);
```

* [Reference](#reference)

  * [`useActionState(reducerAction, initialState, permalink?)`](#useactionstate)
  * [`reducerAction` function](#reduceraction)

* [Usage](#usage)

  * [Adding state to an Action](#adding-state-to-an-action)
  * [Using multiple Action types](#using-multiple-action-types)
  * [Using with `useOptimistic`](#using-with-useoptimistic)
  * [Using with Action props](#using-with-action-props)
  * [Cancelling queued Actions](#cancelling-queued-actions)
  * [Using with `<form>` Action props](#use-with-a-form)
  * [Handling errors](#handling-errors)

* [Troubleshooting](#troubleshooting)

  * [My `isPending` flag is not updating](#ispending-not-updating)
  * [My Action cannot read form data](#action-cannot-read-form-data)
  * [My actions are being skipped](#actions-skipped)
  * [My state doesn’t reset](#reset-state)
  * [I’m getting an error: “An async function with useActionState was called outside of a transition.”](#async-function-outside-transition)
  * [I’m getting an error: “Cannot update action state while rendering”](#cannot-update-during-render)

***

## Reference[](#reference "Link for Reference ")

### `useActionState(reducerAction, initialState, permalink?)`[](#useactionstate "Link for this heading")

Call `useActionState` at the top level of your component to create state for the result of an Action.

```
import { useActionState } from 'react';



function reducerAction(previousState, actionPayload) {

  // ...

}



function MyCart({initialState}) {

  const [state, dispatchAction, isPending] = useActionState(reducerAction, initialState);

  // ...

}
```

[See more examples below.](#usage)

#### Parameters[](#parameters "Link for Parameters ")

* `reducerAction`: The function to be called when the Action is triggered. When called, it receives the previous state (initially the `initialState` you provided, then its previous return value) as its first argument, followed by the `actionPayload` passed to `dispatchAction`.

* `initialState`: The value you want the state to be initially. React ignores this argument after `dispatchAction` is invoked for the first time.

* **optional** `permalink`: A string containing the unique page URL that this form modifies.

  * For use on pages with [React Server Components](/reference/rsc/server-components) with progressive enhancement.
  * If `reducerAction` is a [Server Function](/reference/rsc/server-functions) and the form is submitted before the JavaScript bundle loads, the browser will navigate to the specified permalink URL rather than the current page’s URL.

#### Returns[](#returns "Link for Returns ")

`useActionState` returns an array with exactly three values:

1. The current state. During the first render, it will match the `initialState` you passed. After `dispatchAction` is invoked, it will match the value returned by the `reducerAction`.
2. A `dispatchAction` function that you call inside [Actions](/reference/react/useTransition#functions-called-in-starttransition-are-called-actions).
3. The `isPending` flag that tells you if any dispatched Actions for this Hook are pending.

#### Caveats[](#caveats "Link for Caveats ")

* `useActionState` is a Hook, so you can only call it **at the top level of your component** or your own Hooks. You can’t call it inside loops or conditions. If you need that, extract a new component and move the state into it.
* React queues and executes multiple calls to `dispatchAction` sequentially. Each call to `reducerAction` receives the result of the previous call.
* The `dispatchAction` function has a stable identity, so you will often see it omitted from Effect dependencies, but including it will not cause the Effect to fire. If the linter lets you omit a dependency without errors, it is safe to do. [Learn more about removing Effect dependencies.](/learn/removing-effect-dependencies#move-dynamic-objects-and-functions-inside-your-effect)
* When using the `permalink` option, ensure the same form component is rendered on the destination page (including the same `reducerAction` and `permalink`) so React knows how to pass the state through. Once the page becomes interactive, this parameter has no effect.
* When using Server Functions, `initialState` needs to be [serializable](/reference/rsc/use-server#serializable-parameters-and-return-values) (values like plain objects, arrays, strings, and numbers).
* If `dispatchAction` throws an error, React cancels all queued actions and shows the nearest [Error Boundary](/reference/react/Component#catching-rendering-errors-with-an-error-boundary).
* If there are multiple ongoing Actions, React batches them together. This is a limitation that may be removed in a future release.

### Note

`dispatchAction` must be called from an Action.

You can wrap it in [`startTransition`](/reference/react/startTransition), or pass it to an [Action prop](/reference/react/useTransition#exposing-action-props-from-components). Calls outside that scope won’t be treated as part of the Transition and [log an error](#async-function-outside-transition) on development mode.

***

### `reducerAction` function[](#reduceraction "Link for this heading")

The `reducerAction` function passed to `useActionState` receives the previous state and returns a new state.

Unlike reducers in `useReducer`, the `reducerAction` can be async and perform side effects:

```
async function reducerAction(previousState, actionPayload) {

  const newState = await post(actionPayload);

  return newState;

}
```

Each time you call `dispatchAction`, React calls the `reducerAction` with the `actionPayload`. The reducer will perform side effects such as posting data, and return the new state. If `dispatchAction` is called multiple times, React queues and executes them in order so the result of the previous call is passed as `previousState` for the current call.

#### Parameters[](#reduceraction-parameters "Link for Parameters ")

* `previousState`: The last state. Initially this is equal to the `initialState`. After the first call to `dispatchAction`, it’s equal to the last state returned.

* **optional** `actionPayload`: The argument passed to `dispatchAction`. It can be a value of any type. Similar to `useReducer` conventions, it is usually an object with a `type` property identifying it and, optionally, other properties with additional information.

#### Returns[](#reduceraction-returns "Link for Returns ")

`reducerAction` returns the new state, and triggers a Transition to re-render with that state.

#### Caveats[](#reduceraction-caveats "Link for Caveats ")

* `reducerAction` can be sync or async. It can perform sync actions like showing a notification, or async actions like posting updates to a server.
* `reducerAction` is not invoked twice in `<StrictMode>` since `reducerAction` is designed to allow side effects.
* The return type of `reducerAction` must match the type of `initialState`. If TypeScript infers a mismatch, you may need to explicitly annotate your state type.
* If you set state after `await` in the `reducerAction` you currently need to wrap the state update in an additional `startTransition`. See the [startTransition](/reference/react/useTransition#react-doesnt-treat-my-state-update-after-await-as-a-transition) docs for more info.
* When using Server Functions, `actionPayload` needs to be [serializable](/reference/rsc/use-server#serializable-parameters-and-return-values) (values like plain objects, arrays, strings, and numbers).

##### Deep Dive#### Why is it called `reducerAction`?[](#why-is-it-called-reduceraction "Link for this heading")

The function passed to `useActionState` is called a *reducer action* because:

* It *reduces* the previous state into a new state, like `useReducer`.
* It’s an *Action* because it’s called inside a Transition and can perform side effects.

Conceptually, `useActionState` is like `useReducer`, but you can do side effects in the reducer.

***

## Usage[](#usage "Link for Usage ")

### Adding state to an Action[](#adding-state-to-an-action "Link for Adding state to an Action ")

Call `useActionState` at the top level of your component to create state for the result of an Action.

```
import { useActionState } from 'react';



async function addToCartAction(prevCount) {

  // ...

}

function Counter() {

  const [count, dispatchAction, isPending] = useActionState(addToCartAction, 0);



  // ...

}
```

`useActionState` returns an array with exactly three items:

1. The current state, initially set to the initial state you provided.
2. The action dispatcher that lets you trigger `reducerAction`.
3. A pending state that tells you whether the Action is in progress.

To call `addToCartAction`, call the action dispatcher. React will queue calls to `addToCartAction` with the previous count.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useActionState, startTransition } from 'react';
import { addToCart } from './api';
import Total from './Total';

export default function Checkout() {
  const [count, dispatchAction, isPending] = useActionState(async (prevCount) => {
    return await addToCart(prevCount)
  }, 0);

  function handleClick() {
    startTransition(() => {
      dispatchAction();
    });
  }

  return (
    <div className="checkout">
      <h2>Checkout</h2>
      <div className="row">
        <span>Eras Tour Tickets</span>
        <span>Qty: {count}</span>
      </div>
      <div className="row">
        <button onClick={handleClick}>Add Ticket{isPending ? ' 🌀' : '  '}</button>
      </div>
      <hr />
      <Total quantity={count} />
    </div>
  );
}
```

Every time you click “Add Ticket,” React queues a call to `addToCartAction`. React shows the pending state until all the tickets are added, and then re-renders with the final state.

##### Deep Dive#### How `useActionState` queuing works[](#how-useactionstate-queuing-works "Link for this heading")

Try clicking “Add Ticket” multiple times. Every time you click, a new `addToCartAction` is queued. Since there’s an artificial 1 second delay, that means 4 clicks will take \~4 seconds to complete.

**This is intentional in the design of `useActionState`.**

We have to wait for the previous result of `addToCartAction` in order to pass the `prevCount` to the next call to `addToCartAction`. That means React has to wait for the previous Action to finish before calling the next Action.

You can typically solve this by [using with useOptimistic](/reference/react/useActionState#using-with-useoptimistic) but for more complex cases you may want to consider [cancelling queued actions](#cancelling-queued-actions) or not using `useActionState`.

***

### Using multiple Action types[](#using-multiple-action-types "Link for Using multiple Action types ")

To handle multiple types, you can pass an argument to `dispatchAction`.

By convention, it is common to write it as a switch statement. For each case in the switch, calculate and return some next state. The argument can have any shape, but it is common to pass objects with a `type` property identifying the action.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useActionState, startTransition } from 'react';
import { addToCart, removeFromCart } from './api';
import Total from './Total';

export default function Checkout() {
  const [count, dispatchAction, isPending] = useActionState(updateCartAction, 0);

  function handleAdd() {
    startTransition(() => {
      dispatchAction({ type: 'ADD' });
    });
  }

  function handleRemove() {
    startTransition(() => {
      dispatchAction({ type: 'REMOVE' });
    });
  }

  return (
    <div className="checkout">
      <h2>Checkout</h2>
      <div className="row">
        <span>Eras Tour Tickets</span>
        <span className="stepper">
          <span className="qty">{isPending ? '🌀' : count}</span>
          <span className="buttons">
            <button onClick={handleAdd}>▲</button>
            <button onClick={handleRemove}>▼</button>
          </span>
        </span>
      </div>
      <hr />
      <Total quantity={count} isPending={isPending}/>
    </div>
  );
}

async function updateCartAction(prevCount, actionPayload) {
  switch (actionPayload.type) {
    case 'ADD': {
      return await addToCart(prevCount);
    }
    case 'REMOVE': {
      return await removeFromCart(prevCount);
    }
  }
  return prevCount;
}
```

When you click to increase or decrease the quantity, an `"ADD"` or `"REMOVE"` is dispatched. In the `reducerAction`, different APIs are called to update the quantity.

In this example, we use the pending state of the Actions to replace both the quantity and the total. If you want to provide immediate feedback, such as immediately updating the quantity, you can use `useOptimistic`.

##### Deep Dive#### How is `useActionState` different from `useReducer`?[](#useactionstate-vs-usereducer "Link for this heading")

You might notice this example looks a lot like `useReducer`, but they serve different purposes:

* **Use `useReducer`** to manage state of your UI. The reducer must be pure.

* **Use `useActionState`** to manage state of your Actions. The reducer can perform side effects.

You can think of `useActionState` as `useReducer` for side effects from user Actions. Since it computes the next Action to take based on the previous Action, it has to [order the calls sequentially](/reference/react/useActionState#how-useactionstate-queuing-works). If you want to perform Actions in parallel, use `useState` and `useTransition` directly.

***

### Using with `useOptimistic`[](#using-with-useoptimistic "Link for this heading")

You can combine `useActionState` with [`useOptimistic`](/reference/react/useOptimistic) to show immediate UI feedback:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useActionState, startTransition, useOptimistic } from 'react';
import { addToCart, removeFromCart } from './api';
import Total from './Total';

export default function Checkout() {
  const [count, dispatchAction, isPending] = useActionState(updateCartAction, 0);
  const [optimisticCount, setOptimisticCount] = useOptimistic(count);

  function handleAdd() {
    startTransition(() => {
      setOptimisticCount(c => c + 1);
      dispatchAction({ type: 'ADD' });
    });
  }

  function handleRemove() {
    startTransition(() => {
      setOptimisticCount(c => c - 1);
      dispatchAction({ type: 'REMOVE' });
    });
  }

  return (
    <div className="checkout">
      <h2>Checkout</h2>
      <div className="row">
        <span>Eras Tour Tickets</span>
        <span className="stepper">
          <span className="pending">{isPending && '🌀'}</span>
          <span className="qty">{optimisticCount}</span>
          <span className="buttons">
            <button onClick={handleAdd}>▲</button>
            <button onClick={handleRemove}>▼</button>
          </span>
        </span>
      </div>
      <hr />
      <Total quantity={optimisticCount} isPending={isPending}/>
    </div>
  );
}

async function updateCartAction(prevCount, actionPayload) {
  switch (actionPayload.type) {
    case 'ADD': {
      return await addToCart(prevCount);
    }
    case 'REMOVE': {
      return await removeFromCart(prevCount);
    }
  }
  return prevCount;
}
```

`setOptimisticCount` immediately updates the quantity, and `dispatchAction()` queues the `updateCartAction`. A pending indicator appears on both the quantity and total to give the user feedback that their update is still being applied.

***

### Using with Action props[](#using-with-action-props "Link for Using with Action props ")

When you pass the `dispatchAction` function to a component that exposes an [Action prop](/reference/react/useTransition#exposing-action-props-from-components), you don’t need to call `startTransition` or `useOptimistic` yourself.

This example shows using the `increaseAction` and `decreaseAction` props of a QuantityStepper component:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useActionState } from 'react';
import { addToCart, removeFromCart } from './api';
import QuantityStepper from './QuantityStepper';
import Total from './Total';

export default function Checkout() {
  const [count, dispatchAction, isPending] = useActionState(updateCartAction, 0);

  function addAction() {
    dispatchAction({type: 'ADD'});
  }

  function removeAction() {
    dispatchAction({type: 'REMOVE'});
  }

  return (
    <div className="checkout">
      <h2>Checkout</h2>
      <div className="row">
        <span>Eras Tour Tickets</span>
        <QuantityStepper
          value={count}
          increaseAction={addAction}
          decreaseAction={removeAction}
        />
      </div>
      <hr />
      <Total quantity={count} isPending={isPending} />
    </div>
  );
}

async function updateCartAction(prevCount, actionPayload) {
  switch (actionPayload.type) {
    case 'ADD': {
      return await addToCart(prevCount);
    }
    case 'REMOVE': {
      return await removeFromCart(prevCount);
    }
  }
  return prevCount;
}
```

Since `<QuantityStepper>` has built-in support for transitions, pending state, and optimistically updating the count, you just need to tell the Action *what* to change, and *how* to change it is handled for you.

***

### Cancelling queued Actions[](#cancelling-queued-actions "Link for Cancelling queued Actions ")

You can use an `AbortController` to cancel pending Actions:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useActionState, useRef } from 'react';
import { addToCart, removeFromCart } from './api';
import QuantityStepper from './QuantityStepper';
import Total from './Total';

export default function Checkout() {
  const abortRef = useRef(null);
  const [count, dispatchAction, isPending] = useActionState(updateCartAction, 0);

  async function addAction() {
    if (abortRef.current) {
      abortRef.current.abort();
    }
    abortRef.current = new AbortController();
    await dispatchAction({ type: 'ADD', signal: abortRef.current.signal });
  }

  async function removeAction() {
    if (abortRef.current) {
      abortRef.current.abort();
    }
    abortRef.current = new AbortController();
    await dispatchAction({ type: 'REMOVE', signal: abortRef.current.signal });
  }

  return (
    <div className="checkout">
      <h2>Checkout</h2>
      <div className="row">
        <span>Eras Tour Tickets</span>
        <QuantityStepper
          value={count}
          increaseAction={addAction}
          decreaseAction={removeAction}
        />
      </div>
      <hr />
      <Total quantity={count} isPending={isPending} />
    </div>
  );
}

async function updateCartAction(prevCount, actionPayload) {
  switch (actionPayload.type) {
    case 'ADD': {
      try {
        return await addToCart(prevCount, { signal: actionPayload.signal });
      } catch (e) {
        return prevCount + 1;
      }
    }
    case 'REMOVE': {
      try {
        return await removeFromCart(prevCount, { signal: actionPayload.signal });
      } catch (e) {
        return Math.max(0, prevCount - 1);
      }
    }
  }
  return prevCount;
}
```

Try clicking increase or decrease multiple times, and notice that the total updates within 1 second no matter how many times you click. This works because it uses an `AbortController` to “complete” the previous Action so the next Action can proceed.

### Pitfall

Aborting an Action isn’t always safe.

For example, if the Action performs a mutation (like writing to a database), aborting the network request doesn’t undo the server-side change. This is why `useActionState` doesn’t abort by default. It’s only safe when you know the side effect can be safely ignored or retried.

***

### Using with `<form>` Action props[](#use-with-a-form "Link for this heading")

You can pass the `dispatchAction` function as the `action` prop to a `<form>`.

When used this way, React automatically wraps the submission in a Transition, so you don’t need to call `startTransition` yourself. The `reducerAction` receives the previous state and the submitted `FormData`:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useActionState, useOptimistic } from 'react';
import { addToCart, removeFromCart } from './api';
import Total from './Total';

export default function Checkout() {
  const [count, dispatchAction, isPending] = useActionState(updateCartAction, 0);
  const [optimisticCount, setOptimisticCount] = useOptimistic(count);

  async function formAction(formData) {
    const type = formData.get('type');
    if (type === 'ADD') {
      setOptimisticCount(c => c + 1);
    } else {
      setOptimisticCount(c => Math.max(0, c - 1));
    }
    return dispatchAction(formData);
  }

  return (
    <form action={formAction} className="checkout">
      <h2>Checkout</h2>
      <div className="row">
        <span>Eras Tour Tickets</span>
        <span className="stepper">
          <span className="pending">{isPending && '🌀'}</span>
          <span className="qty">{optimisticCount}</span>
          <span className="buttons">
            <button type="submit" name="type" value="ADD">▲</button>
            <button type="submit" name="type" value="REMOVE">▼</button>
          </span>
        </span>
      </div>
      <hr />
      <Total quantity={count} isPending={isPending} />
    </form>
  );
}

async function updateCartAction(prevCount, formData) {
  const type = formData.get('type');
  switch (type) {
    case 'ADD': {
      return await addToCart(prevCount);
    }
    case 'REMOVE': {
      return await removeFromCart(prevCount);
    }
  }
  return prevCount;
}
```

In this example, when the user clicks the stepper arrows, the button submits the form and `useActionState` calls `updateCartAction` with the form data. The example uses `useOptimistic` to immediately show the new quantity while the server confirms the update.

### React Server Components

When used with a [Server Function](/reference/rsc/server-functions), `useActionState` allows the server’s response to be shown before hydration (when React attaches to server-rendered HTML) completes. You can also use the optional `permalink` parameter for progressive enhancement (allowing the form to work before JavaScript loads) on pages with dynamic content. This is typically handled by your framework for you.

See the [`<form>`](/reference/react-dom/components/form#handle-form-submission-with-a-server-function) docs for more information on using Actions with forms.

***

### Handling errors[](#handling-errors "Link for Handling errors ")

There are two ways to handle errors with `useActionState`.

For known errors, such as “quantity not available” validation errors from your backend, you can return it as part of your `reducerAction` state and display it in the UI.

For unknown errors, such as `undefined is not a function`, you can throw an error. React will cancel all queued Actions and shows the nearest [Error Boundary](/reference/react/Component#catching-rendering-errors-with-an-error-boundary) by rethrowing the error from the `useActionState` hook.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import {useActionState, startTransition} from 'react';
import {ErrorBoundary} from 'react-error-boundary';
import {addToCart} from './api';
import Total from './Total';

function Checkout() {
  const [state, dispatchAction, isPending] = useActionState(
    async (prevState, quantity) => {
      const result = await addToCart(prevState.count, quantity);
      if (result.error) {
        // Return the error from the API as state
        return {...prevState, error: `Could not add quanitiy ${quantity}: ${result.error}`};
      }

      if (!isPending) {
        // Clear the error state for the first dispatch.
        return {count: result.count, error: null};
      }

      // Return the new count, and any errors that happened.
      return {count: result.count, error: prevState.error};


    },
    {
      count: 0,
      error: null,
    }
  );

  function handleAdd(quantity) {
    startTransition(() => {
      dispatchAction(quantity);
    });
  }

  return (
    <div className="checkout">
      <h2>Checkout</h2>
      <div className="row">
        <span>Eras Tour Tickets</span>
        <span>
          {isPending && '🌀 '}Qty: {state.count}
        </span>
      </div>
      <div className="buttons">
        <button onClick={() => handleAdd(1)}>Add 1</button>
        <button onClick={() => handleAdd(10)}>Add 10</button>
        <button onClick={() => handleAdd(NaN)}>Add NaN</button>
      </div>
      {state.error && <div className="error">{state.error}</div>}
      <hr />
      <Total quantity={state.count} isPending={isPending} />
    </div>
  );
}



export default function App() {
  return (
    <ErrorBoundary
      fallbackRender={({resetErrorBoundary}) => (
        <div className="checkout">
          <h2>Something went wrong</h2>
          <p>The action could not be completed.</p>
          <button onClick={resetErrorBoundary}>Try again</button>
        </div>
      )}>
      <Checkout />
    </ErrorBoundary>
  );
}
```

In this example, “Add 10” simulates an API that returns a validation error, which `updateCartAction` stores in state and displays inline. “Add NaN” results in an invalid count, so `updateCartAction` throws, which propagates through `useActionState` to the `ErrorBoundary` and shows a reset UI.

***

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### My `isPending` flag is not updating[](#ispending-not-updating "Link for this heading")

If you’re calling `dispatchAction` manually (not through an Action prop), make sure you wrap the call in [`startTransition`](/reference/react/startTransition):

```
import { useActionState, startTransition } from 'react';



function MyComponent() {

  const [state, dispatchAction, isPending] = useActionState(myAction, null);



  function handleClick() {

    // ✅ Correct: wrap in startTransition

    startTransition(() => {

      dispatchAction();

    });

  }



  // ...

}
```

When `dispatchAction` is passed to an Action prop, React automatically wraps it in a Transition.

***

### My Action cannot read form data[](#action-cannot-read-form-data "Link for My Action cannot read form data ")

When you use `useActionState`, the `reducerAction` receives an extra argument as its first argument: the previous or initial state. The submitted form data is therefore its second argument instead of its first.

```
// Without useActionState

function action(formData) {

  const name = formData.get('name');

}



// With useActionState

function action(prevState, formData) {

  const name = formData.get('name');

}
```

***

### My actions are being skipped[](#actions-skipped "Link for My actions are being skipped ")

If you call `dispatchAction` multiple times and some of them don’t run, it may be because an earlier `dispatchAction` call threw an error.

When a `reducerAction` throws, React skips all subsequently queued `dispatchAction` calls.

To handle this, catch errors within your `reducerAction` and return an error state instead of throwing:

```
async function myReducerAction(prevState, data) {

  try {

    const result = await submitData(data);

    return { success: true, data: result };

  } catch (error) {

    // ✅ Return error state instead of throwing

    return { success: false, error: error.message };

  }

}
```

***

### My state doesn’t reset[](#reset-state "Link for My state doesn’t reset ")

`useActionState` doesn’t provide a built-in reset function. To reset the state, you can design your `reducerAction` to handle a reset signal:

```
const initialState = { name: '', error: null };



async function formAction(prevState, payload) {

  // Handle reset

  if (payload === null) {

    return initialState;

  }

  // Normal action logic

  const result = await submitData(payload);

  return result;

}



function MyComponent() {

  const [state, dispatchAction, isPending] = useActionState(formAction, initialState);



  function handleReset() {

    startTransition(() => {

      dispatchAction(null); // Pass null to trigger reset

    });

  }



  // ...

}
```

Alternatively, you can add a `key` prop to the component using `useActionState` to force it to remount with fresh state, or a `<form>` `action` prop, which resets automatically after submission.

***

### I’m getting an error: “An async function with useActionState was called outside of a transition.”[](#async-function-outside-transition "Link for I’m getting an error: “An async function with useActionState was called outside of a transition.” ")

A common mistake is to forget to call `dispatchAction` from inside a Transition:

Console

An async function with useActionState was called outside of a transition. This is likely not what you intended (for example, isPending will not update correctly). Either call the returned function inside startTransition, or pass it to an `action` or `formAction` prop.

This error happens because `dispatchAction` must run inside a Transition:

```
function MyComponent() {

  const [state, dispatchAction, isPending] = useActionState(myAsyncAction, null);



  function handleClick() {

    // ❌ Wrong: calling dispatchAction outside a Transition

    dispatchAction();

  }



  // ...

}
```

To fix, either wrap the call in [`startTransition`](/reference/react/startTransition):

```
import { useActionState, startTransition } from 'react';



function MyComponent() {

  const [state, dispatchAction, isPending] = useActionState(myAsyncAction, null);



  function handleClick() {

    // ✅ Correct: wrap in startTransition

    startTransition(() => {

      dispatchAction();

    });

  }



  // ...

}
```

Or pass `dispatchAction` to an Action prop, is call in a Transition:

```
function MyComponent() {

  const [state, dispatchAction, isPending] = useActionState(myAsyncAction, null);



  // ✅ Correct: action prop wraps in a Transition for you

  return <Button action={dispatchAction}>...</Button>;

}
```

***

### I’m getting an error: “Cannot update action state while rendering”[](#cannot-update-during-render "Link for I’m getting an error: “Cannot update action state while rendering” ")

You cannot call `dispatchAction` during render:

Console

Cannot update action state while rendering.

This causes an infinite loop because calling `dispatchAction` schedules a state update, which triggers a re-render, which calls `dispatchAction` again.

```
function MyComponent() {

  const [state, dispatchAction, isPending] = useActionState(myAction, null);



  // ❌ Wrong: calling dispatchAction during render

  dispatchAction();



  // ...

}
```

To fix, only call `dispatchAction` in response to user events (like form submissions or button clicks).

[PreviousHooks](/reference/react/hooks)

[NextuseCallback](/reference/react/useCallback)

***

----
url: https://react.dev/reference/eslint-plugin-react-hooks/lints/rules-of-hooks
----

[API Reference](/reference/react)

[Lints](/reference/eslint-plugin-react-hooks)

# rules-of-hooks[](#undefined "Link for this heading")

Validates that components and hooks follow the [Rules of Hooks](/reference/rules/rules-of-hooks).

## Rule Details[](#rule-details "Link for Rule Details ")

React relies on the order in which hooks are called to correctly preserve state between renders. Each time your component renders, React expects the exact same hooks to be called in the exact same order. When hooks are called conditionally or in loops, React loses track of which state corresponds to which hook call, leading to bugs like state mismatches and “Rendered fewer/more hooks than expected” errors.

## Common Violations[](#common-violations "Link for Common Violations ")

These patterns violate the Rules of Hooks:

* **Hooks in conditions** (`if`/`else`, ternary, `&&`/`||`)
* **Hooks in loops** (`for`, `while`, `do-while`)
* **Hooks after early returns**
* **Hooks in callbacks/event handlers**
* **Hooks in async functions**
* **Hooks in class methods**
* **Hooks at module level**

### Note

### `use` hook[](#use-hook "Link for this heading")

The `use` hook is different from other React hooks. You can call it conditionally and in loops:

```
// ✅ `use` can be conditional

if (shouldFetch) {

  const data = use(fetchPromise);

}



// ✅ `use` can be in loops

for (const promise of promises) {

  results.push(use(promise));

}
```

However, `use` still has restrictions:

* Can’t be wrapped in try/catch
* Must be called inside a component or hook

Learn more: [`use` API Reference](/reference/react/use)

### Invalid[](#invalid "Link for Invalid ")

Examples of incorrect code for this rule:

```
// ❌ Hook in condition

if (isLoggedIn) {

  const [user, setUser] = useState(null);

}



// ❌ Hook after early return

if (!data) return <Loading />;

const [processed, setProcessed] = useState(data);



// ❌ Hook in callback

<button onClick={() => {

  const [clicked, setClicked] = useState(false);

}}/>



// ❌ `use` in try/catch

try {

  const data = use(promise);

} catch (e) {

  // error handling

}



// ❌ Hook at module level

const globalState = useState(0); // Outside component
```

### Valid[](#valid "Link for Valid ")

Examples of correct code for this rule:

```
function Component({ isSpecial, shouldFetch, fetchPromise }) {

  // ✅ Hooks at top level

  const [count, setCount] = useState(0);

  const [name, setName] = useState('');



  if (!isSpecial) {

    return null;

  }



  if (shouldFetch) {

    // ✅ `use` can be conditional

    const data = use(fetchPromise);

    return <div>{data}</div>;

  }



  return <div>{name}: {count}</div>;

}
```

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### I want to fetch data based on some condition[](#conditional-data-fetching "Link for I want to fetch data based on some condition ")

You’re trying to conditionally call useEffect:

```
// ❌ Conditional hook

if (isLoggedIn) {

  useEffect(() => {

    fetchUserData();

  }, []);

}
```

Call the hook unconditionally, check condition inside:

```
// ✅ Condition inside hook

useEffect(() => {

  if (isLoggedIn) {

    fetchUserData();

  }

}, [isLoggedIn]);
```

### Note

There are better ways to fetch data rather than in a useEffect. Consider using TanStack Query, useSWR, or React Router 6.4+ for data fetching. These solutions handle deduplicating requests, caching responses, and avoiding network waterfalls.

Learn more: [Fetching Data](/learn/synchronizing-with-effects#fetching-data)

### I need different state for different scenarios[](#conditional-state-initialization "Link for I need different state for different scenarios ")

You’re trying to conditionally initialize state:

```
// ❌ Conditional state

if (userType === 'admin') {

  const [permissions, setPermissions] = useState(adminPerms);

} else {

  const [permissions, setPermissions] = useState(userPerms);

}
```

Always call useState, conditionally set the initial value:

```
// ✅ Conditional initial value

const [permissions, setPermissions] = useState(

  userType === 'admin' ? adminPerms : userPerms

);
```

## Options[](#options "Link for Options ")

You can configure custom effect hooks using shared ESLint settings (available in `eslint-plugin-react-hooks` 6.1.1 and later):

```
{

  "settings": {

    "react-hooks": {

      "additionalEffectHooks": "(useMyEffect|useCustomEffect)"

    }

  }

}
```

* `additionalEffectHooks`: Regex pattern matching custom hooks that should be treated as effects. This allows `useEffectEvent` and similar event functions to be called from your custom effect hooks.

This shared configuration is used by both `rules-of-hooks` and `exhaustive-deps` rules, ensuring consistent behavior across all hook-related linting.

[Previousexhaustive-deps](/reference/eslint-plugin-react-hooks/lints/exhaustive-deps)

[Nextcomponent-hook-factories](/reference/eslint-plugin-react-hooks/lints/component-hook-factories)

***

----
url: https://18.react.dev/reference/react-dom/components/textarea
----

[API Reference](/reference/react)

[Components](/reference/react-dom/components)

# \<textarea>[](#undefined "Link for this heading")

The [built-in browser `<textarea>` component](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea) lets you render a multiline text input.

```
<textarea />
```

***

## Reference[](#reference "Link for Reference ")

### `<textarea>`[](#textarea "Link for this heading")

To display a text area, render the [built-in browser `<textarea>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea) component.

```
<textarea name="postContent" />
```

[See more examples below.](#usage)

#### Props[](#props "Link for Props ")

`<textarea>` supports all [common element props.](/reference/react-dom/components/common#props)

***

## Usage[](#usage "Link for Usage ")

### Displaying a text area[](#displaying-a-text-area "Link for Displaying a text area ")

Render `<textarea>` to display a text area. You can specify its default size with the [`rows`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea#rows) and [`cols`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea#cols) attributes, but by default the user will be able to resize it. To disable resizing, you can specify `resize: none` in the CSS.

```
export default function NewPost() {
  return (
    <label>
      Write your post:
      <textarea name="postContent" rows={4} cols={40} />
    </label>
  );
}
```

***

### Providing a label for a text area[](#providing-a-label-for-a-text-area "Link for Providing a label for a text area ")

Typically, you will place every `<textarea>` inside a [`<label>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/label) tag. This tells the browser that this label is associated with that text area. When the user clicks the label, the browser will focus the text area. It’s also essential for accessibility: a screen reader will announce the label caption when the user focuses the text area.

If you can’t nest `<textarea>` into a `<label>`, associate them by passing the same ID to `<textarea id>` and [`<label htmlFor>`.](https://developer.mozilla.org/en-US/docs/Web/API/HTMLLabelElement/htmlFor) To avoid conflicts between instances of one component, generate such an ID with [`useId`.](/reference/react/useId)

```
import { useId } from 'react';

export default function Form() {
  const postTextAreaId = useId();
  return (
    <>
      <label htmlFor={postTextAreaId}>
        Write your post:
      </label>
      <textarea
        id={postTextAreaId}
        name="postContent"
        rows={4}
        cols={40}
      />
    </>
  );
}
```

***

### Providing an initial value for a text area[](#providing-an-initial-value-for-a-text-area "Link for Providing an initial value for a text area ")

You can optionally specify the initial value for the text area. Pass it as the `defaultValue` string.

```
export default function EditPost() {
  return (
    <label>
      Edit your post:
      <textarea
        name="postContent"
        defaultValue="I really enjoyed biking yesterday!"
        rows={4}
        cols={40}
      />
    </label>
  );
}
```

### Pitfall

Unlike in HTML, passing initial text like `<textarea>Some content</textarea>` is not supported.

***

### Reading the text area value when submitting a form[](#reading-the-text-area-value-when-submitting-a-form "Link for Reading the text area value when submitting a form ")

Add a [`<form>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form) around your textarea with a [`<button type="submit">`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button) inside. It will call your `<form onSubmit>` event handler. By default, the browser will send the form data to the current URL and refresh the page. You can override that behavior by calling `e.preventDefault()`. Read the form data with [`new FormData(e.target)`](https://developer.mozilla.org/en-US/docs/Web/API/FormData).

```
export default function EditPost() {
  function handleSubmit(e) {
    // Prevent the browser from reloading the page
    e.preventDefault();

    // Read the form data
    const form = e.target;
    const formData = new FormData(form);

    // You can pass formData as a fetch body directly:
    fetch('/some-api', { method: form.method, body: formData });

    // Or you can work with it as a plain object:
    const formJson = Object.fromEntries(formData.entries());
    console.log(formJson);
  }

  return (
    <form method="post" onSubmit={handleSubmit}>
      <label>
        Post title: <input name="postTitle" defaultValue="Biking" />
      </label>
      <label>
        Edit your post:
        <textarea
          name="postContent"
          defaultValue="I really enjoyed biking yesterday!"
          rows={4}
          cols={40}
        />
      </label>
      <hr />
      <button type="reset">Reset edits</button>
      <button type="submit">Save post</button>
    </form>
  );
}
```

### Note

Give a `name` to your `<textarea>`, for example `<textarea name="postContent" />`. The `name` you specified will be used as a key in the form data, for example `{ postContent: "Your post" }`.

### Pitfall

By default, *any* `<button>` inside a `<form>` will submit it. This can be surprising! If you have your own custom `Button` React component, consider returning [`<button type="button">`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/button) instead of `<button>`. Then, to be explicit, use `<button type="submit">` for buttons that *are* supposed to submit the form.

***

### Controlling a text area with a state variable[](#controlling-a-text-area-with-a-state-variable "Link for Controlling a text area with a state variable ")

A text area like `<textarea />` is *uncontrolled.* Even if you [pass an initial value](#providing-an-initial-value-for-a-text-area) like `<textarea defaultValue="Initial text" />`, your JSX only specifies the initial value, not the value right now.

**To render a *controlled* text area, pass the `value` prop to it.** React will force the text area to always have the `value` you passed. Typically, you will control a text area by declaring a [state variable:](/reference/react/useState)

```
function NewPost() {

  const [postContent, setPostContent] = useState(''); // Declare a state variable...

  // ...

  return (

    <textarea

      value={postContent} // ...force the input's value to match the state variable...

      onChange={e => setPostContent(e.target.value)} // ... and update the state variable on any edits!

    />

  );

}
```

This is useful if you want to re-render some part of the UI in response to every keystroke.

```
{
  "dependencies": {
    "react": "latest",
    "react-dom": "latest",
    "react-scripts": "latest",
    "remarkable": "2.0.1"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject"
  },
  "devDependencies": {}
}
```

### Pitfall

**If you pass `value` without `onChange`, it will be impossible to type into the text area.** When you control a text area by passing some `value` to it, you *force* it to always have the value you passed. So if you pass a state variable as a `value` but forget to update that state variable synchronously during the `onChange` event handler, React will revert the text area after every keystroke back to the `value` that you specified.

***

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### My text area doesn’t update when I type into it[](#my-text-area-doesnt-update-when-i-type-into-it "Link for My text area doesn’t update when I type into it ")

If you render a text area with `value` but no `onChange`, you will see an error in the console:

```
// 🔴 Bug: controlled text area with no onChange handler

<textarea value={something} />
```

Console

You provided a `value` prop to a form field without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultValue`. Otherwise, set either `onChange` or `readOnly`.

As the error message suggests, if you only wanted to [specify the *initial* value,](#providing-an-initial-value-for-a-text-area) pass `defaultValue` instead:

```
// ✅ Good: uncontrolled text area with an initial value

<textarea defaultValue={something} />
```

If you want [to control this text area with a state variable,](#controlling-a-text-area-with-a-state-variable) specify an `onChange` handler:

```
// ✅ Good: controlled text area with onChange

<textarea value={something} onChange={e => setSomething(e.target.value)} />
```

If the value is intentionally read-only, add a `readOnly` prop to suppress the error:

```
// ✅ Good: readonly controlled text area without on change

<textarea value={something} readOnly={true} />
```

***

### My text area caret jumps to the beginning on every keystroke[](#my-text-area-caret-jumps-to-the-beginning-on-every-keystroke "Link for My text area caret jumps to the beginning on every keystroke ")

If you [control a text area,](#controlling-a-text-area-with-a-state-variable) you must update its state variable to the text area’s value from the DOM during `onChange`.

You can’t update it to something other than `e.target.value`:

```
function handleChange(e) {

  // 🔴 Bug: updating an input to something other than e.target.value

  setFirstName(e.target.value.toUpperCase());

}
```

You also can’t update it asynchronously:

```
function handleChange(e) {

  // 🔴 Bug: updating an input asynchronously

  setTimeout(() => {

    setFirstName(e.target.value);

  }, 100);

}
```

To fix your code, update it synchronously to `e.target.value`:

```
function handleChange(e) {

  // ✅ Updating a controlled input to e.target.value synchronously

  setFirstName(e.target.value);

}
```

If this doesn’t fix the problem, it’s possible that the text area gets removed and re-added from the DOM on every keystroke. This can happen if you’re accidentally [resetting state](/learn/preserving-and-resetting-state) on every re-render. For example, this can happen if the text area or one of its parents always receives a different `key` attribute, or if you nest component definitions (which is not allowed in React and causes the “inner” component to remount on every render).

***

### I’m getting an error: “A component is changing an uncontrolled input to be controlled”[](#im-getting-an-error-a-component-is-changing-an-uncontrolled-input-to-be-controlled "Link for I’m getting an error: “A component is changing an uncontrolled input to be controlled” ")

If you provide a `value` to the component, it must remain a string throughout its lifetime.

You cannot pass `value={undefined}` first and later pass `value="some string"` because React won’t know whether you want the component to be uncontrolled or controlled. A controlled component should always receive a string `value`, not `null` or `undefined`.

If your `value` is coming from an API or a state variable, it might be initialized to `null` or `undefined`. In that case, either set it to an empty string (`''`) initially, or pass `value={someValue ?? ''}` to ensure `value` is a string.

[Previous\<select>](/reference/react-dom/components/select)

[Next\<link>](/reference/react-dom/components/link)

***

----
url: https://18.react.dev/
----

# React

The library for web and native user interfaces

[Learn React](/learn)[API Reference](/reference/react)

## Create user interfaces from components

React lets you build user interfaces out of individual pieces called components. Create your own React components like `Thumbnail`, `LikeButton`, and `Video`. Then combine them into entire screens, pages, and apps.

### Video.js

```
function Video({ video }) {

  return (

    <div>

      <Thumbnail video={video} />

      <a href={video.url}>

        <h3>{video.title}</h3>

        <p>{video.description}</p>

      </a>

      <LikeButton video={video} />

    </div>

  );

}
```

```
function VideoList({ videos, emptyHeading }) {

  const count = videos.length;

  let heading = emptyHeading;

  if (count > 0) {

    const noun = count > 1 ? 'Videos' : 'Video';

    heading = count + ' ' + noun;

  }

  return (

    <section>

      <h2>{heading}</h2>

      {videos.map(video =>

        <Video key={video.id} video={video} />

      )}

    </section>

  );

}
```

```
import { useState } from 'react';



function SearchableVideoList({ videos }) {

  const [searchText, setSearchText] = useState('');

  const foundVideos = filterVideos(videos, searchText);

  return (

    <>

      <SearchInput

        value={searchText}

        onChange={newText => setSearchText(newText)} />

      <VideoList

        videos={foundVideos}

        emptyHeading={`No matches for “${searchText}”`} />

    </>

  );

}
```

----------------

React is a library. It lets you put components together, but it doesn’t prescribe how to do routing and data fetching. To build an entire app with React, we recommend a full-stack React framework like [Next.js](https://nextjs.org) or [Remix](https://remix.run).

### confs/\[slug].js

```
import { db } from './database.js';

import { Suspense } from 'react';



async function ConferencePage({ slug }) {

  const conf = await db.Confs.find({ slug });

  return (

    <ConferenceLayout conf={conf}>

      <Suspense fallback={<TalksLoading />}>

        <Talks confId={conf.id} />

      </Suspense>

    </ConferenceLayout>

  );

}



async function Talks({ confId }) {

  const talks = await db.Talks.findAll({ confId });

  const videos = talks.map(talk => talk.video);

  return <SearchableVideoList videos={videos} />;

}
```

[Get started with a framework](/learn/start-a-new-react-project)

## Use the best from every platform

People love web and native apps for different reasons. React lets you build both web apps and native apps using the same skills. It leans upon each platform’s unique strengths to let your interfaces feel just right on every platform.

example.com

#### Stay true to the web

People expect web app pages to load fast. On the server, React lets you start streaming HTML while you’re still fetching data, progressively filling in the remaining content before any JavaScript code loads. On the client, React can use standard web APIs to keep your UI responsive even in the middle of rendering.

5:15 PM

## [React Compiler Beta Release and Roadmap](/blog/2024/10/21/react-compiler-beta-release)

[October 21, 2024](/blog/2024/10/21/react-compiler-beta-release)

## [React Conf 2024 Recap](/blog/2024/05/22/react-conf-2024-recap)

[May 22, 2024](/blog/2024/05/22/react-conf-2024-recap)

## [React 19 RC](/blog/2024/04/25/react-19)

[April 25, 2024](/blog/2024/04/25/react-19)

## [React 19 RC Upgrade Guide](/blog/2024/04/25/react-19-upgrade-guide)

[April 25, 2024](/blog/2024/04/25/react-19-upgrade-guide)

[Read more React news](/blog)

Join a community\
of millions
-----------

You’re not alone. Two million developers from all over the world visit the React docs every month. React is something that people and teams can agree on.

This is why React is more than a library, an architecture, or even an ecosystem. React is a community. It’s a place where you can ask for help, find opportunities, and meet new friends. You will meet both developers and designers, beginners and experts, researchers and artists, teachers and students. Our backgrounds may be very different, but React lets us all create user interfaces together.

Welcome to the\
React community
---------------

[Get Started](/learn)

----
url: https://legacy.reactjs.org/docs/faq-versioning.html
----

React follows [semantic versioning (semver)](https://semver.org/) principles.

That means that with a version number **x.y.z**:

* When releasing **critical bug fixes**, we make a **patch release** by changing the **z** number (ex: 15.6.2 to 15.6.3).
* When releasing **new features** or **non-critical fixes**, we make a **minor release** by changing the **y** number (ex: 15.6.2 to 15.7.0).
* When releasing **breaking changes**, we make a **major release** by changing the **x** number (ex: 15.6.2 to 16.0.0).

Major releases can also contain new features, and any release can include bug fixes.

Minor releases are the most common type of release.

> This versioning policy does not apply to prerelease builds in the Next or Experimental channels. [Learn more about prereleases.](/docs/release-channels.html)

### [](#breaking-changes)Breaking Changes

Breaking changes are inconvenient for everyone, so we try to minimize the number of major releases – for example, React 15 was released in April 2016 and React 16 was released in September 2017, and React 17 was released in October 2020.

Instead, we release new features in minor versions. That means that minor releases are often more interesting and compelling than majors, despite their unassuming name.

### [](#commitment-to-stability)Commitment to Stability

As we change React over time, we try to minimize the effort required to take advantage of new features. When possible, we’ll keep an older API working, even if that means putting it in a separate package. For example, [mixins have been discouraged for years](/blog/2016/07/13/mixins-considered-harmful.html) but they’re supported to this day [via create-react-class](/docs/react-without-es6.html#mixins) and many codebases continue to use them in stable, legacy code.

Over a million developers use React, collectively maintaining millions of components. The Facebook codebase alone has over 50,000 React components. That means we need to make it as easy as possible to upgrade to new versions of React; if we make large changes without a migration path, people will be stuck on old versions. We test these upgrade paths on Facebook itself – if our team of less than 10 people can update 50,000+ components alone, we hope the upgrade will be manageable for anyone using React. In many cases, we write [automated scripts](https://github.com/reactjs/react-codemod) to upgrade component syntax, which we then include in the open-source release for everyone to use.

### [](#gradual-upgrades-via-warnings)Gradual Upgrades via Warnings

Development builds of React include many helpful warnings. Whenever possible, we add warnings in preparation for future breaking changes. That way, if your app has no warnings on the latest release, it will be compatible with the next major release. This allows you to upgrade your apps one component at a time.

Development warnings won’t affect the runtime behavior of your app. That way, you can feel confident that your app will behave the same way between the development and production builds — the only differences are that the production build won’t log the warnings and that it is more efficient. (If you ever notice otherwise, please file an issue.)

### [](#what-counts-as-a-breaking-change)What Counts as a Breaking Change?

In general, we *don’t* bump the major version number for changes to:

* **Development warnings.** Since these don’t affect production behavior, we may add new warnings or modify existing warnings in between major versions. In fact, this is what allows us to reliably warn about upcoming breaking changes.
* **APIs starting with `unstable_`.** These are provided as experimental features whose APIs we are not yet confident in. By releasing these with an `unstable_` prefix, we can iterate faster and get to a stable API sooner.
* **Alpha and canary versions of React.** We provide alpha versions of React as a way to test new features early, but we need the flexibility to make changes based on what we learn in the alpha period. If you use these versions, note that APIs may change before the stable release.
* **Undocumented APIs and internal data structures.** If you access internal property names like `__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED` or `__reactInternalInstance$uk43rzhitjg`, there is no warranty. You are on your own.

This policy is designed to be pragmatic: certainly, we don’t want to cause headaches for you. If we bumped the major version for all of these changes, we would end up releasing more major versions and ultimately causing more versioning pain for the community. It would also mean that we can’t make progress in improving React as fast as we’d like.

That said, if we expect that a change on this list will cause broad problems in the community, we will still do our best to provide a gradual migration path.

### [](#minors-versus-patches)If a Minor Release Includes No New Features, Why Isn’t It a Patch?

It’s possible that a minor release will not include new features. [This is allowed by semver](https://semver.org/#spec-item-7), which states **”\[a minor version] MAY be incremented if substantial new functionality or improvements are introduced within the private code. It MAY include patch level changes.”**

However, it does raise the question of why these releases aren’t versioned as patches instead.

The answer is that any change to React (or other software) carries some risk of breaking in unexpected ways. Imagine a scenario where a patch release that fixes one bug accidentally introduces a different bug. This would not only be disruptive to developers, but also harm their confidence in future patch releases. It’s especially regrettable if the original fix is for a bug that is rarely encountered in practice.

We have a pretty good track record for keeping React releases free of bugs, but patch releases have an even higher bar for reliability because most developers assume they can be adopted without adverse consequences.

For these reasons, we reserve patch releases only for the most critical bugs and security vulnerabilities.

If a release includes non-essential changes — such as internal refactors, changes to implementation details, performance improvements, or minor bugfixes — we will bump the minor version even when there are no new features.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/faq-versioning.md)

----
url: https://legacy.reactjs.org/blog/2015/10/28/react-v0.14.1.html
----

October 28, 2015 by [Paul O’Shannessy](https://twitter.com/zpao)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

After a couple weeks of having more people use v0.14, we’re ready to ship a patch release addressing a few issues. Thanks to everybody who has reported issues and written patches!

The release is now available for download:

* **React**\
  Dev build with warnings: <https://fb.me/react-0.14.1.js>\
  Minified build for production: <https://fb.me/react-0.14.1.min.js>
* **React with Add-Ons**\
  Dev build with warnings: <https://fb.me/react-with-addons-0.14.1.js>\
  Minified build for production: <https://fb.me/react-with-addons-0.14.1.min.js>
* **React DOM** (include React in the page before React DOM)\
  Dev build with warnings: <https://fb.me/react-dom-0.14.1.js>\
  Minified build for production: <https://fb.me/react-dom-0.14.1.min.js>

We’ve also published version `0.14.1` of the `react`, `react-dom`, and addons packages on npm and the `react` package on bower.

***

## [](#changelog)Changelog

### [](#react-dom)React DOM

* Fixed bug where events wouldn’t fire in old browsers when using React in development mode
* Fixed bug preventing use of `dangerouslySetInnerHTML` with Closure Compiler Advanced mode
* Added support for `srcLang`, `default`, and `kind` attributes for `<track>` elements
* Added support for `color` attribute
* Ensured legacy `.props` access on DOM nodes is updated on re-renders

### [](#react-testutils-add-on)React TestUtils Add-on

* Fixed `scryRenderedDOMComponentsWithClass` so it works with SVG

### [](#react-csstransitiongroup-add-on)React CSSTransitionGroup Add-on

* Fix bug preventing `0` to be used as a timeout value

### [](#react-on-bower)React on Bower

* Added `react-dom.js` to `main` to improve compatibility with tooling

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2015-10-28-react-v0.14.1.md)

----
url: https://legacy.reactjs.org/blog/2019/02/23/is-react-translated-yet.html
----

February 23, 2019 by [Nat Alison](https://twitter.com/tesseralis)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

We’re excited to announce an ongoing effort to maintain official translations of the React documentation website into different languages. Thanks to the dedicated efforts of React community members from around the world, React is now being translated into *over 30* languages! You can find them on the new [Languages](/languages) page.

In addition, the following three languages have completed translating most of the React Docs! 🎉

* **Spanish: [es.reactjs.org](https://es.reactjs.org)**
* **Japanese: [ja.reactjs.org](https://ja.reactjs.org)**
* **Brazilian Portuguese: [pt-br.reactjs.org](https://pt-br.reactjs.org)**

Special congratulations to [Alejandro Ñáñez Ortiz](https://github.com/alejandronanez), [Rainer Martínez Fraga](https://github.com/carburo), [David Morales](https://github.com/dmorales), [Miguel Alejandro Bolivar Portilla](https://github.com/Darking360), and all the contributors to the Spanish translation for being the first to *completely* translate the core pages of the docs!

## [](#why-localization-matters)Why Localization Matters

React already has many meetups and conferences around the world, but many programmers don’t use English as their primary language. We’d love to support local communities who use React by making our documentation available in most popular languages.

In the past, React community members have created unofficial translations for [Chinese](https://github.com/discountry/react), [Arabic](https://wiki.hsoub.com/React), and [Korean](https://github.com/reactjs/ko.reactjs.org/issues/4); by making an official channel for these translated docs we’re hoping to make them easier to find and help make sure that non-English-speaking users of React aren’t left behind.

## [](#contributing)Contributing

If you would like to help out on a current translation, check out the [Languages](/languages) page and click on the “Contribute” link for your language.

Can’t find your language? If you’d like to maintain your language’s translation fork, follow the instructions in the [translation repo](https://github.com/reactjs/reactjs.org-translation#starting-a-new-translation)!

## [](#backstory)Backstory

Hi everyone! I’m [Nat](https://twitter.com/tesseralis)! You may know me as the [polyhedra lady](https://www.youtube.com/watch?v=Ew-UzGC8RqQ). For the past few weeks, I’ve been helping the React team coordinate their translation effort. Here’s how I did it.

Our original approach for translations was to use a SaaS platform that allows users to submit translations. There was already a [pull request](https://github.com/reactjs/reactjs.org/pull/873) to integrate it and my original responsibility was to finish that integration. However, we had concerns about the feasibility of that integration and the current quality of translations on the platform. Our primary concern was ensuring that translations kept up to date with the main repo and didn’t become “stale”.

[Dan](https://twitter.com/dan_abramov) encouraged me to look for alternate solutions, and we stumbled across how [Vue](https://vuejs.org) maintained its translations — through different forks of the main repo on GitHub. In particular, the [Japanese translation](https://jp.vuejs.org) used a bot to periodically check for changes in the English repo and submits pull requests whenever there is a change.

This approach appealed to us for several reasons:

* It was less code integration to get off the ground.
* It encouraged active maintainers for each repo to ensure quality.
* Contributors already understand GitHub as a platform and are motivated to contribute directly to the React organization.

We started off with an initial trial period of three languages: Spanish, Japanese, and Simplified Chinese. This allowed us to work out any kinks in our process and make sure future translations are set up for success. I wanted to give the translation teams freedom to choose whatever tools they felt comfortable with. The only requirement is a [checklist](https://github.com/reactjs/reactjs.org-translation/blob/master/PROGRESS.template.md) that outlines the order of importance for translating pages.

After the trial period, we were ready to accept more languages. I created [a script](https://github.com/reactjs/reactjs.org-translation/blob/master/scripts/create.js) to automate the creation of the new language repo, and a site, [Is React Translated Yet?](https://translations.reactjs.org), to track progress on the different translations. We started *10* new translations on our first day alone!

Because of the automation, the rest of the maintenance went mostly smoothly. We eventually created a [Slack channel](https://rt-slack-invite.herokuapp.com) to make it easier for translators to share information, and I released a guide solidifying the [responsibilities of maintainers](https://github.com/reactjs/reactjs.org-translation/blob/master/maintainer-guide.md). Allowing translators to talk with each other was a great boon — for example, the Arabic, Persian, and Hebrew translations were able to talk to each other in order to get [right-to-left text](https://en.wikipedia.org/wiki/Right-to-left) working!

## [](#the-bot)The Bot

The most challenging part was getting the bot to sync changes from the English version of the site. Initially we were using the [che-tsumi](https://github.com/vuejs-jp/che-tsumi) bot created by the Japanese Vue translation team, but we soon decided to build our own bot to suit our needs. In particular, the che-tsumi bot works by [cherry picking](https://git-scm.com/docs/git-cherry-pick) new commits. This ended up causing a cavalade of new issues that were interconnected, especially when [Hooks were released](/blog/2019/02/06/react-v16.8.0.html).

In the end, we decided that instead of cherry picking each commit, it made more sense to merge all new commits and create a pull request around once a day. Conflicts are merged as-is and listed in the [pull request](https://github.com/reactjs/pt-BR.reactjs.org/pull/114), leaving a checklist for maintainers to fix.

Creating the [sync script](https://github.com/reactjs/reactjs.org-translation/blob/master/scripts/sync.js) was easy enough: it downloads the translated repo, adds the original as a remote, pulls from it, merges the conflicts, and creates a pull request.

The problem was finding a place for the bot to run. I’m a frontend developer for a reason — Heroku and its ilk are alien to me and *endlessly* frustrating. In fact, until this past Tuesday, I was running the script by hand on my local machine!

The biggest challenge was space. Each fork of the repo is around 100MB — which takes minutes to clone on my local machine. We have *32* forks, and the free tiers of most deployment platforms I checked limited you to 512MB of storage.

After lots of notepad calculations, I found a solution: delete each repo once we’ve finished the script and limit the concurrency of `sync` scripts that run at once to be within the storage requirements. Luckily, Heroku dynos have a much faster Internet connection and are able to clone even the React repo quickly.

There were other smaller issues that I ran into. I tried using the [Heroku Scheduler](https://elements.heroku.com/addons/scheduler) add-on so I didn’t have to write any actual `watch` code, but it end up running too inconsistently, and I [had an existential meltdown on Twitter](https://twitter.com/tesseralis/status/1097387938088796160) when I couldn’t figure out how to send commits from the Heroku dyno. But in the end, this frontend engineer was able to get the bot working!

There are, as always, improvements I want to make to the bot. Right now it doesn’t check whether there is an outstanding pull request before pushing another one. It’s still hard to tell the exact change that happened in the original source, and it’s possible to miss out on a needed translation change. But I trust the maintainers we’ve chosen to work through these issues, and the bot is [open source](https://github.com/reactjs/reactjs.org-translation) if anyone wants to help me make these improvements!

## [](#thanks)Thanks

Finally, I would like to extend my gratitude to the following people and groups:

* All the translation maintainers and contributors who are helping translate React to more than thirty languages.
* The [Vue.js Japan User Group](https://github.com/vuejs-jp) for initiating the idea of having bot-managed translations, and especially [Hanatani Takuma](https://github.com/potato4d) for helping us understand their approach and helping maintain the Japanese translation.
* [Soichiro Miki](https://github.com/smikitky) for many [contributions](https://github.com/reactjs/reactjs.org/pull/1636) and thoughtful comments on the overall translation process, as well as for maintaining the Japanese translation.
* [Eric Nakagawa](https://github.com/ericnakagawa) for managing our previous translation process.
* [Brian Vaughn](https://github.com/bvaughn) for setting up the [languages page](/languages) and managing all the subdomains.

And finally, thank you to [Dan Abramov](https://twitter.com/dan_abramov) for giving me this opportunity and being a great mentor along the way.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2019-02-23-is-react-translated-yet.md)

----
url: https://legacy.reactjs.org/blog/2017/09/25/react-v15.6.2.html
----

September 25, 2017 by [Nathan Hunzaker](https://github.com/nhunzaker)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

Today we’re sending out React 15.6.2. In 15.6.1, we shipped a few fixes for change events and inputs that had some unintended consequences. Those regressions have been ironed out, and we’ve also included a few more fixes to improve the stability of React across all browsers.

Additionally, 15.6.2 adds support for the [`controlList`](https://developers.google.com/web/updates/2017/03/chrome-58-media-updates#controlslist) attribute, and CSS columns are no longer appended with a `px` suffix.

## [](#installation)Installation

We recommend using [Yarn](https://yarnpkg.com/) or [npm](https://www.npmjs.com/) for managing front-end dependencies. If you’re new to package managers, the [Yarn documentation](https://yarnpkg.com/en/docs/getting-started) is a good place to get started.

To install React with Yarn, run:

```
yarn add react@^15.6.2 react-dom@^15.6.2
```

To install React with npm, run:

```
npm install --save react@^15.6.2 react-dom@^15.6.2
```

We recommend using a bundler like [webpack](https://webpack.js.org/) or [Browserify](http://browserify.org/) so you can write modular code and bundle it together into small packages to optimize load time.

Remember that by default, React runs extra checks and provides helpful warnings in development mode. When deploying your app, make sure to [use the production build](/docs/optimizing-performance.html#use-the-production-build).

In case you don’t use a bundler, we also provide pre-built bundles in the npm packages which you can [include as script tags](/docs/installation.html#using-a-cdn) on your page:

* **React**\
  Dev build with warnings: [react/dist/react.js](https://unpkg.com/react@15.6.2/dist/react.js)\
  Minified build for production: [react/dist/react.min.js](https://unpkg.com/react@15.6.2/dist/react.min.js)
* **React with Add-Ons**\
  Dev build with warnings: [react/dist/react-with-addons.js](https://unpkg.com/react@15.6.2/dist/react-with-addons.js)\
  Minified build for production: [react/dist/react-with-addons.min.js](https://unpkg.com/react@15.6.2/dist/react-with-addons.min.js)
* **React DOM** (include React in the page before React DOM)\
  Dev build with warnings: [react-dom/dist/react-dom.js](https://unpkg.com/react-dom@15.6.2/dist/react-dom.js)\
  Minified build for production: [react-dom/dist/react-dom.min.js](https://unpkg.com/react-dom@15.6.2/dist/react-dom.min.js)
* **React DOM Server** (include React in the page before React DOM Server)\
  Dev build with warnings: [react-dom/dist/react-dom-server.js](https://unpkg.com/react-dom@15.6.2/dist/react-dom-server.js)\
  Minified build for production: [react-dom/dist/react-dom-server.min.js](https://unpkg.com/react-dom@15.6.2/dist/react-dom-server.min.js)

We’ve also published version `15.6.2` of `react` and `react-dom` on npm, and the `react` package on bower.

***

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

## [](#changelog)Changelog

## [](#1562-september-25-2017)15.6.2 (September 25, 2017)

### [](#all-packages)All Packages

* Switch from BSD + Patents to MIT license

### [](#react-dom)React DOM

* Fix a bug where modifying `document.documentMode` would trigger IE detection in other browsers, breaking change events. ([@aweary](https://github.com/aweary) in [#10032](https://github.com/facebook/react/pull/10032))
* CSS Columns are treated as unitless numbers. ([@aweary](https://github.com/aweary) in [#10115](https://github.com/facebook/react/pull/10115))
* Fix bug in QtWebKit when wrapping synthetic events in proxies. ([@walrusfruitcake](https://github.com/walrusfruitcake) in [#10115](https://github.com/facebook/react/pull/10011))
* Prevent event handlers from receiving extra argument in development. ([@aweary](https://github.com/aweary) in [#10115](https://github.com/facebook/react/pull/8363))
* Fix cases where `onChange` would not fire with `defaultChecked` on radio inputs. ([@jquense](https://github.com/jquense) in [#10156](https://github.com/facebook/react/pull/10156))
* Add support for `controlList` attribute to DOM property whitelist ([@nhunzaker](https://github.com/nhunzaker) in [#9940](https://github.com/facebook/react/pull/9940))
* Fix a bug where creating an element with a ref in a constructor did not throw an error in development. ([@iansu](https://github.com/iansu) in [#10025](https://github.com/facebook/react/pull/10025))

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2017-09-25-react-v15.6.2.md)

----
url: https://react.dev/community
----

For the latest news about React, [follow **@reactjs** on Twitter](https://twitter.com/reactjs), [**@react.dev** on Bluesky](https://bsky.app/profile/react.dev) and the [official React blog](/blog) on this website.

[NextReact Conferences](/community/conferences)

***

----
url: https://react.dev/community/versioning-policy
----

[Community](/community)

# Versioning Policy[](#undefined "Link for this heading")

All stable builds of React go through a high level of testing and follow semantic versioning (semver). React also offers unstable release channels to encourage early feedback on experimental features. This page describes what you can expect from React releases.

This versioning policy describes our approach to version numbers for packages such as `react` and `react-dom`. For a list of previous releases, see the [Versions](/versions) page.

We know our users continue to use old versions of React in production. If we learn of a security vulnerability in React, we release a backported fix for all major versions that are affected by the vulnerability.

### Breaking changes[](#breaking-changes "Link for Breaking changes ")

  ```
  npm update react@canary react-dom@canary
  ```

  Or yarn:

  ```
  yarn upgrade react@canary react-dom@canary
  ```

***

----
url: https://react.dev/learn/rendering-lists
----

```
<ul>

  <li>Creola Katherine Johnson: mathematician</li>

  <li>Mario José Molina-Pasquel Henríquez: chemist</li>

  <li>Mohammad Abdus Salam: physicist</li>

  <li>Percy Lavon Julian: chemist</li>

  <li>Subrahmanyan Chandrasekhar: astrophysicist</li>

</ul>
```

The only difference among those list items is their contents, their data. You will often need to show several instances of the same component using different data when building interfaces: from lists of comments to galleries of profile images. In these situations, you can store that data in JavaScript objects and arrays and use methods like [`map()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) and [`filter()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/filter) to render lists of components from them.

Here’s a short example of how to generate a list of items from an array:

1. **Move** the data into an array:

```
const people = [

  'Creola Katherine Johnson: mathematician',

  'Mario José Molina-Pasquel Henríquez: chemist',

  'Mohammad Abdus Salam: physicist',

  'Percy Lavon Julian: chemist',

  'Subrahmanyan Chandrasekhar: astrophysicist'

];
```

2. **Map** the `people` members into a new array of JSX nodes, `listItems`:

```
const listItems = people.map(person => <li>{person}</li>);
```

3. **Return** `listItems` from your component wrapped in a `<ul>`:

```
return <ul>{listItems}</ul>;
```

Here is the result:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
const people = [
  'Creola Katherine Johnson: mathematician',
  'Mario José Molina-Pasquel Henríquez: chemist',
  'Mohammad Abdus Salam: physicist',
  'Percy Lavon Julian: chemist',
  'Subrahmanyan Chandrasekhar: astrophysicist'
];

export default function List() {
  const listItems = people.map(person =>
    <li>{person}</li>
  );
  return <ul>{listItems}</ul>;
}
```

Notice the sandbox above displays a console error:

Console

Warning: Each child in a list should have a unique “key” prop.

You’ll learn how to fix this error later on this page. Before we get to that, let’s add some structure to your data.

## Filtering arrays of items[](#filtering-arrays-of-items "Link for Filtering arrays of items ")

This data can be structured even more.

```
const people = [{

  id: 0,

  name: 'Creola Katherine Johnson',

  profession: 'mathematician',

}, {

  id: 1,

  name: 'Mario José Molina-Pasquel Henríquez',

  profession: 'chemist',

}, {

  id: 2,

  name: 'Mohammad Abdus Salam',

  profession: 'physicist',

}, {

  id: 3,

  name: 'Percy Lavon Julian',

  profession: 'chemist',

}, {

  id: 4,

  name: 'Subrahmanyan Chandrasekhar',

  profession: 'astrophysicist',

}];
```

Let’s say you want a way to only show people whose profession is `'chemist'`. You can use JavaScript’s `filter()` method to return just those people. This method takes an array of items, passes them through a “test” (a function that returns `true` or `false`), and returns a new array of only those items that passed the test (returned `true`).

You only want the items where `profession` is `'chemist'`. The “test” function for this looks like `(person) => person.profession === 'chemist'`. Here’s how to put it together:

1. **Create** a new array of just “chemist” people, `chemists`, by calling `filter()` on the `people` filtering by `person.profession === 'chemist'`:

```
const chemists = people.filter(person =>

  person.profession === 'chemist'

);
```

2. Now **map** over `chemists`:

```
const listItems = chemists.map(person =>

  <li>

     <img

       src={getImageUrl(person)}

       alt={person.name}

     />

     <p>

       <b>{person.name}:</b>

       {' ' + person.profession + ' '}

       known for {person.accomplishment}

     </p>

  </li>

);
```

3. Lastly, **return** the `listItems` from your component:

```
return <ul>{listItems}</ul>;
```

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { people } from './data.js';
import { getImageUrl } from './utils.js';

export default function List() {
  const chemists = people.filter(person =>
    person.profession === 'chemist'
  );
  const listItems = chemists.map(person =>
    <li>
      <img
        src={getImageUrl(person)}
        alt={person.name}
      />
      <p>
        <b>{person.name}:</b>
        {' ' + person.profession + ' '}
        known for {person.accomplishment}
      </p>
    </li>
  );
  return <ul>{listItems}</ul>;
}
```

### Pitfall

Arrow functions implicitly return the expression right after `=>`, so you didn’t need a `return` statement:

```
const listItems = chemists.map(person =>

  <li>...</li> // Implicit return!

);
```

However, **you must write `return` explicitly if your `=>` is followed by a `{` curly brace!**

```
const listItems = chemists.map(person => { // Curly brace

  return <li>...</li>;

});
```

Arrow functions containing `=> {` are said to have a [“block body”.](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions#function_body) They let you write more than a single line of code, but you *have to* write a `return` statement yourself. If you forget it, nothing gets returned!

## Keeping list items in order with `key`[](#keeping-list-items-in-order-with-key "Link for this heading")

Notice that all the sandboxes above show an error in the console:

Console

Warning: Each child in a list should have a unique “key” prop.

You need to give each array item a `key` — a string or a number that uniquely identifies it among other items in that array:

```
<li key={person.id}>...</li>
```

### Note

JSX elements directly inside a `map()` call always need keys!

Keys tell React which array item each component corresponds to, so that it can match them up later. This becomes important if your array items can move (e.g. due to sorting), get inserted, or get deleted. A well-chosen `key` helps React infer what exactly has happened, and make the correct updates to the DOM tree.

Rather than generating keys on the fly, you should include them in your data:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
export const people = [{
  id: 0, // Used in JSX as a key
  name: 'Creola Katherine Johnson',
  profession: 'mathematician',
  accomplishment: 'spaceflight calculations',
  imageId: 'MK3eW3A'
}, {
  id: 1, // Used in JSX as a key
  name: 'Mario José Molina-Pasquel Henríquez',
  profession: 'chemist',
  accomplishment: 'discovery of Arctic ozone hole',
  imageId: 'mynHUSa'
}, {
  id: 2, // Used in JSX as a key
  name: 'Mohammad Abdus Salam',
  profession: 'physicist',
  accomplishment: 'electromagnetism theory',
  imageId: 'bE7W1ji'
}, {
  id: 3, // Used in JSX as a key
  name: 'Percy Lavon Julian',
  profession: 'chemist',
  accomplishment: 'pioneering cortisone drugs, steroids and birth control pills',
  imageId: 'IOjWm71'
}, {
  id: 4, // Used in JSX as a key
  name: 'Subrahmanyan Chandrasekhar',
  profession: 'astrophysicist',
  accomplishment: 'white dwarf star mass calculations',
  imageId: 'lrWQx8l'
}];
```

##### Deep Dive#### Displaying several DOM nodes for each list item[](#displaying-several-dom-nodes-for-each-list-item "Link for Displaying several DOM nodes for each list item ")

What do you do when each item needs to render not one, but several DOM nodes?

The short [`<>...</>` Fragment](/reference/react/Fragment) syntax won’t let you pass a key, so you need to either group them into a single `<div>`, or use the slightly longer and [more explicit `<Fragment>` syntax:](/reference/react/Fragment#rendering-a-list-of-fragments)

```
import { Fragment } from 'react';



// ...



const listItems = people.map(person =>

  <Fragment key={person.id}>

    <h1>{person.name}</h1>

    <p>{person.bio}</p>

  </Fragment>

);
```

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { people } from './data.js';
import { getImageUrl } from './utils.js';

export default function List() {
  const listItems = people.map(person =>
    <li key={person.id}>
      <img
        src={getImageUrl(person)}
        alt={person.name}
      />
      <p>
        <b>{person.name}:</b>
        {' ' + person.profession + ' '}
        known for {person.accomplishment}
      </p>
    </li>
  );
  return (
    <article>
      <h1>Scientists</h1>
      <ul>{listItems}</ul>
    </article>
  );
}
```

[PreviousConditional Rendering](/learn/conditional-rendering)

[NextKeeping Components Pure](/learn/keeping-components-pure)

***

----
url: https://react.dev/reference/react-dom/preinitModule
----

[API Reference](/reference/react)

[APIs](/reference/react-dom)

# preinitModule[](#undefined "Link for this heading")

### Note

[React-based frameworks](/learn/creating-a-react-app) frequently handle resource loading for you, so you might not have to call this API yourself. Consult your framework’s documentation for details.

`preinitModule` lets you eagerly fetch and evaluate an ESM module.

```
preinitModule("https://example.com/module.js", {as: "script"});
```

* [Reference](#reference)
  * [`preinitModule(href, options)`](#preinitmodule)

* [Usage](#usage)

  * [Preloading when rendering](#preloading-when-rendering)
  * [Preloading in an event handler](#preloading-in-an-event-handler)

***

## Reference[](#reference "Link for Reference ")

### `preinitModule(href, options)`[](#preinitmodule "Link for this heading")

To preinit an ESM module, call the `preinitModule` function from `react-dom`.

```
import { preinitModule } from 'react-dom';



function AppRoot() {

  preinitModule("https://example.com/module.js", {as: "script"});

  // ...

}
```

***

## Usage[](#usage "Link for Usage ")

### Preloading when rendering[](#preloading-when-rendering "Link for Preloading when rendering ")

Call `preinitModule` when rendering a component if you know that it or its children will use a specific module and you’re OK with the module being evaluated and thereby taking effect immediately upon being downloaded.

```
import { preinitModule } from 'react-dom';



function AppRoot() {

  preinitModule("https://example.com/module.js", {as: "script"});

  return ...;

}
```

If you want the browser to download the module but not to execute it right away, use [`preloadModule`](/reference/react-dom/preloadModule) instead. If you want to preinit a script that isn’t an ESM module, use [`preinit`](/reference/react-dom/preinit).

### Preloading in an event handler[](#preloading-in-an-event-handler "Link for Preloading in an event handler ")

Call `preinitModule` in an event handler before transitioning to a page or state where the module will be needed. This gets the process started earlier than if you call it during the rendering of the new page or state.

```
import { preinitModule } from 'react-dom';



function CallToAction() {

  const onClick = () => {

    preinitModule("https://example.com/module.js", {as: "script"});

    startWizard();

  }

  return (

    <button onClick={onClick}>Start Wizard</button>

  );

}
```

[Previouspreinit](/reference/react-dom/preinit)

[Nextpreload](/reference/react-dom/preload)

***

----
url: https://18.react.dev/reference/react/createFactory
----

[API Reference](/reference/react)

[Legacy React APIs](/reference/react/legacy)

# createFactory[](#undefined "Link for this heading")

### Deprecated

This API will be removed in a future major version of React. [See the alternatives.](#alternatives)

`createFactory` lets you create a function that produces React elements of a given type.

```
const factory = createFactory(type)
```

* [Reference](#reference)
  * [`createFactory(type)`](#createfactory)

* [Usage](#usage)
  * [Creating React elements with a factory](#creating-react-elements-with-a-factory)

* [Alternatives](#alternatives)

  * [Copying `createFactory` into your project](#copying-createfactory-into-your-project)
  * [Replacing `createFactory` with `createElement`](#replacing-createfactory-with-createelement)
  * [Replacing `createFactory` with JSX](#replacing-createfactory-with-jsx)

***

## Reference[](#reference "Link for Reference ")

### `createFactory(type)`[](#createfactory "Link for this heading")

Call `createFactory(type)` to create a factory function which produces React elements of a given `type`.

```
import { createFactory } from 'react';



const button = createFactory('button');
```

Then you can use it to create React elements without JSX:

```
export default function App() {

  return button({

    onClick: () => {

      alert('Clicked!')

    }

  }, 'Click me');

}
```

[See more examples below.](#usage)

#### Parameters[](#parameters "Link for Parameters ")

* `type`: The `type` argument must be a valid React component type. For example, it could be a tag name string (such as `'div'` or `'span'`), or a React component (a function, a class, or a special component like [`Fragment`](/reference/react/Fragment)).

#### Returns[](#returns "Link for Returns ")

Returns a factory function. That factory function receives a `props` object as the first argument, followed by a list of `...children` arguments, and returns a React element with the given `type`, `props` and `children`.

***

## Usage[](#usage "Link for Usage ")

### Creating React elements with a factory[](#creating-react-elements-with-a-factory "Link for Creating React elements with a factory ")

Although most React projects use [JSX](/learn/writing-markup-with-jsx) to describe the user interface, JSX is not required. In the past, `createFactory` used to be one of the ways you could describe the user interface without JSX.

Call `createFactory` to create a *factory function* for a specific element type like `'button'`:

```
import { createFactory } from 'react';



const button = createFactory('button');
```

Calling that factory function will produce React elements with the props and children you have provided:

```
import { createFactory } from 'react';

const button = createFactory('button');

export default function App() {
  return button({
    onClick: () => {
      alert('Clicked!')
    }
  }, 'Click me');
}
```

This is how `createFactory` was used as an alternative to JSX. However, `createFactory` is deprecated, and you should not call `createFactory` in any new code. See how to migrate away from `createFactory` below.

***

## Alternatives[](#alternatives "Link for Alternatives ")

### Copying `createFactory` into your project[](#copying-createfactory-into-your-project "Link for this heading")

If your project has many `createFactory` calls, copy this `createFactory.js` implementation into your project:

```
import { createFactory } from './createFactory.js';

const button = createFactory('button');

export default function App() {
  return button({
    onClick: () => {
      alert('Clicked!')
    }
  }, 'Click me');
}
```

This lets you keep all of your code unchanged except the imports.

***

### Replacing `createFactory` with `createElement`[](#replacing-createfactory-with-createelement "Link for this heading")

If you have a few `createFactory` calls that you don’t mind porting manually, and you don’t want to use JSX, you can replace every call a factory function with a [`createElement`](/reference/react/createElement) call. For example, you can replace this code:

```
import { createFactory } from 'react';



const button = createFactory('button');



export default function App() {

  return button({

    onClick: () => {

      alert('Clicked!')

    }

  }, 'Click me');

}
```

with this code:

```
import { createElement } from 'react';



export default function App() {

  return createElement('button', {

    onClick: () => {

      alert('Clicked!')

    }

  }, 'Click me');

}
```

Here is a complete example of using React without JSX:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?parameters=N4IgZglgNgpgziAXKOAnAxgeggOwCYwAeAdAFYLIjoD2OALjPUiBALYAO1qdABAEowAhujoAaHsB4BlOqggiAstQI8AvjzCpqrHgB0QqISP0BuXTjaduEnukOCGfatV7rN2vQaN0AtHm2Y6FAQjHSm5pZcvPrEmHB0AJ6wcMTocHDhOBEcUTwAguzsGlo6MZgF7JnmNDjxPFouPAC8tvaOznQAFP7oAK6socQA5jB0AKKwA_QAQgkAknid-g1hIACUa2Y4K8SG-DCoSzg8PAA8MnKKyjAAfOYnJ6cVPJh3x2eYF_J0SgRvmyBRCw4NNcIJUAkkGBBFA4DBVED2MIANaCEZkOC0JCgGoMJiIEDAe6eHCCAb6RCeewiYgEABu-lExP0dIOcAgtApngADMRedzGcyQKxBLgufo4hhsPsSORBe99HA7BB2HQMkgJMSToq6ODVpTlt4fEq5Kq4Dx4nr5Q9PAAjXrQPDirzCXwmlVqnj2x3Wh76BjxZ3Ut3Ks08AO8Hw-Rh0prkfysX3akAwUgwYwaw2u42hz2p9OrYkIoUEdiMAg4dAhdWUonvZPB50APQAjAAOPl8pNUo0J5vtzsCwFanvZ91m5sAVkH-iLTIVIHpABEYGX9pXq1zgKpzKpAcDQaSIVCYXCESB2L1bcEsLgCCQABZ0VhQbFUWh4ujMU4AQiXAHkAGEABUAE0AAUxh4J8XzeU4YKgHgoEEHAhiafRGH0OCHyEPA3keAZdVsB9wThOh0JAABVYCADEfDbLDiVOQjBB4UkBgoukQgAdysVZbA_UIKO4iA8DoB8mnpeQYB8ESxIfcRcAgOgIBhHMYRgJoWy7EB8LOFS6FgG4l2oPopjoU5MAMozzEsnDBDw2zbWUBI9NOPAIDpHhRIolYsMsjy6TgzBnLwVzbMwBCbn3CAQTBY9EGhWF4SBNAsAqDE31xUJmEiaxJDsIQGAmGBzLUYoPAAcmDSqtnMIg-J4AhoV6KBeDAXpKxU2h8kKTo1k1d5DDoXpUGOQqHBgErzM6Sr7ToOhaEq8Q6xtWhAJvZFKX65obkGm0Tg07hZo2-RkRgPAf0qtYRx3d4ER4SrTvQZEeAGa6tjumK4qPSFEtPFKQDSuJEmSVJ0iywT8RAAAqfavWoQhjQgAAvXAhkpZzUAIVAfGcwhPvMcxQoSeGwA_HxoVYaAEkpOAULgY0DggMAthOEVUCGXBKQAJm5dgCeJJE8A81DKW5QmshwB8W3hjmuZwHxFvYcW2Y0Cn2RRmBeZ5gXJfMB8ebl8EFaV6gVZ4CXiXJ-hka13n-cFnA7oNgBmY3OdwM2Lat94bbdVHtZ4ds9d3InpYAFg903ldV62NcDykWwANlD53w4fSdo692PLbV_27aDlsI7Tl3peT7PFdz32TgLzWi91p2y5oFRVvV2366T4gedK_WcFa-HhdFoYfFwYIcBky1uAd0vw--w9wT-pKz3PBgOGQhhmAmhgfGDHxBEKEBVCAA\&query=file%3D%252Fsrc%252FApp.js%26utm_medium%3Dsandpack\&environment=create-react-app "Open in CodeSandbox")

```
import { createElement } from 'react';

export default function App() {
  return createElement('button', {
    onClick: () => {
      alert('Clicked!')
    }
  }, 'Click me');
}
```

***

### Replacing `createFactory` with JSX[](#replacing-createfactory-with-jsx "Link for this heading")

Finally, you can use JSX instead of `createFactory`. This is the most common way to use React:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?parameters=N4IgZglgNgpgziAXKOAnAxgeggOwCYwAeAdAFYLIjoD2OALjPUiBALYAO1qdABAEowAhujoAaHsB4BlOqggiAstQI8AvjzCpqrHgB0QqISP0BuXTjaduEnukOCGfatV7rN2vQaN0AtHm2Y6FAQjHSm5pZcvPrEmHB0AJ6wcMTocHDhOBEcUTwAguzsGlo6MZgF7JnmNDjxPFouPAC8tvaOznQAFP7oAK6socQA5jB0AKKwA_QAQgkAknid-g1hIACUa2Y4K8SG-DCoSzg8PAA8MnKKyjAAfOYnJ6cVPJh3x2eYF_J0SgRvmyBRCw4NNcIJUAkkGBBFA4DBVED2MIANaCEZkOC0JCgGoMJiIEDAe6eHCCAb6RCeewiYgEABu-lExP0dIOcAgtApngADMRedzGcyQKxBLgufo4hhsPsSORBe99HA7BB2HQMkgJMSToq6ODVpTlt4fEq5Kq4Dx4nr5Q9PAAjXrQPDirzCXwmlVqnj2x3Wh76BjxZ3Ut3Ks08AO8Hw-Rh0prkfysX3akAwUgwYwaw2u42hz2p9OrYkIoUEdiMAg4dAhdWUonvZPB50APQAjAAOPl8pNUo0J5vtzsCwFanvZ91m5sAVkH-iLTIVIHpABEYGX9pXq1zgKpzKpAcDQaSIVCYXCESB2L1bcEsLgCCQABZ0VhQbFUWh4ujMU4AQiXAHkAGEABUAE0AAUxh4J8XzeU4YKgHgoEEHAhiafRGH0OCHyEPA3keAZdVsB9wThOh0JAABVYCADEfDbLDiVOQjBB4UkBgoukQgAdysVZbA_UIKO4iA8DoB8mnpeQYB8ESxIfcRcAgOgIBhHMYRgJoWy7EB8LOFS6FgG4l2oPopjoU5MAMozzEsnDBDw2zbWUBI9NOPAIDpHhRIolYsMsjy6TgzBnLwVzbMwBCbn3CAQTBY9EGhWF4SBNAsAqDE31xUJmCIPieAIaFeigXgwF6SsVNofJCk6NZNXeQw6F6VBjiOG1TntOg6Cq2hAJvZEmmAWrmhueqbRODTuE6AByPr5GRGA8B_abNhHVRVD0m05vQZEeHJesPk67qcD01acFULYYrio9IUS08UpANK4kSZJUnSLLBPxEAACoxq9ahCGNCAAC9cCGSlnNQAhUB8ZzCC2HcshwUKEj-sAPx8aFWGgBJKTgFC4GNA4IDALYThFVAhlwSkACZuXYeHiSRPAPNQyluQR8xzAfFs_opqmcB8br2HZsmNAx9lgZgWmaYZzmkYfGm-fBAWheoEWeA54l0foIGpdp-nGfOrmcAfABmZXKdwNWNa194dbdEHpZ4ds5d3E2HwAFkt1XhdF7WJadykWwANjd42FcnH3rb9zWxYdvXnZbT3w8R7mQ-jwXY7tk4E8lpPZaNtPK2uNHA_1l3iBpmBWHl8xir-5nWaGHxcGCHAZMtbgDdTk2rsPcFbqSs9zwYDhkIYZg7CEBgfGDHxBEKEBVCAA\&query=file%3D%252Fsrc%252FApp.js%26utm_medium%3Dsandpack\&environment=create-react-app "Open in CodeSandbox")

```
export default function App() {
  return (
    <button onClick={() => {
      alert('Clicked!');
    }}>
      Click me
    </button>
  );
};
```

### Pitfall

Sometimes, your existing code might pass some variable as a `type` instead of a constant like `'button'`:

```
function Heading({ isSubheading, ...props }) {

  const type = isSubheading ? 'h2' : 'h1';

  const factory = createFactory(type);

  return factory(props);

}
```

To do the same in JSX, you need to rename your variable to start with an uppercase letter like `Type`:

```
function Heading({ isSubheading, ...props }) {

  const Type = isSubheading ? 'h2' : 'h1';

  return <Type {...props} />;

}
```

Otherwise React will interpret `<type>` as a built-in HTML tag because it is lowercase.

[PreviouscreateElement](/reference/react/createElement)

[NextcreateRef](/reference/react/createRef)

***

----
url: https://legacy.reactjs.org/blog/2020/02/26/react-v16.13.0.html
----

February 26, 2020 by [Sunil Pai](https://twitter.com/threepointone)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

Today we are releasing React 16.13.0. It contains bugfixes and new deprecation warnings to help prepare for a future major release.

## [](#new-warnings)New Warnings

### [](#warnings-for-some-updates-during-render)Warnings for some updates during render

A React component should not cause side effects in other components during rendering.

It is supported to call `setState` during render, but [only for *the same component*](/docs/hooks-faq.html#how-do-i-implement-getderivedstatefromprops). If you call `setState` during a render on a different component, you will now see a warning:

```
Warning: Cannot update a component from inside the function body of a different component.
```

**This warning will help you find application bugs caused by unintentional state changes.** In the rare case that you intentionally want to change the state of another component as a result of rendering, you can wrap the `setState` call into `useEffect`.

### [](#warnings-for-conflicting-style-rules)Warnings for conflicting style rules

When dynamically applying a `style` that contains longhand and shorthand versions of CSS properties, particular combinations of updates can cause inconsistent styling. For example:

```
<div style={toggle ? 
  { background: 'blue', backgroundColor: 'red' } : 
  { backgroundColor: 'red' }
}>
  ...
</div> 
```

You might expect this `<div>` to always have a red background, no matter the value of `toggle`. However, on alternating the value of `toggle` between `true` and `false`, the background color start as `red`, then alternates between `transparent` and `blue`, [as you can see in this demo](https://codesandbox.io/s/serene-dijkstra-dr0vev).

**React now detects conflicting style rules and logs a warning.** To fix the issue, don’t mix shorthand and longhand versions of the same CSS property in the `style` prop.

### [](#warnings-for-some-deprecated-string-refs)Warnings for some deprecated string refs

[String Refs is an old legacy API](/docs/refs-and-the-dom.html#legacy-api-string-refs) which is discouraged and is going to be deprecated in the future:

```
<Button ref="myRef" />
```

(Don’t confuse String Refs with refs in general, which **remain fully supported**.)

In the future, we will provide an automated script (a “codemod”) to migrate away from String Refs. However, some rare cases can’t be migrated automatically. This release adds a new warning **only for those cases** in advance of the deprecation.

For example, it will fire if you use String Refs together with the Render Prop pattern:

```
class ClassWithRenderProp extends React.Component {
  componentDidMount() {
    doSomething(this.refs.myRef);
  }
  render() {
    return this.props.children();
  }
}

class ClassParent extends React.Component {
  render() {
    return (
      <ClassWithRenderProp>
        {() => <Button ref="myRef" />}
      </ClassWithRenderProp>
    );
  }
}
```

Code like this often indicates bugs. (You might expect the ref to be available on `ClassParent`, but instead it gets placed on `ClassWithRenderProp`).

**You most likely don’t have code like this**. If you do and it is intentional, convert it to [`React.createRef()`](/docs/refs-and-the-dom.html#creating-refs) instead:

```
class ClassWithRenderProp extends React.Component {
  myRef = React.createRef();
  componentDidMount() {
    doSomething(this.myRef.current);
  }
  render() {
    return this.props.children(this.myRef);
  }
}

class ClassParent extends React.Component {
  render() {
    return (
      <ClassWithRenderProp>
        {myRef => <Button ref={myRef} />}
      </ClassWithRenderProp>
    );
  }
}
```

> Note
>
> To see this warning, you need to have the [babel-plugin-transform-react-jsx-self](https://babeljs.io/docs/en/babel-plugin-transform-react-jsx-self) installed in your Babel plugins. It must *only* be enabled in development mode.
>
> If you use Create React App or have the “react” preset with Babel 7+, you already have this plugin installed by default.

### [](#deprecating-reactcreatefactory)Deprecating `React.createFactory`

[`React.createFactory`](/docs/react-api.html#createfactory) is a legacy helper for creating React elements. This release adds a deprecation warning to the method. It will be removed in a future major version.

Replace usages of `React.createFactory` with regular JSX. Alternately, you can copy and paste this one-line helper or publish it as a library:

```
let createFactory = type => React.createElement.bind(null, type);
```

It does exactly the same thing.

### [](#deprecating-reactdomunstable_createportal-in-favor-of-reactdomcreateportal)Deprecating `ReactDOM.unstable_createPortal` in favor of `ReactDOM.createPortal`

When React 16 was released, `createPortal` became an officially supported API.

However, we kept `unstable_createPortal` as a supported alias to keep the few libraries that adopted it working. We are now deprecating the unstable alias. Use `createPortal` directly instead of `unstable_createPortal`. It has exactly the same signature.

## [](#other-improvements)Other Improvements

### [](#component-stacks-in-hydration-warnings)Component stacks in hydration warnings

React adds component stacks to its development warnings, enabling developers to isolate bugs and debug their programs. This release adds component stacks to a number of development warnings that didn’t previously have them. As an example, consider this hydration warning from the previous versions:

[](/static/20bd06e254e7ad32aa007a59a41d1e65/61583/hydration-warning-before.png)

While it’s pointing out an error with the code, it’s not clear where the error exists, and what to do next. This release adds a component stack to this warning, which makes it look like this:

[](/static/abf3b580867e79d5f377330842bb6522/d3d45/hydration-warning-after.png)

This makes it clear where the problem is, and lets you locate and fix the bug faster.

### [](#notable-bugfixes)Notable bugfixes

This release contains a few other notable improvements:

* In Strict Development Mode, React calls lifecycle methods twice to flush out any possible unwanted side effects. This release adds that behaviour to `shouldComponentUpdate`. This shouldn’t affect most code, unless you have side effects in `shouldComponentUpdate`. To fix this, move the code with side effects into `componentDidUpdate`.
* In Strict Development Mode, the warnings for usage of the legacy context API didn’t include the stack for the component that triggered the warning. This release adds the missing stack to the warning.
* `onMouseEnter` now doesn’t trigger on disabled `<button>` elements.
* ReactDOM was missing a `version` export since we published v16. This release adds it back. We don’t recommend using it in your application logic, but it’s useful when debugging issues with mismatching / multiple versions of ReactDOM on the same page.

We’re thankful to all the contributors who helped surface and fix these and other issues. You can find the full changelog [below](#changelog).

## [](#installation)Installation

### [](#react)React

React v16.13.0 is available on the npm registry.

To install React 16 with Yarn, run:

```
yarn add react@^16.13.0 react-dom@^16.13.0
```

To install React 16 with npm, run:

```
npm install --save react@^16.13.0 react-dom@^16.13.0
```

We also provide UMD builds of React via a CDN:

```
<script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
```

Refer to the documentation for [detailed installation instructions](/docs/installation.html).

## [](#changelog)Changelog

### [](#react)React

* Warn when a string ref is used in a manner that’s not amenable to a future codemod ([@lunaruan](https://github.com/lunaruan) in [#17864](https://github.com/facebook/react/pull/17864))
* Deprecate `React.createFactory()` ([@trueadm](https://github.com/trueadm) in [#17878](https://github.com/facebook/react/pull/17878))

### [](#react-dom)React DOM

* Warn when changes in `style` may cause an unexpected collision ([@sophiebits](https://github.com/sophiebits) in [#14181](https://github.com/facebook/react/pull/14181), [#18002](https://github.com/facebook/react/pull/18002))
* Warn when a function component is updated during another component’s render phase ([@acdlite](\(https://github.com/acdlite\)) in [#17099](https://github.com/facebook/react/pull/17099))
* Deprecate `unstable_createPortal` ([@trueadm](https://github.com/trueadm) in [#17880](https://github.com/facebook/react/pull/17880))
* Fix `onMouseEnter` being fired on disabled buttons ([@AlfredoGJ](https://github.com/AlfredoGJ) in [#17675](https://github.com/facebook/react/pull/17675))
* Call `shouldComponentUpdate` twice when developing in `StrictMode` ([@bvaughn](https://github.com/bvaughn) in [#17942](https://github.com/facebook/react/pull/17942))
* Add `version` property to ReactDOM ([@ealush](https://github.com/ealush) in [#15780](https://github.com/facebook/react/pull/15780))
* Don’t call `toString()` of `dangerouslySetInnerHTML` ([@sebmarkbage](https://github.com/sebmarkbage) in [#17773](https://github.com/facebook/react/pull/17773))
* Show component stacks in more warnings ([@gaearon](https://github.com/gaearon) in [#17922](https://github.com/facebook/react/pull/17922), [#17586](https://github.com/facebook/react/pull/17586))

### [](#concurrent-mode-experimental)Concurrent Mode (Experimental)

* Warn for problematic usages of `ReactDOM.createRoot()` ([@trueadm](https://github.com/trueadm) in [#17937](https://github.com/facebook/react/pull/17937))
* Remove `ReactDOM.createRoot()` callback params and added warnings on usage ([@bvaughn](https://github.com/bvaughn) in [#17916](https://github.com/facebook/react/pull/17916))
* Don’t group Idle/Offscreen work with other work ([@sebmarkbage](https://github.com/sebmarkbage) in [#17456](https://github.com/facebook/react/pull/17456))
* Adjust `SuspenseList` CPU bound heuristic ([@sebmarkbage](https://github.com/sebmarkbage) in [#17455](https://github.com/facebook/react/pull/17455))
* Add missing event plugin priorities ([@trueadm](https://github.com/trueadm) in [#17914](https://github.com/facebook/react/pull/17914))
* Fix `isPending` only being true when transitioning from inside an input event ([@acdlite](https://github.com/acdlite) in [#17382](https://github.com/facebook/react/pull/17382))
* Fix `React.memo` components dropping updates when interrupted by a higher priority update ([@acdlite](https://github.com/acdlite) in [#18091](https://github.com/facebook/react/pull/18091))
* Don’t warn when suspending at the wrong priority ([@gaearon](https://github.com/gaearon) in [#17971](https://github.com/facebook/react/pull/17971))
* Fix a bug with rebasing updates ([@acdlite](https://github.com/acdlite) and [@sebmarkbage](https://github.com/sebmarkbage) in [#17560](https://github.com/facebook/react/pull/17560), [#17510](https://github.com/facebook/react/pull/17510), [#17483](https://github.com/facebook/react/pull/17483), [#17480](https://github.com/facebook/react/pull/17480))

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2020-02-26-react-v16.13.0.md)

----
url: https://legacy.reactjs.org/blog/2015/05/08/react-v0.13.3.html
----

May 08, 2015 by [Paul O’Shannessy](https://twitter.com/zpao)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

Today we’re sharing another patch release in the v0.13 branch. There are only a few small changes, with a couple to address some issues that arose around that undocumented feature so many of you are already using: `context`. We also improved developer ergonomics just a little bit, making some warnings better.

The release is now available for download:

* **React**\
  Dev build with warnings: <https://fb.me/react-0.13.3.js>\
  Minified build for production: <https://fb.me/react-0.13.3.min.js>
* **React with Add-Ons**\
  Dev build with warnings: <https://fb.me/react-with-addons-0.13.3.js>\
  Minified build for production: <https://fb.me/react-with-addons-0.13.3.min.js>
* **In-Browser JSX transformer**\
  <https://fb.me/JSXTransformer-0.13.3.js>

We’ve also published version `0.13.3` of the `react` and `react-tools` packages on npm and the `react` package on bower.

***

## [](#changelog)Changelog

### [](#react-core)React Core

#### [](#new-features)New Features

* Added `clipPath` element and attribute for SVG
* Improved warnings for deprecated methods in plain JS classes

#### [](#bug-fixes)Bug Fixes

* Loosened `dangerouslySetInnerHTML` restrictions so `{__html: undefined}` will no longer throw
* Fixed extraneous context warning with non-pure `getChildContext`
* Ensure `replaceState(obj)` retains prototype of `obj`

### [](#react-with-add-ons)React with Add-ons

### [](#bug-fixes-1)Bug Fixes

* Test Utils: Ensure that shallow rendering works when components define `contextTypes`

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2015-05-08-react-v0.13.3.md)

----
url: https://react.dev/reference/react/experimental_taintObjectReference
----

[API Reference](/reference/react)

[APIs](/reference/react/apis)

# experimental\_taintObjectReference[](#undefined "Link for this heading")

### Experimental Feature

```
experimental_taintObjectReference(message, object);
```

To prevent passing a key, hash or token, see [`taintUniqueValue`](/reference/react/experimental_taintUniqueValue).

* [Reference](#reference)
  * [`taintObjectReference(message, object)`](#taintobjectreference)
* [Usage](#usage)
  * [Prevent user data from unintentionally reaching the client](#prevent-user-data-from-unintentionally-reaching-the-client)

***

## Reference[](#reference "Link for Reference ")

### `taintObjectReference(message, object)`[](#taintobjectreference "Link for this heading")

Call `taintObjectReference` with an object to register it with React as something that should not be allowed to be passed to the Client as is:

```
import {experimental_taintObjectReference} from 'react';



experimental_taintObjectReference(

  'Do not pass ALL environment variables to the client.',

  process.env

);
```

***

## Usage[](#usage "Link for Usage ")

### Prevent user data from unintentionally reaching the client[](#prevent-user-data-from-unintentionally-reaching-the-client "Link for Prevent user data from unintentionally reaching the client ")

A Client Component should never accept objects that carry sensitive data. Ideally, the data fetching functions should not expose data that the current user should not have access to. Sometimes mistakes happen during refactoring. To protect against these mistakes happening down the line we can “taint” the user object in our data API.

```
import {experimental_taintObjectReference} from 'react';



export async function getUser(id) {

  const user = await db`SELECT * FROM users WHERE id = ${id}`;

  experimental_taintObjectReference(

    'Do not pass the entire user object to the client. ' +

      'Instead, pick off the specific properties you need for this use case.',

    user,

  );

  return user;

}
```

Now whenever anyone tries to pass this object to a Client Component, an error will be thrown with the passed in error message instead.

##### Deep Dive#### Protecting against leaks in data fetching[](#protecting-against-leaks-in-data-fetching "Link for Protecting against leaks in data fetching ")

If you’re running a Server Components environment that has access to sensitive data, you have to be careful not to pass objects straight through:

```
// api.js

export async function getUser(id) {

  const user = await db`SELECT * FROM users WHERE id = ${id}`;

  return user;

}
```

```
import { getUser } from 'api.js';

import { InfoCard } from 'components.js';



export async function Profile(props) {

  const user = await getUser(props.userId);

  // DO NOT DO THIS

  return <InfoCard user={user} />;

}
```

```
// components.js

"use client";



export async function InfoCard({ user }) {

  return <div>{user.name}</div>;

}
```

Ideally, the `getUser` should not expose data that the current user should not have access to. To prevent passing the `user` object to a Client Component down the line we can “taint” the user object:

```
// api.js

import {experimental_taintObjectReference} from 'react';



export async function getUser(id) {

  const user = await db`SELECT * FROM users WHERE id = ${id}`;

  experimental_taintObjectReference(

    'Do not pass the entire user object to the client. ' +

      'Instead, pick off the specific properties you need for this use case.',

    user,

  );

  return user;

}
```

Now if anyone tries to pass the `user` object to a Client Component, an error will be thrown with the passed in error message.

[Previoususe](/reference/react/use)

[Nextexperimental\_taintUniqueValue](/reference/react/experimental_taintUniqueValue)

***

----
url: https://18.react.dev/reference/react-dom/hydrate
----

[API Reference](/reference/react)

[APIs](/reference/react-dom)

# hydrate[](#undefined "Link for this heading")

### Deprecated

This API will be removed in a future major version of React.

In React 18, `hydrate` was replaced by [`hydrateRoot`.](/reference/react-dom/client/hydrateRoot) Using `hydrate` in React 18 will warn that your app will behave as if it’s running React 17. Learn more [here.](/blog/2022/03/08/react-18-upgrade-guide#updates-to-client-rendering-apis)

`hydrate` lets you display React components inside a browser DOM node whose HTML content was previously generated by [`react-dom/server`](/reference/react-dom/server) in React 17 and below.

```
hydrate(reactNode, domNode, callback?)
```

* [Reference](#reference)
  * [`hydrate(reactNode, domNode, callback?)`](#hydrate)

* [Usage](#usage)

  * [Hydrating server-rendered HTML](#hydrating-server-rendered-html)
  * [Suppressing unavoidable hydration mismatch errors](#suppressing-unavoidable-hydration-mismatch-errors)
  * [Handling different client and server content](#handling-different-client-and-server-content)

***

## Reference[](#reference "Link for Reference ")

### `hydrate(reactNode, domNode, callback?)`[](#hydrate "Link for this heading")

Call `hydrate` in React 17 and below to “attach” React to existing HTML that was already rendered by React in a server environment.

```
import { hydrate } from 'react-dom';



hydrate(reactNode, domNode);
```

React will attach to the HTML that exists inside the `domNode`, and take over managing the DOM inside it. An app fully built with React will usually only have one `hydrate` call with its root component.

[See more examples below.](#usage)

#### Parameters[](#parameters "Link for Parameters ")

* `reactNode`: The “React node” used to render the existing HTML. This will usually be a piece of JSX like `<App />` which was rendered with a `ReactDOM Server` method such as `renderToString(<App />)` in React 17.

* `domNode`: A [DOM element](https://developer.mozilla.org/en-US/docs/Web/API/Element) that was rendered as the root element on the server.

* **optional**: `callback`: A function. If passed, React will call it after your component is hydrated.

#### Returns[](#returns "Link for Returns ")

`hydrate` returns null.

#### Caveats[](#caveats "Link for Caveats ")

* `hydrate` expects the rendered content to be identical with the server-rendered content. React can patch up differences in text content, but you should treat mismatches as bugs and fix them.
* In development mode, React warns about mismatches during hydration. There are no guarantees that attribute differences will be patched up in case of mismatches. This is important for performance reasons because in most apps, mismatches are rare, and so validating all markup would be prohibitively expensive.
* You’ll likely have only one `hydrate` call in your app. If you use a framework, it might do this call for you.
* If your app is client-rendered with no HTML rendered already, using `hydrate()` is not supported. Use [render()](/reference/react-dom/render) (for React 17 and below) or [createRoot()](/reference/react-dom/client/createRoot) (for React 18+) instead.

***

## Usage[](#usage "Link for Usage ")

Call `hydrate` to attach a React component into a server-rendered browser DOM node.

```
import { hydrate } from 'react-dom';



hydrate(<App />, document.getElementById('root'));
```

Using `hydrate()` to render a client-only app (an app without server-rendered HTML) is not supported. Use [`render()`](/reference/react-dom/render) (in React 17 and below) or [`createRoot()`](/reference/react-dom/client/createRoot) (in React 18+) instead.

### Hydrating server-rendered HTML[](#hydrating-server-rendered-html "Link for Hydrating server-rendered HTML ")

In React, “hydration” is how React “attaches” to existing HTML that was already rendered by React in a server environment. During hydration, React will attempt to attach event listeners to the existing markup and take over rendering the app on the client.

In apps fully built with React, **you will usually only hydrate one “root”, once at startup for your entire app**.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?parameters=N4IgZglgNgpgziAXKOAnAxgeggOwCYwAeAdAFYLIjoD2OALjPUiBALYAO1qdABAOTFMcOgE9YcYujhw-AbgA6ONp249gPABYi8qAIYMeAXx5hU1Vv1Qxd6OgFo85uYuVdeAQXbsTZiwMye7GQyCjiKWjr6MAAUADyBPJgAfAA0PI7oAK6sjHTEAOYwdACisDn0AEIiAJJ40Xxm1HR8AJQtoSApLHAVuLqoIkhgulBwMIZd7DYA1rqFwbRIoDT0uczAijw88iA4ujk7iNsgVjZ5BABuOymbxxcwqHAQtIfHAAzEH2_XtzusurhXjshBhsPgiMEfjgtjs4OhUBB2HQ4K8NtCtsdhP06ECTtZbHY4QikXAeFjuFCMccAEaZaB4XGnAlExHIni0-mUjE7BjCRn4-wskk8Xm8Ox2RgXAC85EcrC5MJAMFIMFs_LOhPhrNJytVOJAtwmvxABHYjAIOHQEHgqNuiqZ-qOOwAegBGAAcn0-CuODoc5lxbs9Xx9Oz9QuRgYArF7vgb0Ub0TtLgARGBm8GW60opBqQyKQydbq9PYDIYjMYTEDsTLUqAQLC4AgkDR0VhQJZUWgMJiIECxACE4tuAAkACoAWQAMjwVj3eLgngQeLE8BALjwIHgpWHqE0dkliEfYpg1xckrcAO66UmFHAPKJ4HzmHgJakiHh-uVCB73VDERRxQvHBV3XTdt13fcQCSWINFdJIRxgKAoGoNJLy4KA8AHE84Jg0912AosIB6Poy0QYZRnGLo0CwQJgk7Oc1j7IgVF4AhhkyKBeDATJLToZ5oUCaIWjUW4rDoTJUGhWD4MQ5DUJ4dDUEw7DMFw0J8xwIiSNLQZyIrKiQBooRRHESRpAY7smJAAAqUT0WpahCEJCAAC9cHyI5HNQAhUDsRzCA0xRFEcvAPzRLYwG7OxhlYaARCOOBdBwOBCQeCAwFCLZ_lQfJcCOAAmN52EC24pjwNccE8ng3iCsIcDg-zsv6PKcDsOhqHYI5atuKL6Bc1yYEKgqSrq8ICqangcta9rOu6rKTGip5BsK4rSpwTTwgAZkm6bcFmrqaoWvrBTcoaeA9UaC2ChqABZdpa_aOsOnr0ROgbztdAA2K6NpujQowe3Knrmo7eqWs6jldW7fs2hqvqBmbnvm8H-uWz6RvWuGaGXCLFrRyGLuIAqYFYMacE4ybysq_I7Fwet70JOhsVW2Gbu0kt-j0ijKyrBgOCgKJmHhawGDsP1dC8EBDCAA\&query=file%3D%252Fsrc%252Findex.js%26utm_medium%3Dsandpack\&environment=create-react-app "Open in CodeSandbox")

```
import './styles.css';
import { hydrate } from 'react-dom';
import App from './App.js';

hydrate(<App />, document.getElementById('root'));
```

Usually you shouldn’t need to call `hydrate` again or to call it in more places. From this point on, React will be managing the DOM of your application. To update the UI, your components will [use state.](/reference/react/useState)

For more information on hydration, see the docs for [`hydrateRoot`.](/reference/react-dom/client/hydrateRoot)

***

### Suppressing unavoidable hydration mismatch errors[](#suppressing-unavoidable-hydration-mismatch-errors "Link for Suppressing unavoidable hydration mismatch errors ")

If a single element’s attribute or text content is unavoidably different between the server and the client (for example, a timestamp), you may silence the hydration mismatch warning.

To silence hydration warnings on an element, add `suppressHydrationWarning={true}`:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?parameters=N4IgZglgNgpgziAXKOAnAxgeggOwCYwAeAdAFYLIjoD2OALjPUiBALYAO1qdABAOTFMcOgE9YcYujhw-AbgA6ONp249gPABYi8qAIYMeAXx5hU1Vv1Qxd6OgFo85uYuVdeAQXbsTZiwMye7GQyCjiKWjr6MAAUADyBPJgAfAA0PI7oAK6sjHTEAOYwdACisDn0AEIiAJJ40Xxm1HR8AJQtoSApLHAVuLqoIkhgulBwMIZd7DYA1rqFwbRIoDT0uczAijw88iA4ujk7iNsgVjZ5BABuOymbxxcwqHAQtIfHAAzEH2_XtzusurhXjshBhsPgiMEfjgtjs4OhUBB2HQ4K8NtCtsdhP06ECTtZbHY4QikXAeFjuFCMccAEaZaB4XGnAlExHIni0-mUjE7BjCRn4-wskk8Xm8Ox2RgXAC85EcrC5MJAMFIMFs_LOhPhrNJytVOJAtwmvxABHYjAIOHQEHgqNuiqZ-qOOwAegBGAAcn0-CuODoc5lxbs9Xx9Oz9QuRgYArF7vgb0Ub0TtLgARGBm8GW60opBqQyKQydbq9PYDIYjMYTEDsTLUqAQLC4AgkDR0VhQJZUWgMJiIECxACE4tuAAkACoAWQAMjwVj3eLgngQeLE8BALjwIHgpWHqE0dkliEfYpg1xckrcAO66UmFHAPKJ4HzmHgJakiHh-uVCB73VDERRxQvHBV3XTdt13fcQCSWINFdJIAGFMlQKx6B4FMoiON5XUwbDMAAJjeQiTzgmDT3XYCiwgHo-jLRBhlGcYujQLBAmCTs5zWPsiBUXgCGGTIoF4MBMktOhnmhQJohaNRbisOhkOhaI7RXOCyUyLwrGkEdtD0cTaAAdX6JQcHyKVgDoVBMnGYCqS2JCUNydDMLUe9L2chhpOIOhqCnah0BGGAMIYABlSzcHyaT83RLYSPg252gLRQqJo0tBnoismJAFihFEcRJGkDjuy4kAACpZPRalqEIQkIAALwio4qtQAhUDsKrCFCaLFCqvAPzRLYwG7OxhlYaARCOOBdBwOBCQeCAwFCLZ_lQfJcCOQj2E624pjwNdTKwrrFHCV0KuW_o1pwOwfPYQ7biG-harqmANvwrajrCHANHws6eBWy7ruoW6eDeJaTGGp5no2t53qSz6NAAZl-_7cEB4HQfuiH6pengPVhnBuq-gAWZGLtRm67vRB7BWxo5XQANnxwmNCjUnVvJoHKcGrGodxommeOr76bZgGKZBsHqaenHXTe7aCcFmhlwG8HHsh6XiHwmBWA-xRBN-3b9vyOxcHre9CTobFoYFz6UpLfp0oYysqwYDgoCiZh4WsBg7D9XQvBAQwgA\&query=file%3D%252Fsrc%252FApp.js%26utm_medium%3Dsandpack\&environment=create-react-app "Open in CodeSandbox")

```
export default function App() {
  return (
    <h1 suppressHydrationWarning={true}>
      Current Date: {new Date().toLocaleDateString()}
    </h1>
  );
}
```

This only works one level deep, and is intended to be an escape hatch. Don’t overuse it. Unless it’s text content, React still won’t attempt to patch it up, so it may remain inconsistent until future updates.

***

### Handling different client and server content[](#handling-different-client-and-server-content "Link for Handling different client and server content ")

If you intentionally need to render something different on the server and the client, you can do a two-pass rendering. Components that render something different on the client can read a [state variable](/reference/react/useState) like `isClient`, which you can set to `true` in an [Effect](/reference/react/useEffect):

[Fork](https://codesandbox.io/api/v1/sandboxes/define?parameters=N4IgZglgNgpgziAXKOAnAxgeggOwCYwAeAdAFYLIjoD2OALjPUiBALYAO1qdABAOTFMcOgE9YcYujhw-AbgA6ONp249gPABYi8qAIYMeAXx5hU1Vv1Qxd6OgFo85uYuVdeAQXbsTZiwMye7GQyCjiKWjr6MAAUADyBPJgAfAA0PI7oAK6sjHTEAOYwdACisDn0AEIiAJJ40Xxm1HR8AJQtoSApLHAVuLqoIkhgulBwMIZd7DYA1rqFwbRIoDT0uczAijw88iA4ujk7iNsgVjZ5BABuOymbxxcwqHAQtIfHAAzEH2_XtzusurhXjshBhsPgiMEfjgtjs4OhUBB2HQ4K8NtCtsdhP06ECTtZbHY4QikXAeFjuFCMccAEaZaB4XGnAlExHIni0-mUjE7BjCRn4-wskk8Xm8Ox2RgXAC85EcrC5MJAMFIMFs_LOhPhrNJytVOJAtwmvxABHYjAIOHQEHgqNuiqZ-qOOwAegBGAAcn0-CuODoc5lxbs9Xx9Oz9QuRgYArF7vgb0Ub0TtLgARGBm8GW60opBqQyKQydbq9PYDIYjMYTEDsTLUqAQLC4AgkDR0VhQJZUWgMJiIECxACE4tuAAkACoAWQAMjwVj3eLgngQeLE8BALjwIHgpWHqE0dkliEfYpg1xckrcAO66UmFHAPKJ4HzmHgJakiHh-uVCB73VDERRxQvHBV3XTdt13fcQCSWINFdJJqlJABlX8HhPOCYNPddgKLCAej6MtEGGUZxi6NAsECYJOznNY-1cVR1EyMYkLoKI0iYmBijAMA9SMZ8LDDAUdlCRQiBUXgCGGTIoF4MBMktOhnmhQJohaNRbhWYQeAAbTwgBhetcjSMY6EQgzrXoABdHgpR4DiWKiaJiLGdpFFuDiuJ42xolUmyknU9EthMszDPoaI6FQTIYFchM0m0yyYtuKw6EyVBoWiO0VwwzKtmAfTQt4AB-fhEJ4czcj4Hgjj4UqUNQP8-HzQKV0wbL0RiprcPw0tBiIitSJAcihFEcRJGkaju1okAACoAq2alqEIQkIAAL1wfIjgW1ACFQOwFsIUImsUBa8A_NEtjAbs7GGVhoBEI44F0HA4EJB4IDAUItn-VB8lwI4ACY3nYA7bimPA1xwDaeDeQ63JwOC5p4b7fpwOw6Godgjhh25LvoZaVpgAH_uB2Gwnh_7EeR3A0YxrHPpMK6ngJgGgZBnAjvhgBmSn-hRmnMeh-nccFVbCZ4D0SYLOGNAAFh5n7qfRgXsfRYX8bF10ADZJfZ6Wo3lvmlbpnHGdFo5XRlnWOY0TWDcV2nBZNvGmY14m2Y5mhl3OhnnbN8XiH-mBWFJxRpMRsGIfyOxcHre9CVY7gWatuGupLfpeuc8YqwYDgoCiZh4WsBg7D9XQvBAQwgA\&query=file%3D%252Fsrc%252FApp.js%26utm_medium%3Dsandpack\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useEffect } from "react";

export default function App() {
  const [isClient, setIsClient] = useState(false);

  useEffect(() => {
    setIsClient(true);
  }, []);

  return (
    <h1>
      {isClient ? 'Is Client' : 'Is Server'}
    </h1>
  );
}
```

This way the initial render pass will render the same content as the server, avoiding mismatches, but an additional pass will happen synchronously right after hydration.

### Pitfall

This approach makes hydration slower because your components have to render twice. Be mindful of the user experience on slow connections. The JavaScript code may load significantly later than the initial HTML render, so rendering a different UI immediately after hydration may feel jarring to the user.

[PreviousfindDOMNode](/reference/react-dom/findDOMNode)

[Nextpreconnect](/reference/react-dom/preconnect)

***

----
url: https://legacy.reactjs.org/docs/cdn-links.html
----

> These docs are old and won’t be updated. Go to [react.dev](https://react.dev/) for the new React docs.
>
> See [Add React to an Existing Project](https://react.dev/learn/add-react-to-an-existing-project) for the recommended ways to add React.

Both React and ReactDOM are available over a CDN.

```
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
```

The versions above are only meant for development, and are not suitable for production. Minified and optimized production versions of React are available at:

```
<script crossorigin src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
```

To load a specific version of `react` and `react-dom`, replace `18` with the version number.

### [](#why-the-crossorigin-attribute)Why the `crossorigin` Attribute?

If you serve React from a CDN, we recommend to keep the [`crossorigin`](https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes) attribute set:

```
<script crossorigin src="..."></script>
```

We also recommend to verify that the CDN you are using sets the `Access-Control-Allow-Origin: *` HTTP header:

[](/static/89baed0a6540f29e954065ce04661048/13ae7/cdn-cors-header.png)

This enables a better [error handling experience](/blog/2017/07/26/error-handling-in-react-16.html) in React 16 and later.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/cdn-links.md)

* Previous article

  [Create a New React App](/docs/create-a-new-react-app.html)

* Next article

  [Release Channels](/docs/release-channels.html)

----
url: https://legacy.reactjs.org/blog/2013/06/05/why-react.html
----

June 05, 2013 by [Pete Hunt](https://twitter.com/floydophone)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

There are a lot of JavaScript MVC frameworks out there. Why did we build React and why would you want to use it?

## [](#react-isnt-an-mvc-framework)React isn’t an MVC framework.

React is a library for building composable user interfaces. It encourages the creation of reusable UI components which present data that changes over time.

## [](#react-doesnt-use-templates)React doesn’t use templates.

Traditionally, web application UIs are built using templates or HTML directives. These templates dictate the full set of abstractions that you are allowed to use to build your UI.

React approaches building user interfaces differently by breaking them into **components**. This means React uses a real, full featured programming language to render views, which we see as an advantage over templates for a few reasons:

* **JavaScript is a flexible, powerful programming language** with the ability to build abstractions. This is incredibly important in large applications.
* By unifying your markup with its corresponding view logic, React can actually make views **easier to extend and maintain**.
* By baking an understanding of markup and content into JavaScript, there’s **no manual string concatenation** and therefore less surface area for XSS vulnerabilities.

We’ve also created [JSX](/docs/jsx-in-depth.html), an optional syntax extension, in case you prefer the readability of HTML to raw JavaScript.

## [](#reactive-updates-are-dead-simple)Reactive updates are dead simple.

React really shines when your data changes over time.

In a traditional JavaScript application, you need to look at what data changed and imperatively make changes to the DOM to keep it up-to-date. Even AngularJS, which provides a declarative interface via directives and data binding [requires a linking function to manually update DOM nodes](https://code.angularjs.org/1.0.8/docs/guide/directive#reasonsbehindthecompilelinkseparation).

React takes a different approach.

When your component is first initialized, the `render` method is called, generating a lightweight representation of your view. From that representation, a string of markup is produced, and injected into the document. When your data changes, the `render` method is called again. In order to perform updates as efficiently as possible, we diff the return value from the previous call to `render` with the new one, and generate a minimal set of changes to be applied to the DOM.

> The data returned from `render` is neither a string nor a DOM node — it’s a lightweight description of what the DOM should look like.

We call this process **reconciliation**. Check out [this jsFiddle](http://jsfiddle.net/2h6th4ju/) to see an example of reconciliation in action.

Because this re-render is so fast (around 1ms for TodoMVC), the developer doesn’t need to explicitly specify data bindings. We’ve found this approach makes it easier to build apps.

## [](#html-is-just-the-beginning)HTML is just the beginning.

Because React has its own lightweight representation of the document, we can do some pretty cool things with it:

* Facebook has dynamic charts that render to `<canvas>` instead of HTML.
* Instagram is a “single page” web app built entirely with React and `Backbone.Router`. Designers regularly contribute React code with JSX.
* We’ve built internal prototypes that run React apps in a web worker and use React to drive **native iOS views** via an Objective-C bridge.
* You can run React [on the server](https://github.com/petehunt/react-server-rendering-example) for SEO, performance, code sharing and overall flexibility.
* Events behave in a consistent, standards-compliant way in all browsers (including IE8) and automatically use [event delegation](http://davidwalsh.name/event-delegate).

Head on over to <https://reactjs.org> to check out what we have built. Our documentation is geared towards building apps with the framework, but if you are interested in the nuts and bolts [get in touch](/support.html) with us!

Thanks for reading!

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2013-06-05-why-react.md)

----
url: https://legacy.reactjs.org/blog/2013/06/21/react-v0-3-3.html
----

June 21, 2013 by [Paul O’Shannessy](https://twitter.com/zpao)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

We have a ton of great stuff coming in v0.4, but in the meantime we’re releasing v0.3.3. This release addresses some small issues people were having and simplifies our tools to make them easier to use.

## [](#react-tools)react-tools

* Upgrade Commoner so `require` statements are no longer relativized when passing through the transformer. This was a feature needed when building React, but doesn’t translate well for other consumers of `bin/jsx`.
* Upgraded our dependencies on Commoner and Recast so they use a different directory for their cache.
* Freeze our esprima dependency.

## [](#react)React

* Allow reusing the same DOM node to render different components. e.g. `React.renderComponent(<div/>, domNode); React.renderComponent(<span/>, domNode);` will work now.

## [](#jsxtransformer)JSXTransformer

* Improved the in-browser transformer so that transformed scripts will execute in the expected scope. The allows components to be defined and used from separate files.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2013-06-21-react-v0-3-3.md)

----
url: https://legacy.reactjs.org/docs/shallow-compare.html
----

> Note:
>
> `shallowCompare` is a legacy add-on. Use [`React.memo`](/docs/react-api.html#reactmemo) or [`React.PureComponent`](/docs/react-api.html#reactpurecomponent) instead.

**Importing**

```
import shallowCompare from 'react-addons-shallow-compare'; // ES6
var shallowCompare = require('react-addons-shallow-compare'); // ES5 with npm
```

## [](#overview)Overview

Before [`React.PureComponent`](/docs/react-api.html#reactpurecomponent) was introduced, `shallowCompare` was commonly used to achieve the same functionality as [`PureRenderMixin`](pure-render-mixin.html) while using ES6 classes with React.

If your React component’s render function is “pure” (in other words, it renders the same result given the same props and state), you can use this helper function for a performance boost in some cases.

Example:

```
export class SampleComponent extends React.Component {
  shouldComponentUpdate(nextProps, nextState) {
    return shallowCompare(this, nextProps, nextState);
  }

  render() {
    return <div className={this.props.className}>foo</div>;
  }
}
```

`shallowCompare` performs a shallow equality check on the current `props` and `nextProps` objects as well as the current `state` and `nextState` objects.\
It does this by iterating on the keys of the objects being compared and returning true when the values of a key in each object are not strictly equal.

`shallowCompare` returns `true` if the shallow comparison for props or state fails and therefore the component should update.\
`shallowCompare` returns `false` if the shallow comparison for props and state both pass and therefore the component does not need to update.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/addons-shallow-compare.md)

----
url: https://react.dev/reference/eslint-plugin-react-hooks/lints/purity
----

[API Reference](/reference/react)

[Lints](/reference/eslint-plugin-react-hooks)

# purity[](#undefined "Link for this heading")

Validates that [components/hooks are pure](/reference/rules/components-and-hooks-must-be-pure) by checking that they do not call known-impure functions.

## Rule Details[](#rule-details "Link for Rule Details ")

React components must be pure functions - given the same props, they should always return the same JSX. When components use functions like `Math.random()` or `Date.now()` during render, they produce different output each time, breaking React’s assumptions and causing bugs like hydration mismatches, incorrect memoization, and unpredictable behavior.

## Common Violations[](#common-violations "Link for Common Violations ")

In general, any API that returns a different value for the same inputs violates this rule. Usual examples include:

* `Math.random()`
* `Date.now()` / `new Date()`
* `crypto.randomUUID()`
* `performance.now()`

### Invalid[](#invalid "Link for Invalid ")

Examples of incorrect code for this rule:

```
// ❌ Math.random() in render

function Component() {

  const id = Math.random(); // Different every render

  return <div key={id}>Content</div>;

}



// ❌ Date.now() for values

function Component() {

  const timestamp = Date.now(); // Changes every render

  return <div>Created at: {timestamp}</div>;

}
```

### Valid[](#valid "Link for Valid ")

Examples of correct code for this rule:

```
// ✅ Stable IDs from initial state

function Component() {

  const [id] = useState(() => crypto.randomUUID());

  return <div key={id}>Content</div>;

}
```

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### I need to show the current time[](#current-time "Link for I need to show the current time ")

Calling `Date.now()` during render makes your component impure:

```
// ❌ Wrong: Time changes every render

function Clock() {

  return <div>Current time: {Date.now()}</div>;

}
```

Instead, [move the impure function outside of render](/reference/rules/components-and-hooks-must-be-pure#components-and-hooks-must-be-idempotent):

```
function Clock() {

  const [time, setTime] = useState(() => Date.now());



  useEffect(() => {

    const interval = setInterval(() => {

      setTime(Date.now());

    }, 1000);



    return () => clearInterval(interval);

  }, []);



  return <div>Current time: {time}</div>;

}
```

[Previouspreserve-manual-memoization](/reference/eslint-plugin-react-hooks/lints/preserve-manual-memoization)

[Nextrefs](/reference/eslint-plugin-react-hooks/lints/refs)

***

----
url: https://react.dev/learn/you-might-not-need-an-effect
----

You *do* need Effects to [synchronize](/learn/synchronizing-with-effects#what-are-effects-and-how-are-they-different-from-events) with external systems. For example, you can write an Effect that keeps a jQuery widget synchronized with the React state. You can also fetch data with Effects: for example, you can synchronize the search results with the current search query. Keep in mind that modern [frameworks](/learn/creating-a-react-app#full-stack-frameworks) provide more efficient built-in data fetching mechanisms than writing Effects directly in your components.

To help you gain the right intuition, let’s look at some common concrete examples!

### Updating state based on props or state[](#updating-state-based-on-props-or-state "Link for Updating state based on props or state ")

Suppose you have a component with two state variables: `firstName` and `lastName`. You want to calculate a `fullName` from them by concatenating them. Moreover, you’d like `fullName` to update whenever `firstName` or `lastName` change. Your first instinct might be to add a `fullName` state variable and update it in an Effect:

```
function Form() {

  const [firstName, setFirstName] = useState('Taylor');

  const [lastName, setLastName] = useState('Swift');



  // 🔴 Avoid: redundant state and unnecessary Effect

  const [fullName, setFullName] = useState('');

  useEffect(() => {

    setFullName(firstName + ' ' + lastName);

  }, [firstName, lastName]);

  // ...

}
```

This is more complicated than necessary. It is inefficient too: it does an entire render pass with a stale value for `fullName`, then immediately re-renders with the updated value. Remove the state variable and the Effect:

```
function Form() {

  const [firstName, setFirstName] = useState('Taylor');

  const [lastName, setLastName] = useState('Swift');

  // ✅ Good: calculated during rendering

  const fullName = firstName + ' ' + lastName;

  // ...

}
```

**When something can be calculated from the existing props or state, [don’t put it in state.](/learn/choosing-the-state-structure#avoid-redundant-state) Instead, calculate it during rendering.** This makes your code faster (you avoid the extra “cascading” updates), simpler (you remove some code), and less error-prone (you avoid bugs caused by different state variables getting out of sync with each other). If this approach feels new to you, [Thinking in React](/learn/thinking-in-react#step-3-find-the-minimal-but-complete-representation-of-ui-state) explains what should go into state.

### Caching expensive calculations[](#caching-expensive-calculations "Link for Caching expensive calculations ")

This component computes `visibleTodos` by taking the `todos` it receives by props and filtering them according to the `filter` prop. You might feel tempted to store the result in state and update it from an Effect:

```
function TodoList({ todos, filter }) {

  const [newTodo, setNewTodo] = useState('');



  // 🔴 Avoid: redundant state and unnecessary Effect

  const [visibleTodos, setVisibleTodos] = useState([]);

  useEffect(() => {

    setVisibleTodos(getFilteredTodos(todos, filter));

  }, [todos, filter]);



  // ...

}
```

Like in the earlier example, this is both unnecessary and inefficient. First, remove the state and the Effect:

```
function TodoList({ todos, filter }) {

  const [newTodo, setNewTodo] = useState('');

  // ✅ This is fine if getFilteredTodos() is not slow.

  const visibleTodos = getFilteredTodos(todos, filter);

  // ...

}
```

Usually, this code is fine! But maybe `getFilteredTodos()` is slow or you have a lot of `todos`. In that case you don’t want to recalculate `getFilteredTodos()` if some unrelated state variable like `newTodo` has changed.

You can cache (or [“memoize”](https://en.wikipedia.org/wiki/Memoization)) an expensive calculation by wrapping it in a [`useMemo`](/reference/react/useMemo) Hook:

### Note

[React Compiler](/learn/react-compiler) can automatically memoize expensive calculations for you, eliminating the need for manual `useMemo` in many cases.

```
import { useMemo, useState } from 'react';



function TodoList({ todos, filter }) {

  const [newTodo, setNewTodo] = useState('');

  const visibleTodos = useMemo(() => {

    // ✅ Does not re-run unless todos or filter change

    return getFilteredTodos(todos, filter);

  }, [todos, filter]);

  // ...

}
```

Or, written as a single line:

```
import { useMemo, useState } from 'react';



function TodoList({ todos, filter }) {

  const [newTodo, setNewTodo] = useState('');

  // ✅ Does not re-run getFilteredTodos() unless todos or filter change

  const visibleTodos = useMemo(() => getFilteredTodos(todos, filter), [todos, filter]);

  // ...

}
```

**This tells React that you don’t want the inner function to re-run unless either `todos` or `filter` have changed.** React will remember the return value of `getFilteredTodos()` during the initial render. During the next renders, it will check if `todos` or `filter` are different. If they’re the same as last time, `useMemo` will return the last result it has stored. But if they are different, React will call the inner function again (and store its result).

The function you wrap in [`useMemo`](/reference/react/useMemo) runs during rendering, so this only works for [pure calculations.](/learn/keeping-components-pure)

##### Deep Dive#### How to tell if a calculation is expensive?[](#how-to-tell-if-a-calculation-is-expensive "Link for How to tell if a calculation is expensive? ")

In general, unless you’re creating or looping over thousands of objects, it’s probably not expensive. If you want to get more confidence, you can add a console log to measure the time spent in a piece of code:

```
console.time('filter array');

const visibleTodos = getFilteredTodos(todos, filter);

console.timeEnd('filter array');
```

Perform the interaction you’re measuring (for example, typing into the input). You will then see logs like `filter array: 0.15ms` in your console. If the overall logged time adds up to a significant amount (say, `1ms` or more), it might make sense to memoize that calculation. As an experiment, you can then wrap the calculation in `useMemo` to verify whether the total logged time has decreased for that interaction or not:

```
console.time('filter array');

const visibleTodos = useMemo(() => {

  return getFilteredTodos(todos, filter); // Skipped if todos and filter haven't changed

}, [todos, filter]);

console.timeEnd('filter array');
```

`useMemo` won’t make the *first* render faster. It only helps you skip unnecessary work on updates.

Keep in mind that your machine is probably faster than your users’ so it’s a good idea to test the performance with an artificial slowdown. For example, Chrome offers a [CPU Throttling](https://developer.chrome.com/blog/new-in-devtools-61/#throttling) option for this.

Also note that measuring performance in development will not give you the most accurate results. (For example, when [Strict Mode](/reference/react/StrictMode) is on, you will see each component render twice rather than once.) To get the most accurate timings, build your app for production and test it on a device like your users have.

### Resetting all state when a prop changes[](#resetting-all-state-when-a-prop-changes "Link for Resetting all state when a prop changes ")

This `ProfilePage` component receives a `userId` prop. The page contains a comment input, and you use a `comment` state variable to hold its value. One day, you notice a problem: when you navigate from one profile to another, the `comment` state does not get reset. As a result, it’s easy to accidentally post a comment on a wrong user’s profile. To fix the issue, you want to clear out the `comment` state variable whenever the `userId` changes:

```
export default function ProfilePage({ userId }) {

  const [comment, setComment] = useState('');



  // 🔴 Avoid: Resetting state on prop change in an Effect

  useEffect(() => {

    setComment('');

  }, [userId]);

  // ...

}
```

This is inefficient because `ProfilePage` and its children will first render with the stale value, and then render again. It is also complicated because you’d need to do this in *every* component that has some state inside `ProfilePage`. For example, if the comment UI is nested, you’d want to clear out nested comment state too.

Instead, you can tell React that each user’s profile is conceptually a *different* profile by giving it an explicit key. Split your component in two and pass a `key` attribute from the outer component to the inner one:

```
export default function ProfilePage({ userId }) {

  return (

    <Profile

      userId={userId}

      key={userId}

    />

  );

}



function Profile({ userId }) {

  // ✅ This and any other state below will reset on key change automatically

  const [comment, setComment] = useState('');

  // ...

}
```

Normally, React preserves the state when the same component is rendered in the same spot. **By passing `userId` as a `key` to the `Profile` component, you’re asking React to treat two `Profile` components with different `userId` as two different components that should not share any state.** Whenever the key (which you’ve set to `userId`) changes, React will recreate the DOM and [reset the state](/learn/preserving-and-resetting-state#option-2-resetting-state-with-a-key) of the `Profile` component and all of its children. Now the `comment` field will clear out automatically when navigating between profiles.

Note that in this example, only the outer `ProfilePage` component is exported and visible to other files in the project. Components rendering `ProfilePage` don’t need to pass the key to it: they pass `userId` as a regular prop. The fact `ProfilePage` passes it as a `key` to the inner `Profile` component is an implementation detail.

### Adjusting some state when a prop changes[](#adjusting-some-state-when-a-prop-changes "Link for Adjusting some state when a prop changes ")

Sometimes, you might want to reset or adjust a part of the state on a prop change, but not all of it.

This `List` component receives a list of `items` as a prop, and maintains the selected item in the `selection` state variable. You want to reset the `selection` to `null` whenever the `items` prop receives a different array:

```
function List({ items }) {

  const [isReverse, setIsReverse] = useState(false);

  const [selection, setSelection] = useState(null);



  // 🔴 Avoid: Adjusting state on prop change in an Effect

  useEffect(() => {

    setSelection(null);

  }, [items]);

  // ...

}
```

This, too, is not ideal. Every time the `items` change, the `List` and its child components will render with a stale `selection` value at first. Then React will update the DOM and run the Effects. Finally, the `setSelection(null)` call will cause another re-render of the `List` and its child components, restarting this whole process again.

Start by deleting the Effect. Instead, adjust the state directly during rendering:

```
function List({ items }) {

  const [isReverse, setIsReverse] = useState(false);

  const [selection, setSelection] = useState(null);



  // Better: Adjust the state while rendering

  const [prevItems, setPrevItems] = useState(items);

  if (items !== prevItems) {

    setPrevItems(items);

    setSelection(null);

  }

  // ...

}
```

[Storing information from previous renders](/reference/react/useState#storing-information-from-previous-renders) like this can be hard to understand, but it’s better than updating the same state in an Effect. In the above example, `setSelection` is called directly during a render. React will re-render the `List` *immediately* after it exits with a `return` statement. React has not rendered the `List` children or updated the DOM yet, so this lets the `List` children skip rendering the stale `selection` value.

When you update a component during rendering, React throws away the returned JSX and immediately retries rendering. To avoid very slow cascading retries, React only lets you update the *same* component’s state during a render. If you update another component’s state during a render, you’ll see an error. A condition like `items !== prevItems` is necessary to avoid loops. You may adjust state like this, but any other side effects (like changing the DOM or setting timeouts) should stay in event handlers or Effects to [keep components pure.](/learn/keeping-components-pure)

**Although this pattern is more efficient than an Effect, most components shouldn’t need it either.** No matter how you do it, adjusting state based on props or other state makes your data flow more difficult to understand and debug. Always check whether you can [reset all state with a key](#resetting-all-state-when-a-prop-changes) or [calculate everything during rendering](#updating-state-based-on-props-or-state) instead. For example, instead of storing (and resetting) the selected *item*, you can store the selected *item ID:*

```
function List({ items }) {

  const [isReverse, setIsReverse] = useState(false);

  const [selectedId, setSelectedId] = useState(null);

  // ✅ Best: Calculate everything during rendering

  const selection = items.find(item => item.id === selectedId) ?? null;

  // ...

}
```

Now there is no need to “adjust” the state at all. If the item with the selected ID is in the list, it remains selected. If it’s not, the `selection` calculated during rendering will be `null` because no matching item was found. This behavior is different, but arguably better because most changes to `items` preserve the selection.

### Sharing logic between event handlers[](#sharing-logic-between-event-handlers "Link for Sharing logic between event handlers ")

Let’s say you have a product page with two buttons (Buy and Checkout) that both let you buy that product. You want to show a notification whenever the user puts the product in the cart. Calling `showNotification()` in both buttons’ click handlers feels repetitive so you might be tempted to place this logic in an Effect:

```
function ProductPage({ product, addToCart }) {

  // 🔴 Avoid: Event-specific logic inside an Effect

  useEffect(() => {

    if (product.isInCart) {

      showNotification(`Added ${product.name} to the shopping cart!`);

    }

  }, [product]);



  function handleBuyClick() {

    addToCart(product);

  }



  function handleCheckoutClick() {

    addToCart(product);

    navigateTo('/checkout');

  }

  // ...

}
```

This Effect is unnecessary. It will also most likely cause bugs. For example, let’s say that your app “remembers” the shopping cart between the page reloads. If you add a product to the cart once and refresh the page, the notification will appear again. It will keep appearing every time you refresh that product’s page. This is because `product.isInCart` will already be `true` on the page load, so the Effect above will call `showNotification()`.

**When you’re not sure whether some code should be in an Effect or in an event handler, ask yourself *why* this code needs to run. Use Effects only for code that should run *because* the component was displayed to the user.** In this example, the notification should appear because the user *pressed the button*, not because the page was displayed! Delete the Effect and put the shared logic into a function called from both event handlers:

```
function ProductPage({ product, addToCart }) {

  // ✅ Good: Event-specific logic is called from event handlers

  function buyProduct() {

    addToCart(product);

    showNotification(`Added ${product.name} to the shopping cart!`);

  }



  function handleBuyClick() {

    buyProduct();

  }



  function handleCheckoutClick() {

    buyProduct();

    navigateTo('/checkout');

  }

  // ...

}
```

This both removes the unnecessary Effect and fixes the bug.

### Sending a POST request[](#sending-a-post-request "Link for Sending a POST request ")

This `Form` component sends two kinds of POST requests. It sends an analytics event when it mounts. When you fill in the form and click the Submit button, it will send a POST request to the `/api/register` endpoint:

```
function Form() {

  const [firstName, setFirstName] = useState('');

  const [lastName, setLastName] = useState('');



  // ✅ Good: This logic should run because the component was displayed

  useEffect(() => {

    post('/analytics/event', { eventName: 'visit_form' });

  }, []);



  // 🔴 Avoid: Event-specific logic inside an Effect

  const [jsonToSubmit, setJsonToSubmit] = useState(null);

  useEffect(() => {

    if (jsonToSubmit !== null) {

      post('/api/register', jsonToSubmit);

    }

  }, [jsonToSubmit]);



  function handleSubmit(e) {

    e.preventDefault();

    setJsonToSubmit({ firstName, lastName });

  }

  // ...

}
```

Let’s apply the same criteria as in the example before.

The analytics POST request should remain in an Effect. This is because the *reason* to send the analytics event is that the form was displayed. (It would fire twice in development, but [see here](/learn/synchronizing-with-effects#sending-analytics) for how to deal with that.)

However, the `/api/register` POST request is not caused by the form being *displayed*. You only want to send the request at one specific moment in time: when the user presses the button. It should only ever happen *on that particular interaction*. Delete the second Effect and move that POST request into the event handler:

```
function Form() {

  const [firstName, setFirstName] = useState('');

  const [lastName, setLastName] = useState('');



  // ✅ Good: This logic runs because the component was displayed

  useEffect(() => {

    post('/analytics/event', { eventName: 'visit_form' });

  }, []);



  function handleSubmit(e) {

    e.preventDefault();

    // ✅ Good: Event-specific logic is in the event handler

    post('/api/register', { firstName, lastName });

  }

  // ...

}
```

When you choose whether to put some logic into an event handler or an Effect, the main question you need to answer is *what kind of logic* it is from the user’s perspective. If this logic is caused by a particular interaction, keep it in the event handler. If it’s caused by the user *seeing* the component on the screen, keep it in the Effect.

### Chains of computations[](#chains-of-computations "Link for Chains of computations ")

Sometimes you might feel tempted to chain Effects that each adjust a piece of state based on other state:

```
function Game() {

  const [card, setCard] = useState(null);

  const [goldCardCount, setGoldCardCount] = useState(0);

  const [round, setRound] = useState(1);

  const [isGameOver, setIsGameOver] = useState(false);



  // 🔴 Avoid: Chains of Effects that adjust the state solely to trigger each other

  useEffect(() => {

    if (card !== null && card.gold) {

      setGoldCardCount(c => c + 1);

    }

  }, [card]);



  useEffect(() => {

    if (goldCardCount > 3) {

      setRound(r => r + 1)

      setGoldCardCount(0);

    }

  }, [goldCardCount]);



  useEffect(() => {

    if (round > 5) {

      setIsGameOver(true);

    }

  }, [round]);



  useEffect(() => {

    alert('Good game!');

  }, [isGameOver]);



  function handlePlaceCard(nextCard) {

    if (isGameOver) {

      throw Error('Game already ended.');

    } else {

      setCard(nextCard);

    }

  }



  // ...
```

There are two problems with this code.

The first problem is that it is very inefficient: the component (and its children) have to re-render between each `set` call in the chain. In the example above, in the worst case (`setCard` → render → `setGoldCardCount` → render → `setRound` → render → `setIsGameOver` → render) there are three unnecessary re-renders of the tree below.

The second problem is that even if it weren’t slow, as your code evolves, you will run into cases where the “chain” you wrote doesn’t fit the new requirements. Imagine you are adding a way to step through the history of the game moves. You’d do it by updating each state variable to a value from the past. However, setting the `card` state to a value from the past would trigger the Effect chain again and change the data you’re showing. Such code is often rigid and fragile.

In this case, it’s better to calculate what you can during rendering, and adjust the state in the event handler:

```
function Game() {

  const [card, setCard] = useState(null);

  const [goldCardCount, setGoldCardCount] = useState(0);

  const [round, setRound] = useState(1);



  // ✅ Calculate what you can during rendering

  const isGameOver = round > 5;



  function handlePlaceCard(nextCard) {

    if (isGameOver) {

      throw Error('Game already ended.');

    }



    // ✅ Calculate all the next state in the event handler

    setCard(nextCard);

    if (nextCard.gold) {

      if (goldCardCount < 3) {

        setGoldCardCount(goldCardCount + 1);

      } else {

        setGoldCardCount(0);

        setRound(round + 1);

        if (round === 5) {

          alert('Good game!');

        }

      }

    }

  }



  // ...
```

This is a lot more efficient. Also, if you implement a way to view game history, now you will be able to set each state variable to a move from the past without triggering the Effect chain that adjusts every other value. If you need to reuse logic between several event handlers, you can [extract a function](#sharing-logic-between-event-handlers) and call it from those handlers.

Remember that inside event handlers, [state behaves like a snapshot.](/learn/state-as-a-snapshot) For example, even after you call `setRound(round + 1)`, the `round` variable will reflect the value at the time the user clicked the button. If you need to use the next value for calculations, define it manually like `const nextRound = round + 1`.

In some cases, you *can’t* calculate the next state directly in the event handler. For example, imagine a form with multiple dropdowns where the options of the next dropdown depend on the selected value of the previous dropdown. Then, a chain of Effects is appropriate because you are synchronizing with network.

### Initializing the application[](#initializing-the-application "Link for Initializing the application ")

Some logic should only run once when the app loads.

You might be tempted to place it in an Effect in the top-level component:

```
function App() {

  // 🔴 Avoid: Effects with logic that should only ever run once

  useEffect(() => {

    loadDataFromLocalStorage();

    checkAuthToken();

  }, []);

  // ...

}
```

However, you’ll quickly discover that it [runs twice in development.](/learn/synchronizing-with-effects#how-to-handle-the-effect-firing-twice-in-development) This can cause issues—for example, maybe it invalidates the authentication token because the function wasn’t designed to be called twice. In general, your components should be resilient to being remounted. This includes your top-level `App` component.

Although it may not ever get remounted in practice in production, following the same constraints in all components makes it easier to move and reuse code. If some logic must run *once per app load* rather than *once per component mount*, add a top-level variable to track whether it has already executed:

```
let didInit = false;



function App() {

  useEffect(() => {

    if (!didInit) {

      didInit = true;

      // ✅ Only runs once per app load

      loadDataFromLocalStorage();

      checkAuthToken();

    }

  }, []);

  // ...

}
```

You can also run it during module initialization and before the app renders:

```
if (typeof window !== 'undefined') { // Check if we're running in the browser.

   // ✅ Only runs once per app load

  checkAuthToken();

  loadDataFromLocalStorage();

}



function App() {

  // ...

}
```

Code at the top level runs once when your component is imported—even if it doesn’t end up being rendered. To avoid slowdown or surprising behavior when importing arbitrary components, don’t overuse this pattern. Keep app-wide initialization logic to root component modules like `App.js` or in your application’s entry point.

### Notifying parent components about state changes[](#notifying-parent-components-about-state-changes "Link for Notifying parent components about state changes ")

Let’s say you’re writing a `Toggle` component with an internal `isOn` state which can be either `true` or `false`. There are a few different ways to toggle it (by clicking or dragging). You want to notify the parent component whenever the `Toggle` internal state changes, so you expose an `onChange` event and call it from an Effect:

```
function Toggle({ onChange }) {

  const [isOn, setIsOn] = useState(false);



  // 🔴 Avoid: The onChange handler runs too late

  useEffect(() => {

    onChange(isOn);

  }, [isOn, onChange])



  function handleClick() {

    setIsOn(!isOn);

  }



  function handleDragEnd(e) {

    if (isCloserToRightEdge(e)) {

      setIsOn(true);

    } else {

      setIsOn(false);

    }

  }



  // ...

}
```

Like earlier, this is not ideal. The `Toggle` updates its state first, and React updates the screen. Then React runs the Effect, which calls the `onChange` function passed from a parent component. Now the parent component will update its own state, starting another render pass. It would be better to do everything in a single pass.

Delete the Effect and instead update the state of *both* components within the same event handler:

```
function Toggle({ onChange }) {

  const [isOn, setIsOn] = useState(false);



  function updateToggle(nextIsOn) {

    // ✅ Good: Perform all updates during the event that caused them

    setIsOn(nextIsOn);

    onChange(nextIsOn);

  }



  function handleClick() {

    updateToggle(!isOn);

  }



  function handleDragEnd(e) {

    if (isCloserToRightEdge(e)) {

      updateToggle(true);

    } else {

      updateToggle(false);

    }

  }



  // ...

}
```

With this approach, both the `Toggle` component and its parent component update their state during the event. React [batches updates](/learn/queueing-a-series-of-state-updates) from different components together, so there will only be one render pass.

You might also be able to remove the state altogether, and instead receive `isOn` from the parent component:

```
// ✅ Also good: the component is fully controlled by its parent

function Toggle({ isOn, onChange }) {

  function handleClick() {

    onChange(!isOn);

  }



  function handleDragEnd(e) {

    if (isCloserToRightEdge(e)) {

      onChange(true);

    } else {

      onChange(false);

    }

  }



  // ...

}
```

[“Lifting state up”](/learn/sharing-state-between-components) lets the parent component fully control the `Toggle` by toggling the parent’s own state. This means the parent component will have to contain more logic, but there will be less state overall to worry about. Whenever you try to keep two different state variables synchronized, try lifting state up instead!

### Passing data to the parent[](#passing-data-to-the-parent "Link for Passing data to the parent ")

This `Child` component fetches some data and then passes it to the `Parent` component in an Effect:

```
function Parent() {

  const [data, setData] = useState(null);

  // ...

  return <Child onFetched={setData} />;

}



function Child({ onFetched }) {

  const data = useSomeAPI();

  // 🔴 Avoid: Passing data to the parent in an Effect

  useEffect(() => {

    if (data) {

      onFetched(data);

    }

  }, [onFetched, data]);

  // ...

}
```

In React, data flows from the parent components to their children. When you see something wrong on the screen, you can trace where the information comes from by going up the component chain until you find which component passes the wrong prop or has the wrong state. When child components update the state of their parent components in Effects, the data flow becomes very difficult to trace. Since both the child and the parent need the same data, let the parent component fetch that data, and *pass it down* to the child instead:

```
function Parent() {

  const data = useSomeAPI();

  // ...

  // ✅ Good: Passing data down to the child

  return <Child data={data} />;

}



function Child({ data }) {

  // ...

}
```

This is simpler and keeps the data flow predictable: the data flows down from the parent to the child.

### Subscribing to an external store[](#subscribing-to-an-external-store "Link for Subscribing to an external store ")

Sometimes, your components may need to subscribe to some data outside of the React state. This data could be from a third-party library or a built-in browser API. Since this data can change without React’s knowledge, you need to manually subscribe your components to it. This is often done with an Effect, for example:

```
function useOnlineStatus() {

  // Not ideal: Manual store subscription in an Effect

  const [isOnline, setIsOnline] = useState(true);

  useEffect(() => {

    function updateState() {

      setIsOnline(navigator.onLine);

    }



    updateState();



    window.addEventListener('online', updateState);

    window.addEventListener('offline', updateState);

    return () => {

      window.removeEventListener('online', updateState);

      window.removeEventListener('offline', updateState);

    };

  }, []);

  return isOnline;

}



function ChatIndicator() {

  const isOnline = useOnlineStatus();

  // ...

}
```

Here, the component subscribes to an external data store (in this case, the browser `navigator.onLine` API). Since this API does not exist on the server (so it can’t be used for the initial HTML), initially the state is set to `true`. Whenever the value of that data store changes in the browser, the component updates its state.

Although it’s common to use Effects for this, React has a purpose-built Hook for subscribing to an external store that is preferred instead. Delete the Effect and replace it with a call to [`useSyncExternalStore`](/reference/react/useSyncExternalStore):

```
function subscribe(callback) {

  window.addEventListener('online', callback);

  window.addEventListener('offline', callback);

  return () => {

    window.removeEventListener('online', callback);

    window.removeEventListener('offline', callback);

  };

}



function useOnlineStatus() {

  // ✅ Good: Subscribing to an external store with a built-in Hook

  return useSyncExternalStore(

    subscribe, // React won't resubscribe for as long as you pass the same function

    () => navigator.onLine, // How to get the value on the client

    () => true // How to get the value on the server

  );

}



function ChatIndicator() {

  const isOnline = useOnlineStatus();

  // ...

}
```

This approach is less error-prone than manually syncing mutable data to React state with an Effect. Typically, you’ll write a custom Hook like `useOnlineStatus()` above so that you don’t need to repeat this code in the individual components. [Read more about subscribing to external stores from React components.](/reference/react/useSyncExternalStore)

### Fetching data[](#fetching-data "Link for Fetching data ")

Many apps use Effects to kick off data fetching. It is quite common to write a data fetching Effect like this:

```
function SearchResults({ query }) {

  const [results, setResults] = useState([]);

  const [page, setPage] = useState(1);



  useEffect(() => {

    // 🔴 Avoid: Fetching without cleanup logic

    fetchResults(query, page).then(json => {

      setResults(json);

    });

  }, [query, page]);



  function handleNextPageClick() {

    setPage(page + 1);

  }

  // ...

}
```

You *don’t* need to move this fetch to an event handler.

This might seem like a contradiction with the earlier examples where you needed to put the logic into the event handlers! However, consider that it’s not *the typing event* that’s the main reason to fetch. Search inputs are often prepopulated from the URL, and the user might navigate Back and Forward without touching the input.

It doesn’t matter where `page` and `query` come from. While this component is visible, you want to keep `results` [synchronized](/learn/synchronizing-with-effects) with data from the network for the current `page` and `query`. This is why it’s an Effect.

However, the code above has a bug. Imagine you type `"hello"` fast. Then the `query` will change from `"h"`, to `"he"`, `"hel"`, `"hell"`, and `"hello"`. This will kick off separate fetches, but there is no guarantee about which order the responses will arrive in. For example, the `"hell"` response may arrive *after* the `"hello"` response. Since it will call `setResults()` last, you will be displaying the wrong search results. This is called a [“race condition”](https://en.wikipedia.org/wiki/Race_condition): two different requests “raced” against each other and came in a different order than you expected.

**To fix the race condition, you need to [add a cleanup function](/learn/synchronizing-with-effects#fetching-data) to ignore stale responses:**

```
function SearchResults({ query }) {

  const [results, setResults] = useState([]);

  const [page, setPage] = useState(1);

  useEffect(() => {

    let ignore = false;

    fetchResults(query, page).then(json => {

      if (!ignore) {

        setResults(json);

      }

    });

    return () => {

      ignore = true;

    };

  }, [query, page]);



  function handleNextPageClick() {

    setPage(page + 1);

  }

  // ...

}
```

This ensures that when your Effect fetches data, all responses except the last requested one will be ignored.

Handling race conditions is not the only difficulty with implementing data fetching. You might also want to think about caching responses (so that the user can click Back and see the previous screen instantly), how to fetch data on the server (so that the initial server-rendered HTML contains the fetched content instead of a spinner), and how to avoid network waterfalls (so that a child can fetch data without waiting for every parent).

**These issues apply to any UI library, not just React. Solving them is not trivial, which is why modern [frameworks](/learn/creating-a-react-app#full-stack-frameworks) provide more efficient built-in data fetching mechanisms than fetching data in Effects.**

If you don’t use a framework (and don’t want to build your own) but would like to make data fetching from Effects more ergonomic, consider extracting your fetching logic into a custom Hook like in this example:

```
function SearchResults({ query }) {

  const [page, setPage] = useState(1);

  const params = new URLSearchParams({ query, page });

  const results = useData(`/api/search?${params}`);



  function handleNextPageClick() {

    setPage(page + 1);

  }

  // ...

}



function useData(url) {

  const [data, setData] = useState(null);

  useEffect(() => {

    let ignore = false;

    fetch(url)

      .then(response => response.json())

      .then(json => {

        if (!ignore) {

          setData(json);

        }

      });

    return () => {

      ignore = true;

    };

  }, [url]);

  return data;

}
```

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useEffect } from 'react';
import { initialTodos, createTodo } from './todos.js';

export default function TodoList() {
  const [todos, setTodos] = useState(initialTodos);
  const [showActive, setShowActive] = useState(false);
  const [activeTodos, setActiveTodos] = useState([]);
  const [visibleTodos, setVisibleTodos] = useState([]);
  const [footer, setFooter] = useState(null);

  useEffect(() => {
    setActiveTodos(todos.filter(todo => !todo.completed));
  }, [todos]);

  useEffect(() => {
    setVisibleTodos(showActive ? activeTodos : todos);
  }, [showActive, todos, activeTodos]);

  useEffect(() => {
    setFooter(
      <footer>
        {activeTodos.length} todos left
      </footer>
    );
  }, [activeTodos]);

  return (
    <>
      <label>
        <input
          type="checkbox"
          checked={showActive}
          onChange={e => setShowActive(e.target.checked)}
        />
        Show only active todos
      </label>
      <NewTodo onAdd={newTodo => setTodos([...todos, newTodo])} />
      <ul>
        {visibleTodos.map(todo => (
          <li key={todo.id}>
            {todo.completed ? <s>{todo.text}</s> : todo.text}
          </li>
        ))}
      </ul>
      {footer}
    </>
  );
}

function NewTodo({ onAdd }) {
  const [text, setText] = useState('');

  function handleAddClick() {
    setText('');
    onAdd(createTodo(text));
  }

  return (
    <>
      <input value={text} onChange={e => setText(e.target.value)} />
      <button onClick={handleAddClick}>
        Add
      </button>
    </>
  );
}
```

[PreviousSynchronizing with Effects](/learn/synchronizing-with-effects)

[NextLifecycle of Reactive Effects](/learn/lifecycle-of-reactive-effects)

***

----
url: https://legacy.reactjs.org/blog/2022/03/29/react-v18.html
----

March 29, 2022 by [The React Team](https://reactjs.org/community/team.html)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

React 18 is now available on npm!

In our last post, we shared step-by-step instructions for [upgrading your app to React 18](https://reactjs.org/blog/2022/03/08/react-18-upgrade-guide.html). In this post, we’ll give an overview of what’s new in React 18, and what it means for the future.

Our latest major version includes out-of-the-box improvements like automatic batching, new APIs like startTransition, and streaming server-side rendering with support for Suspense.

Many of the features in React 18 are built on top of our new concurrent renderer, a behind-the-scenes change that unlocks powerful new capabilities. Concurrent React is opt-in — it’s only enabled when you use a concurrent feature — but we think it will have a big impact on the way people build applications.

We’ve spent years researching and developing support for concurrency in React, and we’ve taken extra care to provide a gradual adoption path for existing users. Last summer, [we formed the React 18 Working Group](https://reactjs.org/blog/2021/06/08/the-plan-for-react-18.html) to gather feedback from experts in the community and ensure a smooth upgrade experience for the entire React ecosystem.

In case you missed it, we shared a lot of this vision at React Conf 2021:

* In [the keynote](https://www.youtube.com/watch?v=FZ0cG47msEk\&list=PLNG_1j3cPCaZZ7etkzWA7JfdmKWT0pMsa), we explain how React 18 fits into our mission to make it easy for developers to build great user experiences
* [Shruti Kapoor](https://twitter.com/shrutikapoor08) [demonstrated how to use the new features in React 18](https://www.youtube.com/watch?v=ytudH8je5ko\&list=PLNG_1j3cPCaZZ7etkzWA7JfdmKWT0pMsa\&index=2)
* [Shaundai Person](https://twitter.com/shaundai) gave us an overview of [streaming server rendering with Suspense](https://www.youtube.com/watch?v=pj5N-Khihgc\&list=PLNG_1j3cPCaZZ7etkzWA7JfdmKWT0pMsa\&index=3)

Below is a full overview of what to expect in this release, starting with Concurrent Rendering.

*Note for React Native users: React 18 will ship in React Native with the New React Native Architecture. For more information, see the [React Conf keynote here](https://www.youtube.com/watch?v=FZ0cG47msEk\&t=1530s).*

## [](#what-is-concurrent-react)What is Concurrent React?

## [](#gradually-adopting-concurrent-features)Gradually Adopting Concurrent Features

Technically, concurrent rendering is a breaking change. Because concurrent rendering is interruptible, components behave slightly differently when it is enabled.

In our testing, we’ve upgraded thousands of components to React 18. What we’ve found is that nearly all existing components “just work” with concurrent rendering, without any changes. However, some of them may require some additional migration effort. Although the changes are usually small, you’ll still have the ability to make them at your own pace. The new rendering behavior in React 18 is **only enabled in the parts of your app that use new features.**

The overall upgrade strategy is to get your application running on React 18 without breaking existing code. Then you can gradually start adding concurrent features at your own pace. You can use [`<StrictMode>`](/docs/strict-mode.html) to help surface concurrency-related bugs during development. Strict Mode doesn’t affect production behavior, but during development it will log extra warnings and double-invoke functions that are expected to be idempotent. It won’t catch everything, but it’s effective at preventing the most common types of mistakes.

After you upgrade to React 18, you’ll be able to start using concurrent features immediately. For example, you can use startTransition to navigate between screens without blocking user input. Or useDeferredValue to throttle expensive re-renders.

However, long term, we expect the main way you’ll add concurrency to your app is by using a concurrent-enabled library or framework. In most cases, you won’t interact with concurrent APIs directly. For example, instead of developers calling startTransition whenever they navigate to a new screen, router libraries will automatically wrap navigations in startTransition.

It may take some time for libraries to upgrade to be concurrent compatible. We’ve provided new APIs to make it easier for libraries to take advantage of concurrent features. In the meantime, please be patient with maintainers as we work to gradually migrate the React ecosystem.

For more info, see our previous post: [How to upgrade to React 18](https://reactjs.org/blog/2022/03/08/react-18-upgrade-guide.html).

## [](#suspense-in-data-frameworks)Suspense in Data Frameworks

In React 18, you can start using Suspense for data fetching in opinionated frameworks like Relay, Next.js, Hydrogen, or Remix. Ad hoc data fetching with Suspense is technically possible, but still not recommended as a general strategy.

In the future, we may expose additional primitives that could make it easier to access your data with Suspense, perhaps without the use of an opinionated framework. However, Suspense works best when it’s deeply integrated into your application’s architecture: your router, your data layer, and your server rendering environment. So even long term, we expect that libraries and frameworks will play a crucial role in the React ecosystem.

As in previous versions of React, you can also use Suspense for code splitting on the client with React.lazy. But our vision for Suspense has always been about much more than loading code — the goal is to extend support for Suspense so that eventually, the same declarative Suspense fallback can handle any asynchronous operation (loading code, data, images, etc).

## [](#server-components-is-still-in-development)Server Components is Still in Development

[**Server Components**](https://reactjs.org/blog/2020/12/21/data-fetching-with-react-server-components.html) is an upcoming feature that allows developers to build apps that span the server and client, combining the rich interactivity of client-side apps with the improved performance of traditional server rendering. Server Components is not inherently coupled to Concurrent React, but it’s designed to work best with concurrent features like Suspense and streaming server rendering.

Server Components is still experimental, but we expect to release an initial version in a minor 18.x release. In the meantime, we’re working with frameworks like Next.js, Hydrogen, and Remix to advance the proposal and get it ready for broad adoption.

## [](#whats-new-in-react-18)What’s New in React 18

### [](#new-feature-automatic-batching)New Feature: Automatic Batching

Batching is when React groups multiple state updates into a single re-render for better performance. Without automatic batching, we only batched updates inside React event handlers. Updates inside of promises, setTimeout, native event handlers, or any other event were not batched in React by default. With automatic batching, these updates will be batched automatically:

```
// Before: only React events were batched.
setTimeout(() => {
  setCount(c => c + 1);
  setFlag(f => !f);
  // React will render twice, once for each state update (no batching)
}, 1000);

// After: updates inside of timeouts, promises,
// native event handlers or any other event are batched.
setTimeout(() => {
  setCount(c => c + 1);
  setFlag(f => !f);
  // React will only re-render once at the end (that's batching!)
}, 1000);
```

For more info, see this post for [Automatic batching for fewer renders in React 18](https://github.com/reactwg/react-18/discussions/21).

### [](#new-feature-transitions)New Feature: Transitions

A transition is a new concept in React to distinguish between urgent and non-urgent updates.

* **Urgent updates** reflect direct interaction, like typing, clicking, pressing, and so on.
* **Transition updates** transition the UI from one view to another.

Urgent updates like typing, clicking, or pressing, need immediate response to match our intuitions about how physical objects behave. Otherwise they feel “wrong”. However, transitions are different because the user doesn’t expect to see every intermediate value on screen.

For example, when you select a filter in a dropdown, you expect the filter button itself to respond immediately when you click. However, the actual results may transition separately. A small delay would be imperceptible and often expected. And if you change the filter again before the results are done rendering, you only care to see the latest results.

Typically, for the best user experience, a single user input should result in both an urgent update and a non-urgent one. You can use startTransition API inside an input event to inform React which updates are urgent and which are “transitions”:

```
import {startTransition} from 'react';

// Urgent: Show what was typed
setInputValue(input);

// Mark any state updates inside as transitions
startTransition(() => {
  // Transition: Show the results
  setSearchQuery(input);
});
```

Updates wrapped in startTransition are handled as non-urgent and will be interrupted if more urgent updates like clicks or key presses come in. If a transition gets interrupted by the user (for example, by typing multiple characters in a row), React will throw out the stale rendering work that wasn’t finished and render only the latest update.

* `useTransition`: a hook to start transitions, including a value to track the pending state.
* `startTransition`: a method to start transitions when the hook cannot be used.

Transitions will opt in to concurrent rendering, which allows the update to be interrupted. If the content re-suspends, transitions also tell React to continue showing the current content while rendering the transition content in the background (see the [Suspense RFC](https://github.com/reactjs/rfcs/blob/main/text/0213-suspense-in-react-18.md) for more info).

[See docs for transitions here](/docs/react-api.html#transitions).

### [](#new-suspense-features)New Suspense Features

Suspense lets you declaratively specify the loading state for a part of the component tree if it’s not yet ready to be displayed:

```
<Suspense fallback={<Spinner />}>
  <Comments />
</Suspense>
```

Suspense makes the “UI loading state” a first-class declarative concept in the React programming model. This lets us build higher-level features on top of it.

We introduced a limited version of Suspense several years ago. However, the only supported use case was code splitting with React.lazy, and it wasn’t supported at all when rendering on the server.

In React 18, we’ve added support for Suspense on the server and expanded its capabilities using concurrent rendering features.

Suspense in React 18 works best when combined with the transition API. If you suspend during a transition, React will prevent already-visible content from being replaced by a fallback. Instead, React will delay the render until enough data has loaded to prevent a bad loading state.

For more, see the RFC for [Suspense in React 18](https://github.com/reactjs/rfcs/blob/main/text/0213-suspense-in-react-18.md).

### [](#new-client-and-server-rendering-apis)New Client and Server Rendering APIs

In this release we took the opportunity to redesign the APIs we expose for rendering on the client and server. These changes allow users to continue using the old APIs in React 17 mode while they upgrade to the new APIs in React 18.

#### [](#react-dom-client)React DOM Client

These new APIs are now exported from `react-dom/client`:

* `createRoot`: New method to create a root to `render` or `unmount`. Use it instead of `ReactDOM.render`. New features in React 18 don’t work without it.
* `hydrateRoot`: New method to hydrate a server rendered application. Use it instead of `ReactDOM.hydrate` in conjunction with the new React DOM Server APIs. New features in React 18 don’t work without it.

Both `createRoot` and `hydrateRoot` accept a new option called `onRecoverableError` in case you want to be notified when React recovers from errors during rendering or hydration for logging. By default, React will use [`reportError`](https://developer.mozilla.org/en-US/docs/Web/API/reportError), or `console.error` in the older browsers.

[See docs for React DOM Client here](/docs/react-dom-client.html).

#### [](#react-dom-server)React DOM Server

These new APIs are now exported from `react-dom/server` and have full support for streaming Suspense on the server:

* `renderToPipeableStream`: for streaming in Node environments.
* `renderToReadableStream`: for modern edge runtime environments, such as Deno and Cloudflare workers.

The existing `renderToString` method keeps working but is discouraged.

[See docs for React DOM Server here](/docs/react-dom-server.html).

### [](#new-strict-mode-behaviors)New Strict Mode Behaviors

In the future, we’d like to add a feature that allows React to add and remove sections of the UI while preserving state. For example, when a user tabs away from a screen and back, React should be able to immediately show the previous screen. To do this, React would unmount and remount trees using the same component state as before.

This feature will give React apps better performance out-of-the-box, but requires components to be resilient to effects being mounted and destroyed multiple times. Most effects will work without any changes, but some effects assume they are only mounted or destroyed once.

To help surface these issues, React 18 introduces a new development-only check to Strict Mode. This new check will automatically unmount and remount every component, whenever a component mounts for the first time, restoring the previous state on the second mount.

Before this change, React would mount the component and create the effects:

```
* React mounts the component.
  * Layout effects are created.
  * Effects are created.
```

With Strict Mode in React 18, React will simulate unmounting and remounting the component in development mode:

```
* React mounts the component.
  * Layout effects are created.
  * Effects are created.
* React simulates unmounting the component.
  * Layout effects are destroyed.
  * Effects are destroyed.
* React simulates mounting the component with the previous state.
  * Layout effects are created.
  * Effects are created.
```

[See docs for ensuring reusable state here](/docs/strict-mode.html#ensuring-reusable-state).

### [](#new-hooks)New Hooks

#### [](#useid)useId

`useId` is a new hook for generating unique IDs on both the client and server, while avoiding hydration mismatches. It is primarily useful for component libraries integrating with accessibility APIs that require unique IDs. This solves an issue that already exists in React 17 and below, but it’s even more important in React 18 because of how the new streaming server renderer delivers HTML out-of-order. [See docs here](/docs/hooks-reference.html#useid).

> Note
>
> `useId` is **not** for generating [keys in a list](/docs/lists-and-keys.html#keys). Keys should be generated from your data.

#### [](#usetransition)useTransition

`useTransition` and `startTransition` let you mark some state updates as not urgent. Other state updates are considered urgent by default. React will allow urgent state updates (for example, updating a text input) to interrupt non-urgent state updates (for example, rendering a list of search results). [See docs here](/docs/hooks-reference.html#usetransition)

#### [](#usedeferredvalue)useDeferredValue

`useDeferredValue` lets you defer re-rendering a non-urgent part of the tree. It is similar to debouncing, but has a few advantages compared to it. There is no fixed time delay, so React will attempt the deferred render right after the first render is reflected on the screen. The deferred render is interruptible and doesn’t block user input. [See docs here](/docs/hooks-reference.html#usedeferredvalue).

#### [](#usesyncexternalstore)useSyncExternalStore

`useSyncExternalStore` is a new hook that allows external stores to support concurrent reads by forcing updates to the store to be synchronous. It removes the need for useEffect when implementing subscriptions to external data sources, and is recommended for any library that integrates with state external to React. [See docs here](/docs/hooks-reference.html#usesyncexternalstore).

> Note
>
> `useSyncExternalStore` is intended to be used by libraries, not application code.

#### [](#useinsertioneffect)useInsertionEffect

`useInsertionEffect` is a new hook that allows CSS-in-JS libraries to address performance issues of injecting styles in render. Unless you’ve already built a CSS-in-JS library we don’t expect you to ever use this. This hook will run after the DOM is mutated, but before layout effects read the new layout. This solves an issue that already exists in React 17 and below, but is even more important in React 18 because React yields to the browser during concurrent rendering, giving it a chance to recalculate layout. [See docs here](/docs/hooks-reference.html#useinsertioneffect).

> Note
>
> `useInsertionEffect` is intended to be used by libraries, not application code.

## [](#how-to-upgrade)How to Upgrade

See [How to Upgrade to React 18](https://reactjs.org/blog/2022/03/08/react-18-upgrade-guide.html) for step-by-step instructions and a full list of breaking and notable changes.

## [](#changelog)Changelog

### [](#react)React

### [](#react-dom)React DOM

### [](#react-dom-server-1)React DOM Server

### [](#react-dom-test-utils)React DOM Test Utils

* Throw when `act` is used in production. ([#21686](https://github.com/facebook/react/pull/21686) by [@acdlite](https://github.com/acdlite))
* Support disabling spurious act warnings with `global.IS_REACT_ACT_ENVIRONMENT`. ([#22561](https://github.com/facebook/react/pull/22561) by [@acdlite](https://github.com/acdlite))
* Expand act warning to cover all APIs that might schedule React work. ([#22607](https://github.com/facebook/react/pull/22607) by [@acdlite](https://github.com/acdlite))
* Make `act` batch updates. ([#21797](https://github.com/facebook/react/pull/21797) by [@acdlite](https://github.com/acdlite))
* Remove warning for dangling passive effects. ([#22609](https://github.com/facebook/react/pull/22609) by [@acdlite](https://github.com/acdlite))

### [](#react-refresh)React Refresh

* Track late-mounted roots in Fast Refresh. ([#22740](https://github.com/facebook/react/pull/22740) by [@anc95](https://github.com/anc95))
* Add `exports` field to `package.json`. ([#23087](https://github.com/facebook/react/pull/23087) by [@otakustay](https://github.com/otakustay))

### [](#server-components-experimental)Server Components (Experimental)

* Add Server Context support. ([#23244](https://github.com/facebook/react/pull/23244) by [@salazarm](https://github.com/salazarm))
* Add `lazy` support. ([#24068](https://github.com/facebook/react/pull/24068) by [@gnoff](https://github.com/gnoff))
* Update webpack plugin for webpack 5 ([#22739](https://github.com/facebook/react/pull/22739) by [@michenly](https://github.com/michenly))
* Fix a mistake in the Node loader. ([#22537](https://github.com/facebook/react/pull/22537) by [@btea](https://github.com/btea))
* Use `globalThis` instead of `window` for edge environments. ([#22777](https://github.com/facebook/react/pull/22777) by [@huozhi](https://github.com/huozhi))

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2022-03-29-react-v18.md)

----
url: https://legacy.reactjs.org/docs/handling-events.html
----

> These docs are old and won’t be updated. Go to [react.dev](https://react.dev/) for the new React docs.
>
> These new documentation pages teach modern React and include live examples:
>
> * [Responding to Events](https://react.dev/learn/responding-to-events)

Handling events with React elements is very similar to handling events on DOM elements. There are some syntax differences:

* React events are named using camelCase, rather than lowercase.
* With JSX you pass a function as the event handler, rather than a string.

For example, the HTML:

```
<button onclick="activateLasers()">
  Activate Lasers
</button>
```

is slightly different in React:

```
<button onClick={activateLasers}>  Activate Lasers
</button>
```

Another difference is that you cannot return `false` to prevent default behavior in React. You must call `preventDefault` explicitly. For example, with plain HTML, to prevent the default form behavior of submitting, you can write:

```
<form onsubmit="console.log('You clicked submit.'); return false">
  <button type="submit">Submit</button>
</form>
```

In React, this could instead be:

```
function Form() {
  function handleSubmit(e) {
    e.preventDefault();    console.log('You clicked submit.');
  }

  return (
    <form onSubmit={handleSubmit}>
      <button type="submit">Submit</button>
    </form>
  );
}
```

Here, `e` is a synthetic event. React defines these synthetic events according to the [W3C spec](https://www.w3.org/TR/DOM-Level-3-Events/), so you don’t need to worry about cross-browser compatibility. React events do not work exactly the same as native events. See the [`SyntheticEvent`](/docs/events.html) reference guide to learn more.

When using React, you generally don’t need to call `addEventListener` to add listeners to a DOM element after it is created. Instead, just provide a listener when the element is initially rendered.

When you define a component using an [ES6 class](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Classes), a common pattern is for an event handler to be a method on the class. For example, this `Toggle` component renders a button that lets the user toggle between “ON” and “OFF” states:

```
class Toggle extends React.Component {
  constructor(props) {
    super(props);
    this.state = {isToggleOn: true};

    // This binding is necessary to make `this` work in the callback    this.handleClick = this.handleClick.bind(this);  }

  handleClick() {    this.setState(prevState => ({      isToggleOn: !prevState.isToggleOn    }));  }
  render() {
    return (
      <button onClick={this.handleClick}>        {this.state.isToggleOn ? 'ON' : 'OFF'}
      </button>
    );
  }
}
```

[**Try it on CodePen**](https://codepen.io/gaearon/pen/xEmzGg?editors=0010)

You have to be careful about the meaning of `this` in JSX callbacks. In JavaScript, class methods are not [bound](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_objects/Function/bind) by default. If you forget to bind `this.handleClick` and pass it to `onClick`, `this` will be `undefined` when the function is actually called.

This is not React-specific behavior; it is a part of [how functions work in JavaScript](https://www.smashingmagazine.com/2014/01/understanding-javascript-function-prototype-bind/). Generally, if you refer to a method without `()` after it, such as `onClick={this.handleClick}`, you should bind that method.

If calling `bind` annoys you, there are two ways you can get around this. You can use [public class fields syntax](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Public_class_fields#public_instance_fields) to correctly bind callbacks:

```
class LoggingButton extends React.Component {
  // This syntax ensures `this` is bound within handleClick.  handleClick = () => {    console.log('this is:', this);  };  render() {
    return (
      <button onClick={this.handleClick}>
        Click me
      </button>
    );
  }
}
```

This syntax is enabled by default in [Create React App](https://github.com/facebookincubator/create-react-app).

If you aren’t using class fields syntax, you can use an [arrow function](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions) in the callback:

```
class LoggingButton extends React.Component {
  handleClick() {
    console.log('this is:', this);
  }

  render() {
    // This syntax ensures `this` is bound within handleClick    return (      <button onClick={() => this.handleClick()}>        Click me
      </button>
    );
  }
}
```

The problem with this syntax is that a different callback is created each time the `LoggingButton` renders. In most cases, this is fine. However, if this callback is passed as a prop to lower components, those components might do an extra re-rendering. We generally recommend binding in the constructor or using the class fields syntax, to avoid this sort of performance problem.

## [](#passing-arguments-to-event-handlers)Passing Arguments to Event Handlers

Inside a loop, it is common to want to pass an extra parameter to an event handler. For example, if `id` is the row ID, either of the following would work:

```
<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>
<button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>
```

The above two lines are equivalent, and use [arrow functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions) and [`Function.prototype.bind`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Function/bind) respectively.

In both cases, the `e` argument representing the React event will be passed as a second argument after the ID. With an arrow function, we have to pass it explicitly, but with `bind` any further arguments are automatically forwarded.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/handling-events.md)

* Previous article

  [State and Lifecycle](/docs/state-and-lifecycle.html)

* Next article

  [Conditional Rendering](/docs/conditional-rendering.html)

----
url: https://legacy.reactjs.org/blog/2013/06/02/jsfiddle-integration.html
----

June 02, 2013 by [Vjeux](https://twitter.com/vjeux)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

[JSFiddle](https://jsfiddle.net) just announced support for React. This is an exciting news as it makes collaboration on snippets of code a lot easier. You can play around this **[base React JSFiddle](http://jsfiddle.net/vjeux/kb3gN/)**, fork it and share it! A [fiddle without JSX](http://jsfiddle.net/vjeux/VkebS/) is also available.

> React (by Facebook) is now available on JSFiddle. [facebook.github.io/react/](http://t.co/wNQf9JPv5u "http://facebook.github.io/react/")
>
> — JSFiddle (@jsfiddle) [June 2, 2013](https://twitter.com/jsfiddle/status/341114115781177344)

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2013-06-02-jsfiddle-integration.md)

----
url: https://react.dev/learn/separating-events-from-effects
----

```
function ChatRoom({ roomId }) {

  const [message, setMessage] = useState('');

  // ...

  function handleSendClick() {

    sendMessage(message);

  }

  // ...

  return (

    <>

      <input value={message} onChange={e => setMessage(e.target.value)} />

      <button onClick={handleSendClick}>Send</button>

    </>

  );

}
```

With an event handler, you can be sure that `sendMessage(message)` will *only* run if the user presses the button.

### Effects run whenever synchronization is needed[](#effects-run-whenever-synchronization-is-needed "Link for Effects run whenever synchronization is needed ")

Recall that you also need to keep the component connected to the chat room. Where does that code go?

The *reason* to run this code is not some particular interaction. It doesn’t matter why or how the user navigated to the chat room screen. Now that they’re looking at it and could interact with it, the component needs to stay connected to the selected chat server. Even if the chat room component was the initial screen of your app, and the user has not performed any interactions at all, you would *still* need to connect. This is why it’s an Effect:

```
function ChatRoom({ roomId }) {

  // ...

  useEffect(() => {

    const connection = createConnection(serverUrl, roomId);

    connection.connect();

    return () => {

      connection.disconnect();

    };

  }, [roomId]);

  // ...

}
```

With this code, you can be sure that there is always an active connection to the currently selected chat server, *regardless* of the specific interactions performed by the user. Whether the user has only opened your app, selected a different room, or navigated to another screen and back, your Effect ensures that the component will *remain synchronized* with the currently selected room, and will [re-connect whenever it’s necessary.](/learn/lifecycle-of-reactive-effects#why-synchronization-may-need-to-happen-more-than-once)

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useEffect } from 'react';
import { createConnection, sendMessage } from './chat.js';

const serverUrl = 'https://localhost:1234';

function ChatRoom({ roomId }) {
  const [message, setMessage] = useState('');

  useEffect(() => {
    const connection = createConnection(serverUrl, roomId);
    connection.connect();
    return () => connection.disconnect();
  }, [roomId]);

  function handleSendClick() {
    sendMessage(message);
  }

  return (
    <>
      <h1>Welcome to the {roomId} room!</h1>
      <input value={message} onChange={e => setMessage(e.target.value)} />
      <button onClick={handleSendClick}>Send</button>
    </>
  );
}

export default function App() {
  const [roomId, setRoomId] = useState('general');
  const [show, setShow] = useState(false);
  return (
    <>
      <label>
        Choose the chat room:{' '}
        <select
          value={roomId}
          onChange={e => setRoomId(e.target.value)}
        >
          <option value="general">general</option>
          <option value="travel">travel</option>
          <option value="music">music</option>
        </select>
      </label>
      <button onClick={() => setShow(!show)}>
        {show ? 'Close chat' : 'Open chat'}
      </button>
      {show && <hr />}
      {show && <ChatRoom roomId={roomId} />}
    </>
  );
}
```

## Reactive values and reactive logic[](#reactive-values-and-reactive-logic "Link for Reactive values and reactive logic ")

Intuitively, you could say that event handlers are always triggered “manually”, for example by clicking a button. Effects, on the other hand, are “automatic”: they run and re-run as often as it’s needed to stay synchronized.

There is a more precise way to think about this.

Props, state, and variables declared inside your component’s body are called reactive values. In this example, `serverUrl` is not a reactive value, but `roomId` and `message` are. They participate in the rendering data flow:

```
const serverUrl = 'https://localhost:1234';



function ChatRoom({ roomId }) {

  const [message, setMessage] = useState('');



  // ...

}
```

Reactive values like these can change due to a re-render. For example, the user may edit the `message` or choose a different `roomId` in a dropdown. Event handlers and Effects respond to changes differently:

* **Logic inside event handlers is *not reactive.*** It will not run again unless the user performs the same interaction (e.g. a click) again. Event handlers can read reactive values without “reacting” to their changes.
* **Logic inside Effects is *reactive.*** If your Effect reads a reactive value, [you have to specify it as a dependency.](/learn/lifecycle-of-reactive-effects#effects-react-to-reactive-values) Then, if a re-render causes that value to change, React will re-run your Effect’s logic with the new value.

Let’s revisit the previous example to illustrate this difference.

### Logic inside event handlers is not reactive[](#logic-inside-event-handlers-is-not-reactive "Link for Logic inside event handlers is not reactive ")

Take a look at this line of code. Should this logic be reactive or not?

```
    // ...

    sendMessage(message);

    // ...
```

From the user’s perspective, **a change to the `message` does *not* mean that they want to send a message.** It only means that the user is typing. In other words, the logic that sends a message should not be reactive. It should not run again only because the reactive value has changed. That’s why it belongs in the event handler:

```
  function handleSendClick() {

    sendMessage(message);

  }
```

Event handlers aren’t reactive, so `sendMessage(message)` will only run when the user clicks the Send button.

### Logic inside Effects is reactive[](#logic-inside-effects-is-reactive "Link for Logic inside Effects is reactive ")

Now let’s return to these lines:

```
    // ...

    const connection = createConnection(serverUrl, roomId);

    connection.connect();

    // ...
```

From the user’s perspective, **a change to the `roomId` *does* mean that they want to connect to a different room.** In other words, the logic for connecting to the room should be reactive. You *want* these lines of code to “keep up” with the reactive value, and to run again if that value is different. That’s why it belongs in an Effect:

```
  useEffect(() => {

    const connection = createConnection(serverUrl, roomId);

    connection.connect();

    return () => {

      connection.disconnect()

    };

  }, [roomId]);
```

Effects are reactive, so `createConnection(serverUrl, roomId)` and `connection.connect()` will run for every distinct value of `roomId`. Your Effect keeps the chat connection synchronized to the currently selected room.

## Extracting non-reactive logic out of Effects[](#extracting-non-reactive-logic-out-of-effects "Link for Extracting non-reactive logic out of Effects ")

Things get more tricky when you want to mix reactive logic with non-reactive logic.

For example, imagine that you want to show a notification when the user connects to the chat. You read the current theme (dark or light) from the props so that you can show the notification in the correct color:

```
function ChatRoom({ roomId, theme }) {

  useEffect(() => {

    const connection = createConnection(serverUrl, roomId);

    connection.on('connected', () => {

      showNotification('Connected!', theme);

    });

    connection.connect();

    // ...
```

However, `theme` is a reactive value (it can change as a result of re-rendering), and [every reactive value read by an Effect must be declared as its dependency.](/learn/lifecycle-of-reactive-effects#react-verifies-that-you-specified-every-reactive-value-as-a-dependency) Now you have to specify `theme` as a dependency of your Effect:

```
function ChatRoom({ roomId, theme }) {

  useEffect(() => {

    const connection = createConnection(serverUrl, roomId);

    connection.on('connected', () => {

      showNotification('Connected!', theme);

    });

    connection.connect();

    return () => {

      connection.disconnect()

    };

  }, [roomId, theme]); // ✅ All dependencies declared

  // ...
```

Play with this example and see if you can spot the problem with this user experience:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useEffect } from 'react';
import { createConnection, sendMessage } from './chat.js';
import { showNotification } from './notifications.js';

const serverUrl = 'https://localhost:1234';

function ChatRoom({ roomId, theme }) {
  useEffect(() => {
    const connection = createConnection(serverUrl, roomId);
    connection.on('connected', () => {
      showNotification('Connected!', theme);
    });
    connection.connect();
    return () => connection.disconnect();
  }, [roomId, theme]);

  return <h1>Welcome to the {roomId} room!</h1>
}

export default function App() {
  const [roomId, setRoomId] = useState('general');
  const [isDark, setIsDark] = useState(false);
  return (
    <>
      <label>
        Choose the chat room:{' '}
        <select
          value={roomId}
          onChange={e => setRoomId(e.target.value)}
        >
          <option value="general">general</option>
          <option value="travel">travel</option>
          <option value="music">music</option>
        </select>
      </label>
      <label>
        <input
          type="checkbox"
          checked={isDark}
          onChange={e => setIsDark(e.target.checked)}
        />
        Use dark theme
      </label>
      <hr />
      <ChatRoom
        roomId={roomId}
        theme={isDark ? 'dark' : 'light'}
      />
    </>
  );
}
```

When the `roomId` changes, the chat re-connects as you would expect. But since `theme` is also a dependency, the chat *also* re-connects every time you switch between the dark and the light theme. That’s not great!

In other words, you *don’t* want this line to be reactive, even though it is inside an Effect (which is reactive):

```
      // ...

      showNotification('Connected!', theme);

      // ...
```

You need a way to separate this non-reactive logic from the reactive Effect around it.

### Declaring an Effect Event[](#declaring-an-effect-event "Link for Declaring an Effect Event ")

Use a special Hook called [`useEffectEvent`](/reference/react/useEffectEvent) to extract this non-reactive logic out of your Effect:

```
import { useEffect, useEffectEvent } from 'react';



function ChatRoom({ roomId, theme }) {

  const onConnected = useEffectEvent(() => {

    showNotification('Connected!', theme);

  });

  // ...
```

Here, `onConnected` is called an *Effect Event.* It’s a part of your Effect logic, but it behaves a lot more like an event handler. The logic inside it is not reactive, and it always “sees” the latest values of your props and state.

Now you can call the `onConnected` Effect Event from inside your Effect:

```
function ChatRoom({ roomId, theme }) {

  const onConnected = useEffectEvent(() => {

    showNotification('Connected!', theme);

  });



  useEffect(() => {

    const connection = createConnection(serverUrl, roomId);

    connection.on('connected', () => {

      onConnected();

    });

    connection.connect();

    return () => connection.disconnect();

  }, [roomId]); // ✅ All dependencies declared

  // ...
```

This solves the problem. Note that you had to *remove* `theme` from the list of your Effect’s dependencies, because it’s no longer used in the Effect. You also don’t need to *add* `onConnected` to it, because **Effect Events are not reactive and must be omitted from dependencies.**

Verify that the new behavior works as you would expect:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useEffect } from 'react';
import { useEffectEvent } from 'react';
import { createConnection, sendMessage } from './chat.js';
import { showNotification } from './notifications.js';

const serverUrl = 'https://localhost:1234';

function ChatRoom({ roomId, theme }) {
  const onConnected = useEffectEvent(() => {
    showNotification('Connected!', theme);
  });

  useEffect(() => {
    const connection = createConnection(serverUrl, roomId);
    connection.on('connected', () => {
      onConnected();
    });
    connection.connect();
    return () => connection.disconnect();
  }, [roomId]);

  return <h1>Welcome to the {roomId} room!</h1>
}

export default function App() {
  const [roomId, setRoomId] = useState('general');
  const [isDark, setIsDark] = useState(false);
  return (
    <>
      <label>
        Choose the chat room:{' '}
        <select
          value={roomId}
          onChange={e => setRoomId(e.target.value)}
        >
          <option value="general">general</option>
          <option value="travel">travel</option>
          <option value="music">music</option>
        </select>
      </label>
      <label>
        <input
          type="checkbox"
          checked={isDark}
          onChange={e => setIsDark(e.target.checked)}
        />
        Use dark theme
      </label>
      <hr />
      <ChatRoom
        roomId={roomId}
        theme={isDark ? 'dark' : 'light'}
      />
    </>
  );
}
```

You can think of Effect Events as being very similar to event handlers. The main difference is that event handlers run in response to user interactions, whereas Effect Events are triggered by you from Effects. Effect Events let you “break the chain” between the reactivity of Effects and code that should not be reactive.

### Reading latest props and state with Effect Events[](#reading-latest-props-and-state-with-effect-events "Link for Reading latest props and state with Effect Events ")

Effect Events let you fix many patterns where you might be tempted to suppress the dependency linter.

For example, say you have an Effect to log the page visits:

```
function Page() {

  useEffect(() => {

    logVisit();

  }, []);

  // ...

}
```

Later, you add multiple routes to your site. Now your `Page` component receives a `url` prop with the current path. You want to pass the `url` as a part of your `logVisit` call, but the dependency linter complains:

```
function Page({ url }) {

  useEffect(() => {

    logVisit(url);

  }, []); // 🔴 React Hook useEffect has a missing dependency: 'url'

  // ...

}
```

Think about what you want the code to do. You *want* to log a separate visit for different URLs since each URL represents a different page. In other words, this `logVisit` call *should* be reactive with respect to the `url`. This is why, in this case, it makes sense to follow the dependency linter, and add `url` as a dependency:

```
function Page({ url }) {

  useEffect(() => {

    logVisit(url);

  }, [url]); // ✅ All dependencies declared

  // ...

}
```

Now let’s say you want to include the number of items in the shopping cart together with every page visit:

```
function Page({ url }) {

  const { items } = useContext(ShoppingCartContext);

  const numberOfItems = items.length;



  useEffect(() => {

    logVisit(url, numberOfItems);

  }, [url]); // 🔴 React Hook useEffect has a missing dependency: 'numberOfItems'

  // ...

}
```

You used `numberOfItems` inside the Effect, so the linter asks you to add it as a dependency. However, you *don’t* want the `logVisit` call to be reactive with respect to `numberOfItems`. If the user puts something into the shopping cart, and the `numberOfItems` changes, this *does not mean* that the user visited the page again. In other words, *visiting the page* is, in some sense, an “event”. It happens at a precise moment in time.

Split the code in two parts:

```
function Page({ url }) {

  const { items } = useContext(ShoppingCartContext);

  const numberOfItems = items.length;



  const onVisit = useEffectEvent(visitedUrl => {

    logVisit(visitedUrl, numberOfItems);

  });



  useEffect(() => {

    onVisit(url);

  }, [url]); // ✅ All dependencies declared

  // ...

}
```

Here, `onVisit` is an Effect Event. The code inside it isn’t reactive. This is why you can use `numberOfItems` (or any other reactive value!) without worrying that it will cause the surrounding code to re-execute on changes.

On the other hand, the Effect itself remains reactive. Code inside the Effect uses the `url` prop, so the Effect will re-run after every re-render with a different `url`. This, in turn, will call the `onVisit` Effect Event.

As a result, you will call `logVisit` for every change to the `url`, and always read the latest `numberOfItems`. However, if `numberOfItems` changes on its own, this will not cause any of the code to re-run.

### Note

You might be wondering if you could call `onVisit()` with no arguments, and read the `url` inside it:

```
  const onVisit = useEffectEvent(() => {

    logVisit(url, numberOfItems);

  });



  useEffect(() => {

    onVisit();

  }, [url]);
```

This would work, but it’s better to pass this `url` to the Effect Event explicitly. **By passing `url` as an argument to your Effect Event, you are saying that visiting a page with a different `url` constitutes a separate “event” from the user’s perspective.** The `visitedUrl` is a *part* of the “event” that happened:

```
  const onVisit = useEffectEvent(visitedUrl => {

    logVisit(visitedUrl, numberOfItems);

  });



  useEffect(() => {

    onVisit(url);

  }, [url]);
```

Since your Effect Event explicitly “asks” for the `visitedUrl`, now you can’t accidentally remove `url` from the Effect’s dependencies. If you remove the `url` dependency (causing distinct page visits to be counted as one), the linter will warn you about it. You want `onVisit` to be reactive with regards to the `url`, so instead of reading the `url` inside (where it wouldn’t be reactive), you pass it *from* your Effect.

This becomes especially important if there is some asynchronous logic inside the Effect:

```
  const onVisit = useEffectEvent(visitedUrl => {

    logVisit(visitedUrl, numberOfItems);

  });



  useEffect(() => {

    setTimeout(() => {

      onVisit(url);

    }, 5000); // Delay logging visits

  }, [url]);
```

Here, `url` inside `onVisit` corresponds to the *latest* `url` (which could have already changed), but `visitedUrl` corresponds to the `url` that originally caused this Effect (and this `onVisit` call) to run.

##### Deep Dive#### Is it okay to suppress the dependency linter instead?[](#is-it-okay-to-suppress-the-dependency-linter-instead "Link for Is it okay to suppress the dependency linter instead? ")

In the existing codebases, you may sometimes see the lint rule suppressed like this:

```
function Page({ url }) {

  const { items } = useContext(ShoppingCartContext);

  const numberOfItems = items.length;



  useEffect(() => {

    logVisit(url, numberOfItems);

    // 🔴 Avoid suppressing the linter like this:

    // eslint-disable-next-line react-hooks/exhaustive-deps

  }, [url]);

  // ...

}
```

We recommend **never suppressing the linter**.

The first downside of suppressing the rule is that React will no longer warn you when your Effect needs to “react” to a new reactive dependency you’ve introduced to your code. In the earlier example, you added `url` to the dependencies *because* React reminded you to do it. You will no longer get such reminders for any future edits to that Effect if you disable the linter. This leads to bugs.

Here is an example of a confusing bug caused by suppressing the linter. In this example, the `handleMove` function is supposed to read the current `canMove` state variable value in order to decide whether the dot should follow the cursor. However, `canMove` is always `true` inside `handleMove`.

Can you see why?

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useEffect } from 'react';

export default function App() {
  const [position, setPosition] = useState({ x: 0, y: 0 });
  const [canMove, setCanMove] = useState(true);

  function handleMove(e) {
    if (canMove) {
      setPosition({ x: e.clientX, y: e.clientY });
    }
  }

  useEffect(() => {
    window.addEventListener('pointermove', handleMove);
    return () => window.removeEventListener('pointermove', handleMove);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  return (
    <>
      <label>
        <input type="checkbox"
          checked={canMove}
          onChange={e => setCanMove(e.target.checked)}
        />
        The dot is allowed to move
      </label>
      <hr />
      <div style={{
        position: 'absolute',
        backgroundColor: 'pink',
        borderRadius: '50%',
        opacity: 0.6,
        transform: `translate(${position.x}px, ${position.y}px)`,
        pointerEvents: 'none',
        left: -20,
        top: -20,
        width: 40,
        height: 40,
      }} />
    </>
  );
}
```

The problem with this code is in suppressing the dependency linter. If you remove the suppression, you’ll see that this Effect should depend on the `handleMove` function. This makes sense: `handleMove` is declared inside the component body, which makes it a reactive value. Every reactive value must be specified as a dependency, or it can potentially get stale over time!

The author of the original code has “lied” to React by saying that the Effect does not depend (`[]`) on any reactive values. This is why React did not re-synchronize the Effect after `canMove` has changed (and `handleMove` with it). Because React did not re-synchronize the Effect, the `handleMove` attached as a listener is the `handleMove` function created during the initial render. During the initial render, `canMove` was `true`, which is why `handleMove` from the initial render will forever see that value.

**If you never suppress the linter, you will never see problems with stale values.**

With `useEffectEvent`, there is no need to “lie” to the linter, and the code works as you would expect:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useEffect } from 'react';
import { useEffectEvent } from 'react';

export default function App() {
  const [position, setPosition] = useState({ x: 0, y: 0 });
  const [canMove, setCanMove] = useState(true);

  const onMove = useEffectEvent(e => {
    if (canMove) {
      setPosition({ x: e.clientX, y: e.clientY });
    }
  });

  useEffect(() => {
    window.addEventListener('pointermove', onMove);
    return () => window.removeEventListener('pointermove', onMove);
  }, []);

  return (
    <>
      <label>
        <input type="checkbox"
          checked={canMove}
          onChange={e => setCanMove(e.target.checked)}
        />
        The dot is allowed to move
      </label>
      <hr />
      <div style={{
        position: 'absolute',
        backgroundColor: 'pink',
        borderRadius: '50%',
        opacity: 0.6,
        transform: `translate(${position.x}px, ${position.y}px)`,
        pointerEvents: 'none',
        left: -20,
        top: -20,
        width: 40,
        height: 40,
      }} />
    </>
  );
}
```

This doesn’t mean that `useEffectEvent` is *always* the correct solution. You should only apply it to the lines of code that you don’t want to be reactive. In the above sandbox, you didn’t want the Effect’s code to be reactive with regards to `canMove`. That’s why it made sense to extract an Effect Event.

Read [Removing Effect Dependencies](/learn/removing-effect-dependencies) for other correct alternatives to suppressing the linter.

### Limitations of Effect Events[](#limitations-of-effect-events "Link for Limitations of Effect Events ")

Effect Events are very limited in how you can use them:

* **Only call them from inside Effects.**
* **Never pass them to other components or Hooks.**

For example, don’t declare and pass an Effect Event like this:

```
function Timer() {

  const [count, setCount] = useState(0);



  const onTick = useEffectEvent(() => {

    setCount(count + 1);

  });



  useTimer(onTick, 1000); // 🔴 Avoid: Passing Effect Events



  return <h1>{count}</h1>

}



function useTimer(callback, delay) {

  useEffect(() => {

    const id = setInterval(() => {

      callback();

    }, delay);

    return () => {

      clearInterval(id);

    };

  }, [delay, callback]); // Need to specify "callback" in dependencies

}
```

Instead, always declare Effect Events directly next to the Effects that use them:

```
function Timer() {

  const [count, setCount] = useState(0);

  useTimer(() => {

    setCount(count + 1);

  }, 1000);

  return <h1>{count}</h1>

}



function useTimer(callback, delay) {

  const onTick = useEffectEvent(() => {

    callback();

  });



  useEffect(() => {

    const id = setInterval(() => {

      onTick(); // ✅ Good: Only called locally inside an Effect

    }, delay);

    return () => {

      clearInterval(id);

    };

  }, [delay]); // No need to specify "onTick" (an Effect Event) as a dependency

}
```

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useEffect } from 'react';

export default function Timer() {
  const [count, setCount] = useState(0);
  const [increment, setIncrement] = useState(1);

  useEffect(() => {
    const id = setInterval(() => {
      setCount(c => c + increment);
    }, 1000);
    return () => {
      clearInterval(id);
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  return (
    <>
      <h1>
        Counter: {count}
        <button onClick={() => setCount(0)}>Reset</button>
      </h1>
      <hr />
      <p>
        Every second, increment by:
        <button disabled={increment === 0} onClick={() => {
          setIncrement(i => i - 1);
        }}>–</button>
        <b>{increment}</b>
        <button onClick={() => {
          setIncrement(i => i + 1);
        }}>+</button>
      </p>
    </>
  );
}
```

[PreviousLifecycle of Reactive Effects](/learn/lifecycle-of-reactive-effects)

[NextRemoving Effect Dependencies](/learn/removing-effect-dependencies)

***

----
url: https://react.dev/reference/react-compiler/configuration
----

[API Reference](/reference/react)

# Configuration[](#undefined "Link for this heading")

This page lists all configuration options available in React Compiler.

### Note

For most apps, the default options should work out of the box. If you have a special need, you can use these advanced options.

```
// babel.config.js

module.exports = {

  plugins: [

    [

      'babel-plugin-react-compiler', {

        // compiler options

      }

    ]

  ]

};
```

***

## Compilation Control[](#compilation-control "Link for Compilation Control ")

These options control *what* the compiler optimizes and *how* it selects components and hooks to compile.

* [`compilationMode`](/reference/react-compiler/compilationMode) controls the strategy for selecting functions to compile (e.g., all functions, only annotated ones, or intelligent detection).

```
{

  compilationMode: 'annotation' // Only compile "use memo" functions

}
```

***

## Version Compatibility[](#version-compatibility "Link for Version Compatibility ")

React version configuration ensures the compiler generates code compatible with your React version.

[`target`](/reference/react-compiler/target) specifies which React version you’re using (17, 18, or 19).

```
// For React 18 projects

{

  target: '18' // Also requires react-compiler-runtime package

}
```

***

## Error Handling[](#error-handling "Link for Error Handling ")

These options control how the compiler responds to code that doesn’t follow the [Rules of React](/reference/rules).

[`panicThreshold`](/reference/react-compiler/panicThreshold) determines whether to fail the build or skip problematic components.

```
// Recommended for production

{

  panicThreshold: 'none' // Skip components with errors instead of failing the build

}
```

***

## Debugging[](#debugging "Link for Debugging ")

Logging and analysis options help you understand what the compiler is doing.

[`logger`](/reference/react-compiler/logger) provides custom logging for compilation events.

```
{

  logger: {

    logEvent(filename, event) {

      if (event.kind === 'CompileSuccess') {

        console.log('Compiled:', filename);

      }

    }

  }

}
```

***

## Feature Flags[](#feature-flags "Link for Feature Flags ")

Conditional compilation lets you control when optimized code is used.

[`gating`](/reference/react-compiler/gating) enables runtime feature flags for A/B testing or gradual rollouts.

```
{

  gating: {

    source: 'my-feature-flags',

    importSpecifierName: 'isCompilerEnabled'

  }

}
```

***

## Common Configuration Patterns[](#common-patterns "Link for Common Configuration Patterns ")

### Default configuration[](#default-configuration "Link for Default configuration ")

For most React 19 applications, the compiler works without configuration:

```
// babel.config.js

module.exports = {

  plugins: [

    'babel-plugin-react-compiler'

  ]

};
```

### React 17/18 projects[](#react-17-18 "Link for React 17/18 projects ")

Older React versions need the runtime package and target configuration:

```
npm install react-compiler-runtime@latest
```

```
{

  target: '18' // or '17'

}
```

### Incremental adoption[](#incremental-adoption "Link for Incremental adoption ")

Start with specific directories and expand gradually:

```
{

  compilationMode: 'annotation' // Only compile "use memo" functions

}
```

[NextcompilationMode](/reference/react-compiler/compilationMode)

***

----
url: https://react.dev/reference/react/legacy
----

[API Reference](/reference/react)

# Legacy React APIs[](#undefined "Link for this heading")

These APIs are exported from the `react` package, but they are not recommended for use in newly written code. See the linked individual API pages for the suggested alternatives.

***

## Legacy APIs[](#legacy-apis "Link for Legacy APIs ")

* [`Children`](/reference/react/Children) lets you manipulate and transform the JSX received as the `children` prop. [See alternatives.](/reference/react/Children#alternatives)
* [`cloneElement`](/reference/react/cloneElement) lets you create a React element using another element as a starting point. [See alternatives.](/reference/react/cloneElement#alternatives)
* [`Component`](/reference/react/Component) lets you define a React component as a JavaScript class. [See alternatives.](/reference/react/Component#alternatives)
* [`createElement`](/reference/react/createElement) lets you create a React element. Typically, you’ll use JSX instead.
* [`createRef`](/reference/react/createRef) creates a ref object which can contain arbitrary value. [See alternatives.](/reference/react/createRef#alternatives)
* [`forwardRef`](/reference/react/forwardRef) lets your component expose a DOM node to parent component with a [ref.](/learn/manipulating-the-dom-with-refs)
* [`isValidElement`](/reference/react/isValidElement) checks whether a value is a React element. Typically used with [`cloneElement`.](/reference/react/cloneElement)
* [`PureComponent`](/reference/react/PureComponent) is similar to [`Component`,](/reference/react/Component) but it skip re-renders with same props. [See alternatives.](/reference/react/PureComponent#alternatives)

***

## Removed APIs[](#removed-apis "Link for Removed APIs ")

These APIs were removed in React 19:

* [`createFactory`](https://18.react.dev/reference/react/createFactory): use JSX instead.
* Class Components: [`static contextTypes`](https://18.react.dev//reference/react/Component#static-contexttypes): use [`static contextType`](#static-contexttype) instead.
* Class Components: [`static childContextTypes`](https://18.react.dev//reference/react/Component#static-childcontexttypes): use [`static contextType`](#static-contexttype) instead.
* Class Components: [`static getChildContext`](https://18.react.dev//reference/react/Component#getchildcontext): use [`Context`](/reference/react/createContext#provider) instead.
* Class Components: [`static propTypes`](https://18.react.dev//reference/react/Component#static-proptypes): use a type system like [TypeScript](https://www.typescriptlang.org/) instead.
* Class Components: [`this.refs`](https://18.react.dev//reference/react/Component#refs): use [`createRef`](/reference/react/createRef) instead.

[NextChildren](/reference/react/Children)

***

----
url: https://18.react.dev/reference/react/hooks
----

[API Reference](/reference/react)

# Built-in React Hooks[](#undefined "Link for this heading")

*Hooks* let you use different React features from your components. You can either use the built-in Hooks or combine them to build your own. This page lists all built-in Hooks in React.

***

## State Hooks[](#state-hooks "Link for State Hooks ")

*State* lets a component [“remember” information like user input.](/learn/state-a-components-memory) For example, a form component can use state to store the input value, while an image gallery component can use state to store the selected image index.

To add state to a component, use one of these Hooks:

* [`useState`](/reference/react/useState) declares a state variable that you can update directly.
* [`useReducer`](/reference/react/useReducer) declares a state variable with the update logic inside a [reducer function.](/learn/extracting-state-logic-into-a-reducer)

```
function ImageGallery() {

  const [index, setIndex] = useState(0);

  // ...
```

***

## Context Hooks[](#context-hooks "Link for Context Hooks ")

*Context* lets a component [receive information from distant parents without passing it as props.](/learn/passing-props-to-a-component) For example, your app’s top-level component can pass the current UI theme to all components below, no matter how deep.

* [`useContext`](/reference/react/useContext) reads and subscribes to a context.

```
function Button() {

  const theme = useContext(ThemeContext);

  // ...
```

***

## Ref Hooks[](#ref-hooks "Link for Ref Hooks ")

*Refs* let a component [hold some information that isn’t used for rendering,](/learn/referencing-values-with-refs) like a DOM node or a timeout ID. Unlike with state, updating a ref does not re-render your component. Refs are an “escape hatch” from the React paradigm. They are useful when you need to work with non-React systems, such as the built-in browser APIs.

* [`useRef`](/reference/react/useRef) declares a ref. You can hold any value in it, but most often it’s used to hold a DOM node.
* [`useImperativeHandle`](/reference/react/useImperativeHandle) lets you customize the ref exposed by your component. This is rarely used.

```
function Form() {

  const inputRef = useRef(null);

  // ...
```

***

## Effect Hooks[](#effect-hooks "Link for Effect Hooks ")

*Effects* let a component [connect to and synchronize with external systems.](/learn/synchronizing-with-effects) This includes dealing with network, browser DOM, animations, widgets written using a different UI library, and other non-React code.

* [`useEffect`](/reference/react/useEffect) connects a component to an external system.

```
function ChatRoom({ roomId }) {

  useEffect(() => {

    const connection = createConnection(roomId);

    connection.connect();

    return () => connection.disconnect();

  }, [roomId]);

  // ...
```

Effects are an “escape hatch” from the React paradigm. Don’t use Effects to orchestrate the data flow of your application. If you’re not interacting with an external system, [you might not need an Effect.](/learn/you-might-not-need-an-effect)

There are two rarely used variations of `useEffect` with differences in timing:

* [`useLayoutEffect`](/reference/react/useLayoutEffect) fires before the browser repaints the screen. You can measure layout here.
* [`useInsertionEffect`](/reference/react/useInsertionEffect) fires before React makes changes to the DOM. Libraries can insert dynamic CSS here.

***

## Performance Hooks[](#performance-hooks "Link for Performance Hooks ")

A common way to optimize re-rendering performance is to skip unnecessary work. For example, you can tell React to reuse a cached calculation or to skip a re-render if the data has not changed since the previous render.

To skip calculations and unnecessary re-rendering, use one of these Hooks:

* [`useMemo`](/reference/react/useMemo) lets you cache the result of an expensive calculation.
* [`useCallback`](/reference/react/useCallback) lets you cache a function definition before passing it down to an optimized component.

```
function TodoList({ todos, tab, theme }) {

  const visibleTodos = useMemo(() => filterTodos(todos, tab), [todos, tab]);

  // ...

}
```

Sometimes, you can’t skip re-rendering because the screen actually needs to update. In that case, you can improve performance by separating blocking updates that must be synchronous (like typing into an input) from non-blocking updates which don’t need to block the user interface (like updating a chart).

To prioritize rendering, use one of these Hooks:

* [`useTransition`](/reference/react/useTransition) lets you mark a state transition as non-blocking and allow other updates to interrupt it.
* [`useDeferredValue`](/reference/react/useDeferredValue) lets you defer updating a non-critical part of the UI and let other parts update first.

***

## Other Hooks[](#other-hooks "Link for Other Hooks ")

These Hooks are mostly useful to library authors and aren’t commonly used in the application code.

* [`useDebugValue`](/reference/react/useDebugValue) lets you customize the label React DevTools displays for your custom Hook.
* [`useId`](/reference/react/useId) lets a component associate a unique ID with itself. Typically used with accessibility APIs.
* [`useSyncExternalStore`](/reference/react/useSyncExternalStore) lets a component subscribe to an external store.

- [`useActionState`](/reference/react/useActionState) allows you to manage state of actions.

***

## Your own Hooks[](#your-own-hooks "Link for Your own Hooks ")

You can also [define your own custom Hooks](/learn/reusing-logic-with-custom-hooks#extracting-your-own-custom-hook-from-a-component) as JavaScript functions.

[PreviousOverview](/reference/react)

[NextuseActionState](/reference/react/useActionState)

***

----
url: https://legacy.reactjs.org/blog/2013/08/26/community-roundup-7.html
----

August 26, 2013 by [Vjeux](https://twitter.com/vjeux)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

It’s been three months since we open sourced React and it is going well. Some stats so far:

* 114 285 unique visitors on this website
* [1933 stars](https://github.com/facebook/react/stargazers) and [210 forks](https://github.com/facebook/react/network/members)
* [226 posts on Google Group](https://groups.google.com/forum/#!forum/reactjs)
* [76 GitHub projects using React](https://gist.github.com/vjeux/6335762)
* [30 contributors](https://github.com/facebook/react/graphs/contributors)
* [15 blog posts](/blog/)
* 2 early adopters: [Khan Academy](http://sophiebits.com/2013/06/09/using-react-to-speed-up-khan-academy.html) and [Propeller](http://usepropeller.com/blog/posts/from-backbone-to-react/)

## [](#wolfenstein-rendering-engine-ported-to-react)Wolfenstein Rendering Engine Ported to React

[Pete Hunt](http://www.petehunt.net/) ported the render code of the web version of Wolfenstein 3D to React. Check out [the demo](http://www.petehunt.net/wolfenstein3D-react/wolf3d.html) and [render.js](https://github.com/petehunt/wolfenstein3D-react/blob/master/js/renderer.js#L183) file for the implementation.

[](http://www.petehunt.net/wolfenstein3D-react/wolf3d.html)

## [](#react--meteor)React & Meteor

[Ben Newman](https://twitter.com/benjamn) made a [13-lines wrapper](https://github.com/benjamn/meteor-react/blob/master/lib/mixin.js) to use React and Meteor together. [Meteor](http://www.meteor.com/) handles the real-time data synchronization between client and server. React provides the declarative way to write the interface and only updates the parts of the UI that changed.

> This repository defines a Meteor package that automatically integrates the React rendering framework on both the client and the server, to complement or replace the default Handlebars templating system.
>
> The React core is officially agnostic about how you fetch and update your data, so it is far from obvious which approach is the best. This package provides one answer to that question (use Meteor!), and I hope you will find it a compelling combination.
>
> ```
> var MyComponent = React.createClass({
>  mixins: [MeteorMixin],
>
>  getMeteorState: function() {
>    return { foo: Session.get('foo') };
>  },
>
>  render: function() {
>    return <div>{this.state.foo}</div>;
>  }
> });
> ```
>
> Dependencies will be registered for any data accesses performed by getMeteorState so that the component can be automatically re-rendered whenever the data changes.
>
> [Read more …](https://github.com/benjamn/meteor-react)

## [](#react-page)React Page

[Jordan Walke](https://github.com/jordwalke) implemented a complete React project creator called [react-page](https://github.com/facebook/react-page/). It supports both server-side and client-side rendering, source transform and packaging JSX files using CommonJS modules, and instant reload.

> Easy Application Development with React JavaScript
>
> [](https://github.com/facebook/react-page/)
>
> **Why Server Rendering?**
>
> * Faster initial page speed:
>
>   * Markup displayed before downloading large JavaScript.
>   * Markup can be generated more quickly on a fast server than low power client devices.
>
> * Faster Development and Prototyping:
>
>   * Instantly refresh your app without waiting for any watch scripts or bundlers.
>
> * Easy deployment of static content pages/blogs: just archive using recursive wget.
>
> * SEO benefits of indexability and perf.
>
> **How Does Server Rendering Work?**
>
> * `react-page` computes page markup on the server, sends it to the client so the user can see it quickly.
> * The corresponding JavaScript is then packaged and sent.
> * The browser runs that JavaScript, so that all of the event handlers, interactions and update code will run seamlessly on top of the server generated markup.
> * From the developer’s (and the user’s) perspective, it’s just as if the rendering occurred on the client, only faster.
>
> [Try it out …](https://github.com/facebook/react-page/)

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2013-08-26-community-roundup-7.md)

----
url: https://react.dev/learn/conditional-rendering
----


[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
function Item({ name, isPacked }) {
  return <li className="item">{name}</li>;
}

export default function PackingList() {
  return (
    <section>
      <h1>Sally Ride's Packing List</h1>
      <ul>
        <Item
          isPacked={true}
          name="Space suit"
        />
        <Item
          isPacked={true}
          name="Helmet with a golden leaf"
        />
        <Item
          isPacked={false}
          name="Photo of Tam"
        />
      </ul>
    </section>
  );
}
```

Notice that some of the `Item` components have their `isPacked` prop set to `true` instead of `false`. You want to add a checkmark (✅) to packed items if `isPacked={true}`.

You can write this as an [`if`/`else` statement](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/if...else) like so:

```
if (isPacked) {

  return <li className="item">{name} ✅</li>;

}

return <li className="item">{name}</li>;
```

If the `isPacked` prop is `true`, this code **returns a different JSX tree.** With this change, some of the items get a checkmark at the end:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
function Item({ name, isPacked }) {
  if (isPacked) {
    return <li className="item">{name} ✅</li>;
  }
  return <li className="item">{name}</li>;
}

export default function PackingList() {
  return (
    <section>
      <h1>Sally Ride's Packing List</h1>
      <ul>
        <Item
          isPacked={true}
          name="Space suit"
        />
        <Item
          isPacked={true}
          name="Helmet with a golden leaf"
        />
        <Item
          isPacked={false}
          name="Photo of Tam"
        />
      </ul>
    </section>
  );
}
```

Try editing what gets returned in either case, and see how the result changes!

Notice how you’re creating branching logic with JavaScript’s `if` and `return` statements. In React, control flow (like conditions) is handled by JavaScript.

### Conditionally returning nothing with `null`[](#conditionally-returning-nothing-with-null "Link for this heading")

In some situations, you won’t want to render anything at all. For example, say you don’t want to show packed items at all. A component must return something. In this case, you can return `null`:

```
if (isPacked) {

  return null;

}

return <li className="item">{name}</li>;
```

If `isPacked` is true, the component will return nothing, `null`. Otherwise, it will return JSX to render.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
function Item({ name, isPacked }) {
  if (isPacked) {
    return null;
  }
  return <li className="item">{name}</li>;
}

export default function PackingList() {
  return (
    <section>
      <h1>Sally Ride's Packing List</h1>
      <ul>
        <Item
          isPacked={true}
          name="Space suit"
        />
        <Item
          isPacked={true}
          name="Helmet with a golden leaf"
        />
        <Item
          isPacked={false}
          name="Photo of Tam"
        />
      </ul>
    </section>
  );
}
```

In practice, returning `null` from a component isn’t common because it might surprise a developer trying to render it. More often, you would conditionally include or exclude the component in the parent component’s JSX. Here’s how to do that!

## Conditionally including JSX[](#conditionally-including-jsx "Link for Conditionally including JSX ")

In the previous example, you controlled which (if any!) JSX tree would be returned by the component. You may already have noticed some duplication in the render output:

```
<li className="item">{name} ✅</li>
```

is very similar to

```
<li className="item">{name}</li>
```

Both of the conditional branches return `<li className="item">...</li>`:

```
if (isPacked) {

  return <li className="item">{name} ✅</li>;

}

return <li className="item">{name}</li>;
```

While this duplication isn’t harmful, it could make your code harder to maintain. What if you want to change the `className`? You’d have to do it in two places in your code! In such a situation, you could conditionally include a little JSX to make your code more [DRY.](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself)

### Conditional (ternary) operator (`? :`)[](#conditional-ternary-operator-- "Link for this heading")

JavaScript has a compact syntax for writing a conditional expression — the [conditional operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator) or “ternary operator”.

Instead of this:

```
if (isPacked) {

  return <li className="item">{name} ✅</li>;

}

return <li className="item">{name}</li>;
```

You can write this:

```
return (

  <li className="item">

    {isPacked ? name + ' ✅' : name}

  </li>

);
```

You can read it as *“if `isPacked` is true, then (`?`) render `name + ' ✅'`, otherwise (`:`) render `name`”*.

##### Deep Dive#### Are these two examples fully equivalent?[](#are-these-two-examples-fully-equivalent "Link for Are these two examples fully equivalent? ")

If you’re coming from an object-oriented programming background, you might assume that the two examples above are subtly different because one of them may create two different “instances” of `<li>`. But JSX elements aren’t “instances” because they don’t hold any internal state and aren’t real DOM nodes. They’re lightweight descriptions, like blueprints. So these two examples, in fact, *are* completely equivalent. [Preserving and Resetting State](/learn/preserving-and-resetting-state) goes into detail about how this works.

Now let’s say you want to wrap the completed item’s text into another HTML tag, like `<del>` to strike it out. You can add even more newlines and parentheses so that it’s easier to nest more JSX in each of the cases:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
function Item({ name, isPacked }) {
  return (
    <li className="item">
      {isPacked ? (
        <del>
          {name + ' ✅'}
        </del>
      ) : (
        name
      )}
    </li>
  );
}

export default function PackingList() {
  return (
    <section>
      <h1>Sally Ride's Packing List</h1>
      <ul>
        <Item
          isPacked={true}
          name="Space suit"
        />
        <Item
          isPacked={true}
          name="Helmet with a golden leaf"
        />
        <Item
          isPacked={false}
          name="Photo of Tam"
        />
      </ul>
    </section>
  );
}
```

This style works well for simple conditions, but use it in moderation. If your components get messy with too much nested conditional markup, consider extracting child components to clean things up. In React, markup is a part of your code, so you can use tools like variables and functions to tidy up complex expressions.

### Logical AND operator (`&&`)[](#logical-and-operator- "Link for this heading")

Another common shortcut you’ll encounter is the [JavaScript logical AND (`&&`) operator.](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_AND#:~:text=The%20logical%20AND%20\(%20%26%26%20\)%20operator,it%20returns%20a%20Boolean%20value.) Inside React components, it often comes up when you want to render some JSX when the condition is true, **or render nothing otherwise.** With `&&`, you could conditionally render the checkmark only if `isPacked` is `true`:

```
return (

  <li className="item">

    {name} {isPacked && '✅'}

  </li>

);
```

You can read this as *“if `isPacked`, then (`&&`) render the checkmark, otherwise, render nothing”*.

Here it is in action:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
function Item({ name, isPacked }) {
  return (
    <li className="item">
      {name} {isPacked && '✅'}
    </li>
  );
}

export default function PackingList() {
  return (
    <section>
      <h1>Sally Ride's Packing List</h1>
      <ul>
        <Item
          isPacked={true}
          name="Space suit"
        />
        <Item
          isPacked={true}
          name="Helmet with a golden leaf"
        />
        <Item
          isPacked={false}
          name="Photo of Tam"
        />
      </ul>
    </section>
  );
}
```

```
let itemContent = name;
```

Use an `if` statement to reassign a JSX expression to `itemContent` if `isPacked` is `true`:

```
if (isPacked) {

  itemContent = name + " ✅";

}
```

[Curly braces open the “window into JavaScript”.](/learn/javascript-in-jsx-with-curly-braces#using-curly-braces-a-window-into-the-javascript-world) Embed the variable with curly braces in the returned JSX tree, nesting the previously calculated expression inside of JSX:

```
<li className="item">

  {itemContent}

</li>
```

This style is the most verbose, but it’s also the most flexible. Here it is in action:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
function Item({ name, isPacked }) {
  let itemContent = name;
  if (isPacked) {
    itemContent = name + " ✅";
  }
  return (
    <li className="item">
      {itemContent}
    </li>
  );
}

export default function PackingList() {
  return (
    <section>
      <h1>Sally Ride's Packing List</h1>
      <ul>
        <Item
          isPacked={true}
          name="Space suit"
        />
        <Item
          isPacked={true}
          name="Helmet with a golden leaf"
        />
        <Item
          isPacked={false}
          name="Photo of Tam"
        />
      </ul>
    </section>
  );
}
```

Like before, this works not only for text, but for arbitrary JSX too:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
function Item({ name, isPacked }) {
  let itemContent = name;
  if (isPacked) {
    itemContent = (
      <del>
        {name + " ✅"}
      </del>
    );
  }
  return (
    <li className="item">
      {itemContent}
    </li>
  );
}

export default function PackingList() {
  return (
    <section>
      <h1>Sally Ride's Packing List</h1>
      <ul>
        <Item
          isPacked={true}
          name="Space suit"
        />
        <Item
          isPacked={true}
          name="Helmet with a golden leaf"
        />
        <Item
          isPacked={false}
          name="Photo of Tam"
        />
      </ul>
    </section>
  );
}
```

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
function Item({ name, isPacked }) {
  return (
    <li className="item">
      {name} {isPacked && '✅'}
    </li>
  );
}

export default function PackingList() {
  return (
    <section>
      <h1>Sally Ride's Packing List</h1>
      <ul>
        <Item
          isPacked={true}
          name="Space suit"
        />
        <Item
          isPacked={true}
          name="Helmet with a golden leaf"
        />
        <Item
          isPacked={false}
          name="Photo of Tam"
        />
      </ul>
    </section>
  );
}
```

[PreviousPassing Props to a Component](/learn/passing-props-to-a-component)

[NextRendering Lists](/learn/rendering-lists)

***

----
url: https://react.dev/learn/javascript-in-jsx-with-curly-braces
----

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
export default function Avatar() {
  return (
    <img
      className="avatar"
      src="https://react.dev/images/docs/scientists/7vQD0fPs.jpg"
      alt="Gregorio Y. Zara"
    />
  );
}
```

Here, `"https://react.dev/images/docs/scientists/7vQD0fPs.jpg"` and `"Gregorio Y. Zara"` are being passed as strings.

But what if you want to dynamically specify the `src` or `alt` text? You could **use a value from JavaScript by replacing `"` and `"` with `{` and `}`**:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
export default function Avatar() {
  const avatar = 'https://react.dev/images/docs/scientists/7vQD0fPs.jpg';
  const description = 'Gregorio Y. Zara';
  return (
    <img
      className="avatar"
      src={avatar}
      alt={description}
    />
  );
}
```

Notice the difference between `className="avatar"`, which specifies an `"avatar"` CSS class name that makes the image round, and `src={avatar}` that reads the value of the JavaScript variable called `avatar`. That’s because curly braces let you work with JavaScript right there in your markup!

## Using curly braces: A window into the JavaScript world[](#using-curly-braces-a-window-into-the-javascript-world "Link for Using curly braces: A window into the JavaScript world ")

JSX is a special way of writing JavaScript. That means it’s possible to use JavaScript inside it—with curly braces `{ }`. The example below first declares a name for the scientist, `name`, then embeds it with curly braces inside the `<h1>`:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
export default function TodoList() {
  const name = 'Gregorio Y. Zara';
  return (
    <h1>{name}'s To Do List</h1>
  );
}
```

Try changing the `name`’s value from `'Gregorio Y. Zara'` to `'Hedy Lamarr'`. See how the list title changes?

Any JavaScript expression will work between curly braces, including function calls like `formatDate()`:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
const today = new Date();

function formatDate(date) {
  return new Intl.DateTimeFormat(
    'en-US',
    { weekday: 'long' }
  ).format(date);
}

export default function TodoList() {
  return (
    <h1>To Do List for {formatDate(today)}</h1>
  );
}
```

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
export default function TodoList() {
  return (
    <ul style={{
      backgroundColor: 'black',
      color: 'pink'
    }}>
      <li>Improve the videophone</li>
      <li>Prepare aeronautics lectures</li>
      <li>Work on the alcohol-fuelled engine</li>
    </ul>
  );
}
```

Try changing the values of `backgroundColor` and `color`.

You can really see the JavaScript object inside the curly braces when you write it like this:

```
<ul style={

  {

    backgroundColor: 'black',

    color: 'pink'

  }

}>
```

The next time you see `{{` and `}}` in JSX, know that it’s nothing more than an object inside the JSX curlies!

### Pitfall

Inline `style` properties are written in camelCase. For example, HTML `<ul style="background-color: black">` would be written as `<ul style={{ backgroundColor: 'black' }}>` in your component.

## More fun with JavaScript objects and curly braces[](#more-fun-with-javascript-objects-and-curly-braces "Link for More fun with JavaScript objects and curly braces ")

You can move several expressions into one object, and reference them in your JSX inside curly braces:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
const person = {
  name: 'Gregorio Y. Zara',
  theme: {
    backgroundColor: 'black',
    color: 'pink'
  }
};

export default function TodoList() {
  return (
    <div style={person.theme}>
      <h1>{person.name}'s Todos</h1>
      <img
        className="avatar"
        src="https://react.dev/images/docs/scientists/7vQD0fPs.jpg"
        alt="Gregorio Y. Zara"
      />
      <ul>
        <li>Improve the videophone</li>
        <li>Prepare aeronautics lectures</li>
        <li>Work on the alcohol-fuelled engine</li>
      </ul>
    </div>
  );
}
```

In this example, the `person` JavaScript object contains a `name` string and a `theme` object:

```
const person = {

  name: 'Gregorio Y. Zara',

  theme: {

    backgroundColor: 'black',

    color: 'pink'

  }

};
```

The component can use these values from `person` like so:

```
<div style={person.theme}>

  <h1>{person.name}'s Todos</h1>
```

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
const person = {
  name: 'Gregorio Y. Zara',
  theme: {
    backgroundColor: 'black',
    color: 'pink'
  }
};

export default function TodoList() {
  return (
    <div style={person.theme}>
      <h1>{person}'s Todos</h1>
      <img
        className="avatar"
        src="https://react.dev/images/docs/scientists/7vQD0fPs.jpg"
        alt="Gregorio Y. Zara"
      />
      <ul>
        <li>Improve the videophone</li>
        <li>Prepare aeronautics lectures</li>
        <li>Work on the alcohol-fuelled engine</li>
      </ul>
    </div>
  );
}
```

Can you find the problem?

[PreviousWriting Markup with JSX](/learn/writing-markup-with-jsx)

[NextPassing Props to a Component](/learn/passing-props-to-a-component)

***

----
url: https://react.dev/reference/react/createElement
----

[API Reference](/reference/react)

[Legacy React APIs](/reference/react/legacy)

# createElement[](#undefined "Link for this heading")

`createElement` lets you create a React element. It serves as an alternative to writing [JSX.](/learn/writing-markup-with-jsx)

```
const element = createElement(type, props, ...children)
```

* [Reference](#reference)
  * [`createElement(type, props, ...children)`](#createelement)
* [Usage](#usage)
  * [Creating an element without JSX](#creating-an-element-without-jsx)

***

## Reference[](#reference "Link for Reference ")

### `createElement(type, props, ...children)`[](#createelement "Link for this heading")

Call `createElement` to create a React element with the given `type`, `props`, and `children`.

```
import { createElement } from 'react';



function Greeting({ name }) {

  return createElement(

    'h1',

    { className: 'greeting' },

    'Hello'

  );

}
```

* `props`: The `props` you have passed except for `ref` and `key`.

***

## Usage[](#usage "Link for Usage ")

### Creating an element without JSX[](#creating-an-element-without-jsx "Link for Creating an element without JSX ")

If you don’t like [JSX](/learn/writing-markup-with-jsx) or can’t use it in your project, you can use `createElement` as an alternative.

To create an element without JSX, call `createElement` with some type, props, and children:

```
import { createElement } from 'react';



function Greeting({ name }) {

  return createElement(

    'h1',

    { className: 'greeting' },

    'Hello ',

    createElement('i', null, name),

    '. Welcome!'

  );

}
```

The children are optional, and you can pass as many as you need (the example above has three children). This code will display a `<h1>` header with a greeting. For comparison, here is the same example rewritten with JSX:

```
function Greeting({ name }) {

  return (

    <h1 className="greeting">

      Hello <i>{name}</i>. Welcome!

    </h1>

  );

}
```

To render your own React component, pass a function like `Greeting` as the type instead of a string like `'h1'`:

```
export default function App() {

  return createElement(Greeting, { name: 'Taylor' });

}
```

With JSX, it would look like this:

```
export default function App() {

  return <Greeting name="Taylor" />;

}
```

Here is a complete example written with `createElement`:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { createElement } from 'react';

function Greeting({ name }) {
  return createElement(
    'h1',
    { className: 'greeting' },
    'Hello ',
    createElement('i', null, name),
    '. Welcome!'
  );
}

export default function App() {
  return createElement(
    Greeting,
    { name: 'Taylor' }
  );
}
```

And here is the same example written using JSX:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
function Greeting({ name }) {
  return (
    <h1 className="greeting">
      Hello <i>{name}</i>. Welcome!
    </h1>
  );
}

export default function App() {
  return <Greeting name="Taylor" />;
}
```

Both coding styles are fine, so you can use whichever one you prefer for your project. The main benefit of using JSX compared to `createElement` is that it’s easy to see which closing tag corresponds to which opening tag.

##### Deep Dive#### What is a React element, exactly?[](#what-is-a-react-element-exactly "Link for What is a React element, exactly? ")

An element is a lightweight description of a piece of the user interface. For example, both `<Greeting name="Taylor" />` and `createElement(Greeting, { name: 'Taylor' })` produce an object like this:

```
// Slightly simplified

{

  type: Greeting,

  props: {

    name: 'Taylor'

  },

  key: null,

  ref: null,

}
```

**Note that creating this object does not render the `Greeting` component or create any DOM elements.**

A React element is more like a description—an instruction for React to later render the `Greeting` component. By returning this object from your `App` component, you tell React what to do next.

Creating elements is extremely cheap so you don’t need to try to optimize or avoid it.

[PreviousComponent](/reference/react/Component)

[NextcreateRef](/reference/react/createRef)

***

----
url: https://18.react.dev/reference/react/useEffect
----

[API Reference](/reference/react)

[Hooks](/reference/react/hooks)

# useEffect[](#undefined "Link for this heading")

`useEffect` is a React Hook that lets you [synchronize a component with an external system.](/learn/synchronizing-with-effects)

```
useEffect(setup, dependencies?)
```

***

## Reference[](#reference "Link for Reference ")

### `useEffect(setup, dependencies?)`[](#useeffect "Link for this heading")

Call `useEffect` at the top level of your component to declare an Effect:

```
import { 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]);

  // ...

}
```

[See more examples below.](#usage)

#### Parameters[](#parameters "Link for Parameters ")

* `setup`: The function with your Effect’s logic. Your setup function may also optionally return a *cleanup* function. When your component is added to the DOM, React will run your setup function. After every re-render with changed dependencies, React will first run the cleanup function (if you provided it) with the old values, and then run your setup function with the new values. After your component is removed from the DOM, React will run your cleanup function.

* **optional** `dependencies`: The list of all reactive values referenced inside of the `setup` code. Reactive values include props, state, and all the variables and functions declared directly inside your component body. If your linter is [configured for React](/learn/editor-setup#linting), it will verify that every reactive value is correctly specified as a dependency. The list of dependencies must have a constant number of items and be written inline like `[dep1, dep2, dep3]`. React will compare each dependency with its previous value using the [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) comparison. If you omit this argument, your Effect will re-run after every re-render of the component. [See the difference between passing an array of dependencies, an empty array, and no dependencies at all.](#examples-dependencies)

***

## Usage[](#usage "Link for Usage ")

### Connecting to an external system[](#connecting-to-an-external-system "Link for Connecting to an external system ")

Some components need to stay connected to the network, some browser API, or a third-party library, while they are displayed on the page. These systems aren’t controlled by React, so they are called *external.*

To [connect your component to some external system,](/learn/synchronizing-with-effects) call `useEffect` at the top level of your component:

```
import { 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]);

  // ...

}
```

You need to pass two arguments to `useEffect`:

1. A *setup function* with setup code that connects to that system.
   * It should return a *cleanup function* with cleanup code that disconnects from that system.
2. A list of dependencies including every value from your component used inside of those functions.

**React calls your setup and cleanup functions whenever it’s necessary, which may happen multiple times:**

1. Your setup code runs when your component is added to the page *(mounts)*.

2. After every re-render of your component where the dependencies have changed:

   * First, your cleanup code runs with the old props and state.
   * Then, your setup code runs with the new props and state.

3. Your cleanup code runs one final time after your component is removed from the page *(unmounts).*

**Let’s illustrate this sequence for the example above.**

When the `ChatRoom` component above gets added to the page, it will connect to the chat room with the initial `serverUrl` and `roomId`. If either `serverUrl` or `roomId` change as a result of a re-render (say, if the user picks a different chat room in a dropdown), your Effect will *disconnect from the previous room, and connect to the next one.* When the `ChatRoom` component is removed from the page, your Effect will disconnect one last time.

```
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();
    };
  }, [roomId, serverUrl]);

  return (
    <>
      <label>
        Server URL:{' '}
        <input
          value={serverUrl}
          onChange={e => setServerUrl(e.target.value)}
        />
      </label>
      <h1>Welcome to the {roomId} room!</h1>
    </>
  );
}

export default function App() {
  const [roomId, setRoomId] = useState('general');
  const [show, setShow] = useState(false);
  return (
    <>
      <label>
        Choose the chat room:{' '}
        <select
          value={roomId}
          onChange={e => setRoomId(e.target.value)}
        >
          <option value="general">general</option>
          <option value="travel">travel</option>
          <option value="music">music</option>
        </select>
      </label>
      <button onClick={() => setShow(!show)}>
        {show ? 'Close chat' : 'Open chat'}
      </button>
      {show && <hr />}
      {show && <ChatRoom roomId={roomId} />}
    </>
  );
}
```

***

### Wrapping Effects in custom Hooks[](#wrapping-effects-in-custom-hooks "Link for Wrapping Effects in custom Hooks ")

Effects are an [“escape hatch”:](/learn/escape-hatches) you use them when you need to “step outside React” and when there is no better built-in solution for your use case. If you find yourself often needing to manually write Effects, it’s usually a sign that you need to extract some [custom Hooks](/learn/reusing-logic-with-custom-hooks) for common behaviors your components rely on.

For example, this `useChatRoom` custom Hook “hides” the logic of your Effect behind a more declarative API:

```
function useChatRoom({ serverUrl, roomId }) {

  useEffect(() => {

    const options = {

      serverUrl: serverUrl,

      roomId: roomId

    };

    const connection = createConnection(options);

    connection.connect();

    return () => connection.disconnect();

  }, [roomId, serverUrl]);

}
```

Then you can use it from any component like this:

```
function ChatRoom({ roomId }) {

  const [serverUrl, setServerUrl] = useState('https://localhost:1234');



  useChatRoom({

    roomId: roomId,

    serverUrl: serverUrl

  });

  // ...
```

There are also many excellent custom Hooks for every purpose available in the React ecosystem.

[Learn more about wrapping Effects in custom Hooks.](/learn/reusing-logic-with-custom-hooks)

#### Examples of wrapping Effects in custom Hooks[](#examples-custom-hooks "Link for Examples of wrapping Effects in custom Hooks")

#### Example 1 of 3:Custom `useChatRoom` Hook[](#custom-usechatroom-hook "Link for this heading")

This example is identical to one of the [earlier examples,](#examples-connecting) but the logic is extracted to a custom Hook.

```
import { useState } from 'react';
import { useChatRoom } from './useChatRoom.js';

function ChatRoom({ roomId }) {
  const [serverUrl, setServerUrl] = useState('https://localhost:1234');

  useChatRoom({
    roomId: roomId,
    serverUrl: serverUrl
  });

  return (
    <>
      <label>
        Server URL:{' '}
        <input
          value={serverUrl}
          onChange={e => setServerUrl(e.target.value)}
        />
      </label>
      <h1>Welcome to the {roomId} room!</h1>
    </>
  );
}

export default function App() {
  const [roomId, setRoomId] = useState('general');
  const [show, setShow] = useState(false);
  return (
    <>
      <label>
        Choose the chat room:{' '}
        <select
          value={roomId}
          onChange={e => setRoomId(e.target.value)}
        >
          <option value="general">general</option>
          <option value="travel">travel</option>
          <option value="music">music</option>
        </select>
      </label>
      <button onClick={() => setShow(!show)}>
        {show ? 'Close chat' : 'Open chat'}
      </button>
      {show && <hr />}
      {show && <ChatRoom roomId={roomId} />}
    </>
  );
}
```

***

### Controlling a non-React widget[](#controlling-a-non-react-widget "Link for Controlling a non-React widget ")

Sometimes, you want to keep an external system synchronized to some prop or state of your component.

For example, if you have a third-party map widget or a video player component written without React, you can use an Effect to call methods on it that make its state match the current state of your React component. This Effect creates an instance of a `MapWidget` class defined in `map-widget.js`. When you change the `zoomLevel` prop of the `Map` component, the Effect calls the `setZoom()` on the class instance to keep it synchronized:

```
import { useRef, useEffect } from 'react';
import { MapWidget } from './map-widget.js';

export default function Map({ zoomLevel }) {
  const containerRef = useRef(null);
  const mapRef = useRef(null);

  useEffect(() => {
    if (mapRef.current === null) {
      mapRef.current = new MapWidget(containerRef.current);
    }

    const map = mapRef.current;
    map.setZoom(zoomLevel);
  }, [zoomLevel]);

  return (
    <div
      style={{ width: 200, height: 200 }}
      ref={containerRef}
    />
  );
}
```

In this example, a cleanup function is not needed because the `MapWidget` class manages only the DOM node that was passed to it. After the `Map` React component is removed from the tree, both the DOM node and the `MapWidget` class instance will be automatically garbage-collected by the browser JavaScript engine.

***

### Fetching data with Effects[](#fetching-data-with-effects "Link for Fetching data with Effects ")

You can use an Effect to fetch data for your component. Note that [if you use a framework,](/learn/start-a-new-react-project#production-grade-react-frameworks) using your framework’s data fetching mechanism will be a lot more efficient than writing Effects manually.

If you want to fetch data from an Effect manually, your code might look like this:

```
import { useState, useEffect } from 'react';

import { fetchBio } from './api.js';



export default function Page() {

  const [person, setPerson] = useState('Alice');

  const [bio, setBio] = useState(null);



  useEffect(() => {

    let ignore = false;

    setBio(null);

    fetchBio(person).then(result => {

      if (!ignore) {

        setBio(result);

      }

    });

    return () => {

      ignore = true;

    };

  }, [person]);



  // ...
```

Note the `ignore` variable which is initialized to `false`, and is set to `true` during cleanup. This ensures [your code doesn’t suffer from “race conditions”:](https://maxrozen.com/race-conditions-fetching-data-react-with-useeffect) network responses may arrive in a different order than you sent them.

```
import { useState, useEffect } from 'react';
import { fetchBio } from './api.js';

export default function Page() {
  const [person, setPerson] = useState('Alice');
  const [bio, setBio] = useState(null);
  useEffect(() => {
    let ignore = false;
    setBio(null);
    fetchBio(person).then(result => {
      if (!ignore) {
        setBio(result);
      }
    });
    return () => {
      ignore = true;
    }
  }, [person]);

  return (
    <>
      <select value={person} onChange={e => {
        setPerson(e.target.value);
      }}>
        <option value="Alice">Alice</option>
        <option value="Bob">Bob</option>
        <option value="Taylor">Taylor</option>
      </select>
      <hr />
      <p><i>{bio ?? 'Loading...'}</i></p>
    </>
  );
}
```

You can also rewrite using the [`async` / `await`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function) syntax, but you still need to provide a cleanup function:

```
import { useState, useEffect } from 'react';
import { fetchBio } from './api.js';

export default function Page() {
  const [person, setPerson] = useState('Alice');
  const [bio, setBio] = useState(null);
  useEffect(() => {
    async function startFetching() {
      setBio(null);
      const result = await fetchBio(person);
      if (!ignore) {
        setBio(result);
      }
    }

    let ignore = false;
    startFetching();
    return () => {
      ignore = true;
    }
  }, [person]);

  return (
    <>
      <select value={person} onChange={e => {
        setPerson(e.target.value);
      }}>
        <option value="Alice">Alice</option>
        <option value="Bob">Bob</option>
        <option value="Taylor">Taylor</option>
      </select>
      <hr />
      <p><i>{bio ?? 'Loading...'}</i></p>
    </>
  );
}
```

* **If you use a [framework](/learn/start-a-new-react-project#production-grade-react-frameworks), use its built-in data fetching mechanism.** Modern React frameworks have integrated data fetching mechanisms that are efficient and don’t suffer from the above pitfalls.
* **Otherwise, consider using or building a client-side cache.** Popular open source solutions include [React Query](https://tanstack.com/query/latest/), [useSWR](https://swr.vercel.app/), and [React Router 6.4+.](https://beta.reactrouter.com/en/main/start/overview) You can build your own solution too, in which case you would use Effects under the hood but also add logic for deduplicating requests, caching responses, and avoiding network waterfalls (by preloading data or hoisting data requirements to routes).

You can continue fetching data directly in Effects if neither of these approaches suit you.

***

### Specifying reactive dependencies[](#specifying-reactive-dependencies "Link for Specifying reactive dependencies ")

**Notice that you can’t “choose” the dependencies of your Effect.** Every reactive value used by your Effect’s code must be declared as a dependency. Your Effect’s dependency list is determined by the surrounding code:

```
function ChatRoom({ roomId }) { // This is a reactive value

  const [serverUrl, setServerUrl] = useState('https://localhost:1234'); // This is a reactive value too



  useEffect(() => {

    const connection = createConnection(serverUrl, roomId); // This Effect reads these reactive values

    connection.connect();

    return () => connection.disconnect();

  }, [serverUrl, roomId]); // ✅ So you must specify them as dependencies of your Effect

  // ...

}
```

If either `serverUrl` or `roomId` change, your Effect will reconnect to the chat using the new values.

**[Reactive values](/learn/lifecycle-of-reactive-effects#effects-react-to-reactive-values) include props and all variables and functions declared directly inside of your component.** Since `roomId` and `serverUrl` are reactive values, you can’t remove them from the dependencies. If you try to omit them and [your linter is correctly configured for React,](/learn/editor-setup#linting) the linter will flag this as a mistake you need to fix:

```
function ChatRoom({ roomId }) {

  const [serverUrl, setServerUrl] = useState('https://localhost:1234');

  

  useEffect(() => {

    const connection = createConnection(serverUrl, roomId);

    connection.connect();

    return () => connection.disconnect();

  }, []); // 🔴 React Hook useEffect has missing dependencies: 'roomId' and 'serverUrl'

  // ...

}
```

**To remove a dependency, you need to [“prove” to the linter that it *doesn’t need* to be a dependency.](/learn/removing-effect-dependencies#removing-unnecessary-dependencies)** For example, you can move `serverUrl` out of your component to prove that it’s not reactive and won’t change on re-renders:

```
const serverUrl = 'https://localhost:1234'; // Not a reactive value anymore



function ChatRoom({ roomId }) {

  useEffect(() => {

    const connection = createConnection(serverUrl, roomId);

    connection.connect();

    return () => connection.disconnect();

  }, [roomId]); // ✅ All dependencies declared

  // ...

}
```

Now that `serverUrl` is not a reactive value (and can’t change on a re-render), it doesn’t need to be a dependency. **If your Effect’s code doesn’t use any reactive values, its dependency list should be empty (`[]`):**

```
const serverUrl = 'https://localhost:1234'; // Not a reactive value anymore

const roomId = 'music'; // Not a reactive value anymore



function ChatRoom() {

  useEffect(() => {

    const connection = createConnection(serverUrl, roomId);

    connection.connect();

    return () => connection.disconnect();

  }, []); // ✅ All dependencies declared

  // ...

}
```

[An Effect with empty dependencies](/learn/lifecycle-of-reactive-effects#what-an-effect-with-empty-dependencies-means) doesn’t re-run when any of your component’s props or state change.

### Pitfall

If you have an existing codebase, you might have some Effects that suppress the linter like this:

```
useEffect(() => {

  // ...

  // 🔴 Avoid suppressing the linter like this:

  // eslint-ignore-next-line react-hooks/exhaustive-deps

}, []);
```

**When dependencies don’t match the code, there is a high risk of introducing bugs.** By suppressing the linter, you “lie” to React about the values your Effect depends on. [Instead, prove they’re unnecessary.](/learn/removing-effect-dependencies#removing-unnecessary-dependencies)

#### Examples of passing reactive dependencies[](#examples-dependencies "Link for Examples of passing reactive dependencies")

#### Example 1 of 3:Passing a dependency array[](#passing-a-dependency-array "Link for this heading")

If you specify the dependencies, your Effect runs **after the initial render *and* after re-renders with changed dependencies.**

```
useEffect(() => {

  // ...

}, [a, b]); // Runs again if a or b are different
```

In the below example, `serverUrl` and `roomId` are [reactive values,](/learn/lifecycle-of-reactive-effects#effects-react-to-reactive-values) so they both must be specified as dependencies. As a result, selecting a different room in the dropdown or editing the server URL input causes the chat to re-connect. However, since `message` isn’t used in the Effect (and so it isn’t a dependency), editing the message doesn’t re-connect to the chat.

```
import { useState, useEffect } from 'react';
import { createConnection } from './chat.js';

function ChatRoom({ roomId }) {
  const [serverUrl, setServerUrl] = useState('https://localhost:1234');
  const [message, setMessage] = useState('');

  useEffect(() => {
    const connection = createConnection(serverUrl, roomId);
    connection.connect();
    return () => {
      connection.disconnect();
    };
  }, [serverUrl, roomId]);

  return (
    <>
      <label>
        Server URL:{' '}
        <input
          value={serverUrl}
          onChange={e => setServerUrl(e.target.value)}
        />
      </label>
      <h1>Welcome to the {roomId} room!</h1>
      <label>
        Your message:{' '}
        <input value={message} onChange={e => setMessage(e.target.value)} />
      </label>
    </>
  );
}

export default function App() {
  const [show, setShow] = useState(false);
  const [roomId, setRoomId] = useState('general');
  return (
    <>
      <label>
        Choose the chat room:{' '}
        <select
          value={roomId}
          onChange={e => setRoomId(e.target.value)}
        >
          <option value="general">general</option>
          <option value="travel">travel</option>
          <option value="music">music</option>
        </select>
        <button onClick={() => setShow(!show)}>
          {show ? 'Close chat' : 'Open chat'}
        </button>
      </label>
      {show && <hr />}
      {show && <ChatRoom roomId={roomId}/>}
    </>
  );
}
```

***

### Updating state based on previous state from an Effect[](#updating-state-based-on-previous-state-from-an-effect "Link for Updating state based on previous state from an Effect ")

When you want to update state based on previous state from an Effect, you might run into a problem:

```
function Counter() {

  const [count, setCount] = useState(0);



  useEffect(() => {

    const intervalId = setInterval(() => {

      setCount(count + 1); // You want to increment the counter every second...

    }, 1000)

    return () => clearInterval(intervalId);

  }, [count]); // 🚩 ... but specifying `count` as a dependency always resets the interval.

  // ...

}
```

Since `count` is a reactive value, it must be specified in the list of dependencies. However, that causes the Effect to cleanup and setup again every time the `count` changes. This is not ideal.

To fix this, [pass the `c => c + 1` state updater](/reference/react/useState#updating-state-based-on-the-previous-state) to `setCount`:

```
import { useState, useEffect } from 'react';

export default function Counter() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    const intervalId = setInterval(() => {
      setCount(c => c + 1); // ✅ Pass a state updater
    }, 1000);
    return () => clearInterval(intervalId);
  }, []); // ✅ Now count is not a dependency

  return <h1>{count}</h1>;
}
```

Now that you’re passing `c => c + 1` instead of `count + 1`, [your Effect no longer needs to depend on `count`.](/learn/removing-effect-dependencies#are-you-reading-some-state-to-calculate-the-next-state) As a result of this fix, it won’t need to cleanup and setup the interval again every time the `count` changes.

***

### Removing unnecessary object dependencies[](#removing-unnecessary-object-dependencies "Link for Removing unnecessary object dependencies ")

If your Effect depends on an object or a function created during rendering, it might run too often. For example, this Effect re-connects after every render because the `options` object is [different for every render:](/learn/removing-effect-dependencies#does-some-reactive-value-change-unintentionally)

```
const serverUrl = 'https://localhost:1234';



function ChatRoom({ roomId }) {

  const [message, setMessage] = useState('');



  const options = { // 🚩 This object is created from scratch on every re-render

    serverUrl: serverUrl,

    roomId: roomId

  };



  useEffect(() => {

    const connection = createConnection(options); // It's used inside the Effect

    connection.connect();

    return () => connection.disconnect();

  }, [options]); // 🚩 As a result, these dependencies are always different on a re-render

  // ...
```

Avoid using an object created during rendering as a dependency. Instead, create the object inside the Effect:

```
import { useState, useEffect } from 'react';
import { createConnection } from './chat.js';

const serverUrl = 'https://localhost:1234';

function ChatRoom({ roomId }) {
  const [message, setMessage] = useState('');

  useEffect(() => {
    const options = {
      serverUrl: serverUrl,
      roomId: roomId
    };
    const connection = createConnection(options);
    connection.connect();
    return () => connection.disconnect();
  }, [roomId]);

  return (
    <>
      <h1>Welcome to the {roomId} room!</h1>
      <input value={message} onChange={e => setMessage(e.target.value)} />
    </>
  );
}

export default function App() {
  const [roomId, setRoomId] = useState('general');
  return (
    <>
      <label>
        Choose the chat room:{' '}
        <select
          value={roomId}
          onChange={e => setRoomId(e.target.value)}
        >
          <option value="general">general</option>
          <option value="travel">travel</option>
          <option value="music">music</option>
        </select>
      </label>
      <hr />
      <ChatRoom roomId={roomId} />
    </>
  );
}
```

Now that you create the `options` object inside the Effect, the Effect itself only depends on the `roomId` string.

With this fix, typing into the input doesn’t reconnect the chat. Unlike an object which gets re-created, a string like `roomId` doesn’t change unless you set it to another value. [Read more about removing dependencies.](/learn/removing-effect-dependencies)

***

### Removing unnecessary function dependencies[](#removing-unnecessary-function-dependencies "Link for Removing unnecessary function dependencies ")

If your Effect depends on an object or a function created during rendering, it might run too often. For example, this Effect re-connects after every render because the `createOptions` function is [different for every render:](/learn/removing-effect-dependencies#does-some-reactive-value-change-unintentionally)

```
function ChatRoom({ roomId }) {

  const [message, setMessage] = useState('');



  function createOptions() { // 🚩 This function is created from scratch on every re-render

    return {

      serverUrl: serverUrl,

      roomId: roomId

    };

  }



  useEffect(() => {

    const options = createOptions(); // It's used inside the Effect

    const connection = createConnection();

    connection.connect();

    return () => connection.disconnect();

  }, [createOptions]); // 🚩 As a result, these dependencies are always different on a re-render

  // ...
```

By itself, creating a function from scratch on every re-render is not a problem. You don’t need to optimize that. However, if you use it as a dependency of your Effect, it will cause your Effect to re-run after every re-render.

Avoid using a function created during rendering as a dependency. Instead, declare it inside the Effect:

```
import { useState, useEffect } from 'react';
import { createConnection } from './chat.js';

const serverUrl = 'https://localhost:1234';

function ChatRoom({ roomId }) {
  const [message, setMessage] = useState('');

  useEffect(() => {
    function createOptions() {
      return {
        serverUrl: serverUrl,
        roomId: roomId
      };
    }

    const options = createOptions();
    const connection = createConnection(options);
    connection.connect();
    return () => connection.disconnect();
  }, [roomId]);

  return (
    <>
      <h1>Welcome to the {roomId} room!</h1>
      <input value={message} onChange={e => setMessage(e.target.value)} />
    </>
  );
}

export default function App() {
  const [roomId, setRoomId] = useState('general');
  return (
    <>
      <label>
        Choose the chat room:{' '}
        <select
          value={roomId}
          onChange={e => setRoomId(e.target.value)}
        >
          <option value="general">general</option>
          <option value="travel">travel</option>
          <option value="music">music</option>
        </select>
      </label>
      <hr />
      <ChatRoom roomId={roomId} />
    </>
  );
}
```

Now that you define the `createOptions` function inside the Effect, the Effect itself only depends on the `roomId` string. With this fix, typing into the input doesn’t reconnect the chat. Unlike a function which gets re-created, a string like `roomId` doesn’t change unless you set it to another value. [Read more about removing dependencies.](/learn/removing-effect-dependencies)

***

### Reading the latest props and state from an Effect[](#reading-the-latest-props-and-state-from-an-effect "Link for Reading the latest props and state from an Effect ")

### Under Construction

This section describes an **experimental API that has not yet been released** in a stable version of React.

By default, when you read a reactive value from an Effect, you have to add it as a dependency. This ensures that your Effect “reacts” to every change of that value. For most dependencies, that’s the behavior you want.

**However, sometimes you’ll want to read the *latest* props and state from an Effect without “reacting” to them.** For example, imagine you want to log the number of the items in the shopping cart for every page visit:

```
function Page({ url, shoppingCart }) {

  useEffect(() => {

    logVisit(url, shoppingCart.length);

  }, [url, shoppingCart]); // ✅ All dependencies declared

  // ...

}
```

**What if you want to log a new page visit after every `url` change, but *not* if only the `shoppingCart` changes?** You can’t exclude `shoppingCart` from dependencies without breaking the [reactivity rules.](#specifying-reactive-dependencies) However, you can express that you *don’t want* a piece of code to “react” to changes even though it is called from inside an Effect. [Declare an *Effect Event*](/learn/separating-events-from-effects#declaring-an-effect-event) with the [`useEffectEvent`](/reference/react/experimental_useEffectEvent) Hook, and move the code reading `shoppingCart` inside of it:

```
function Page({ url, shoppingCart }) {

  const onVisit = useEffectEvent(visitedUrl => {

    logVisit(visitedUrl, shoppingCart.length)

  });



  useEffect(() => {

    onVisit(url);

  }, [url]); // ✅ All dependencies declared

  // ...

}
```

**Effect Events are not reactive and must always be omitted from dependencies of your Effect.** This is what lets you put non-reactive code (where you can read the latest value of some props and state) inside of them. By reading `shoppingCart` inside of `onVisit`, you ensure that `shoppingCart` won’t re-run your Effect.

[Read more about how Effect Events let you separate reactive and non-reactive code.](/learn/separating-events-from-effects#reading-latest-props-and-state-with-effect-events)

***

### Displaying different content on the server and the client[](#displaying-different-content-on-the-server-and-the-client "Link for Displaying different content on the server and the client ")

If your app uses server rendering (either [directly](/reference/react-dom/server) or via a [framework](/learn/start-a-new-react-project#production-grade-react-frameworks)), your component will render in two different environments. On the server, it will render to produce the initial HTML. On the client, React will run the rendering code again so that it can attach your event handlers to that HTML. This is why, for [hydration](/reference/react-dom/client/hydrateRoot#hydrating-server-rendered-html) to work, your initial render output must be identical on the client and the server.

In rare cases, you might need to display different content on the client. For example, if your app reads some data from [`localStorage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage), it can’t possibly do that on the server. Here is how you could implement this:

```
function MyComponent() {

  const [didMount, setDidMount] = useState(false);



  useEffect(() => {

    setDidMount(true);

  }, []);



  if (didMount) {

    // ... return client-only JSX ...

  }  else {

    // ... return initial JSX ...

  }

}
```

While the app is loading, the user will see the initial render output. Then, when it’s loaded and hydrated, your Effect will run and set `didMount` to `true`, triggering a re-render. This will switch to the client-only render output. Effects don’t run on the server, so this is why `didMount` was `false` during the initial server render.

Use this pattern sparingly. Keep in mind that users with a slow connection will see the initial content for quite a bit of time—potentially, many seconds—so you don’t want to make jarring changes to your component’s appearance. In many cases, you can avoid the need for this by conditionally showing different things with CSS.

***

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### My Effect runs twice when the component mounts[](#my-effect-runs-twice-when-the-component-mounts "Link for My Effect runs twice when the component mounts ")

When Strict Mode is on, in development, React runs setup and cleanup one extra time before the actual setup.

This is a stress-test that verifies your Effect’s logic is implemented correctly. If this causes visible issues, your cleanup function is missing some logic. The cleanup function should stop or undo whatever the setup function was doing. The rule of thumb is that the user shouldn’t be able to distinguish between the setup being called once (as in production) and a setup → cleanup → setup sequence (as in development).

Read more about [how this helps find bugs](/learn/synchronizing-with-effects#step-3-add-cleanup-if-needed) and [how to fix your logic.](/learn/synchronizing-with-effects#how-to-handle-the-effect-firing-twice-in-development)

***

### My Effect runs after every re-render[](#my-effect-runs-after-every-re-render "Link for My Effect runs after every re-render ")

First, check that you haven’t forgotten to specify the dependency array:

```
useEffect(() => {

  // ...

}); // 🚩 No dependency array: re-runs after every render!
```

If you’ve specified the dependency array but your Effect still re-runs in a loop, it’s because one of your dependencies is different on every re-render.

You can debug this problem by manually logging your dependencies to the console:

```
  useEffect(() => {

    // ..

  }, [serverUrl, roomId]);



  console.log([serverUrl, roomId]);
```

You can then right-click on the arrays from different re-renders in the console and select “Store as a global variable” for both of them. Assuming the first one got saved as `temp1` and the second one got saved as `temp2`, you can then use the browser console to check whether each dependency in both arrays is the same:

```
Object.is(temp1[0], temp2[0]); // Is the first dependency the same between the arrays?

Object.is(temp1[1], temp2[1]); // Is the second dependency the same between the arrays?

Object.is(temp1[2], temp2[2]); // ... and so on for every dependency ...
```

When you find the dependency that is different on every re-render, you can usually fix it in one of these ways:

* [Updating state based on previous state from an Effect](#updating-state-based-on-previous-state-from-an-effect)
* [Removing unnecessary object dependencies](#removing-unnecessary-object-dependencies)
* [Removing unnecessary function dependencies](#removing-unnecessary-function-dependencies)
* [Reading the latest props and state from an Effect](#reading-the-latest-props-and-state-from-an-effect)

As a last resort (if these methods didn’t help), wrap its creation with [`useMemo`](/reference/react/useMemo#memoizing-a-dependency-of-another-hook) or [`useCallback`](/reference/react/useCallback#preventing-an-effect-from-firing-too-often) (for functions).

***

***

### My cleanup logic runs even though my component didn’t unmount[](#my-cleanup-logic-runs-even-though-my-component-didnt-unmount "Link for My cleanup logic runs even though my component didn’t unmount ")

The cleanup function runs not only during unmount, but before every re-render with changed dependencies. Additionally, in development, React [runs setup+cleanup one extra time immediately after component mounts.](#my-effect-runs-twice-when-the-component-mounts)

If you have cleanup code without corresponding setup code, it’s usually a code smell:

```
useEffect(() => {

  // 🔴 Avoid: Cleanup logic without corresponding setup logic

  return () => {

    doSomething();

  };

}, []);
```

Your cleanup logic should be “symmetrical” to the setup logic, and should stop or undo whatever setup did:

```
  useEffect(() => {

    const connection = createConnection(serverUrl, roomId);

    connection.connect();

    return () => {

      connection.disconnect();

    };

  }, [serverUrl, roomId]);
```

[Learn how the Effect lifecycle is different from the component’s lifecycle.](/learn/lifecycle-of-reactive-effects#the-lifecycle-of-an-effect)

***

### My Effect does something visual, and I see a flicker before it runs[](#my-effect-does-something-visual-and-i-see-a-flicker-before-it-runs "Link for My Effect does something visual, and I see a flicker before it runs ")

If your Effect must block the browser from [painting the screen,](/learn/render-and-commit#epilogue-browser-paint) replace `useEffect` with [`useLayoutEffect`](/reference/react/useLayoutEffect). Note that **this shouldn’t be needed for the vast majority of Effects.** You’ll only need this if it’s crucial to run your Effect before the browser paint: for example, to measure and position a tooltip before the user sees it.

[PrevioususeDeferredValue](/reference/react/useDeferredValue)

[NextuseId](/reference/react/useId)

***

----
url: https://18.react.dev/reference/react-dom/components/select
----

[API Reference](/reference/react)

[Components](/reference/react-dom/components)

# \<select>[](#undefined "Link for this heading")

The [built-in browser `<select>` component](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/select) lets you render a select box with options.

```
<select>

  <option value="someOption">Some option</option>

  <option value="otherOption">Other option</option>

</select>
```

***

## Reference[](#reference "Link for Reference ")

### `<select>`[](#select "Link for this heading")

To display a select box, render the [built-in browser `<select>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/select) component.

```
<select>

  <option value="someOption">Some option</option>

  <option value="otherOption">Other option</option>

</select>
```

[See more examples below.](#usage)

#### Props[](#props "Link for Props ")

`<select>` supports all [common element props.](/reference/react-dom/components/common#props)

***

## Usage[](#usage "Link for Usage ")

### Displaying a select box with options[](#displaying-a-select-box-with-options "Link for Displaying a select box with options ")

Render a `<select>` with a list of `<option>` components inside to display a select box. Give each `<option>` a `value` representing the data to be submitted with the form.

```
export default function FruitPicker() {
  return (
    <label>
      Pick a fruit:
      <select name="selectedFruit">
        <option value="apple">Apple</option>
        <option value="banana">Banana</option>
        <option value="orange">Orange</option>
      </select>
    </label>
  );
}
```

***

### Providing a label for a select box[](#providing-a-label-for-a-select-box "Link for Providing a label for a select box ")

Typically, you will place every `<select>` inside a [`<label>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/label) tag. This tells the browser that this label is associated with that select box. When the user clicks the label, the browser will automatically focus the select box. It’s also essential for accessibility: a screen reader will announce the label caption when the user focuses the select box.

If you can’t nest `<select>` into a `<label>`, associate them by passing the same ID to `<select id>` and [`<label htmlFor>`.](https://developer.mozilla.org/en-US/docs/Web/API/HTMLLabelElement/htmlFor) To avoid conflicts between multiple instances of one component, generate such an ID with [`useId`.](/reference/react/useId)

```
import { useId } from 'react';

export default function Form() {
  const vegetableSelectId = useId();
  return (
    <>
      <label>
        Pick a fruit:
        <select name="selectedFruit">
          <option value="apple">Apple</option>
          <option value="banana">Banana</option>
          <option value="orange">Orange</option>
        </select>
      </label>
      <hr />
      <label htmlFor={vegetableSelectId}>
        Pick a vegetable:
      </label>
      <select id={vegetableSelectId} name="selectedVegetable">
        <option value="cucumber">Cucumber</option>
        <option value="corn">Corn</option>
        <option value="tomato">Tomato</option>
      </select>
    </>
  );
}
```

***

### Providing an initially selected option[](#providing-an-initially-selected-option "Link for Providing an initially selected option ")

By default, the browser will select the first `<option>` in the list. To select a different option by default, pass that `<option>`’s `value` as the `defaultValue` to the `<select>` element.

```
export default function FruitPicker() {
  return (
    <label>
      Pick a fruit:
      <select name="selectedFruit" defaultValue="orange">
        <option value="apple">Apple</option>
        <option value="banana">Banana</option>
        <option value="orange">Orange</option>
      </select>
    </label>
  );
}
```

### Pitfall

Unlike in HTML, passing a `selected` attribute to an individual `<option>` is not supported.

***

### Enabling multiple selection[](#enabling-multiple-selection "Link for Enabling multiple selection ")

Pass `multiple={true}` to the `<select>` to let the user select multiple options. In that case, if you also specify `defaultValue` to choose the initially selected options, it must be an array.

```
export default function FruitPicker() {
  return (
    <label>
      Pick some fruits:
      <select
        name="selectedFruit"
        defaultValue={['orange', 'banana']}
        multiple={true}
      >
        <option value="apple">Apple</option>
        <option value="banana">Banana</option>
        <option value="orange">Orange</option>
      </select>
    </label>
  );
}
```

***

### Reading the select box value when submitting a form[](#reading-the-select-box-value-when-submitting-a-form "Link for Reading the select box value when submitting a form ")

Add a [`<form>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form) around your select box with a [`<button type="submit">`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button) inside. It will call your `<form onSubmit>` event handler. By default, the browser will send the form data to the current URL and refresh the page. You can override that behavior by calling `e.preventDefault()`. Read the form data with [`new FormData(e.target)`](https://developer.mozilla.org/en-US/docs/Web/API/FormData).

```
export default function EditPost() {
  function handleSubmit(e) {
    // Prevent the browser from reloading the page
    e.preventDefault();
    // Read the form data
    const form = e.target;
    const formData = new FormData(form);
    // You can pass formData as a fetch body directly:
    fetch('/some-api', { method: form.method, body: formData });
    // You can generate a URL out of it, as the browser does by default:
    console.log(new URLSearchParams(formData).toString());
    // You can work with it as a plain object.
    const formJson = Object.fromEntries(formData.entries());
    console.log(formJson); // (!) This doesn't include multiple select values
    // Or you can get an array of name-value pairs.
    console.log([...formData.entries()]);
  }

  return (
    <form method="post" onSubmit={handleSubmit}>
      <label>
        Pick your favorite fruit:
        <select name="selectedFruit" defaultValue="orange">
          <option value="apple">Apple</option>
          <option value="banana">Banana</option>
          <option value="orange">Orange</option>
        </select>
      </label>
      <label>
        Pick all your favorite vegetables:
        <select
          name="selectedVegetables"
          multiple={true}
          defaultValue={['corn', 'tomato']}
        >
          <option value="cucumber">Cucumber</option>
          <option value="corn">Corn</option>
          <option value="tomato">Tomato</option>
        </select>
      </label>
      <hr />
      <button type="reset">Reset</button>
      <button type="submit">Submit</button>
    </form>
  );
}
```

### Note

Give a `name` to your `<select>`, for example `<select name="selectedFruit" />`. The `name` you specified will be used as a key in the form data, for example `{ selectedFruit: "orange" }`.

If you use `<select multiple={true}>`, the [`FormData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData) you’ll read from the form will include each selected value as a separate name-value pair. Look closely at the console logs in the example above.

### Pitfall

By default, *any* `<button>` inside a `<form>` will submit it. This can be surprising! If you have your own custom `Button` React component, consider returning [`<button type="button">`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/button) instead of `<button>`. Then, to be explicit, use `<button type="submit">` for buttons that *are* supposed to submit the form.

***

### Controlling a select box with a state variable[](#controlling-a-select-box-with-a-state-variable "Link for Controlling a select box with a state variable ")

A select box like `<select />` is *uncontrolled.* Even if you [pass an initially selected value](#providing-an-initially-selected-option) like `<select defaultValue="orange" />`, your JSX only specifies the initial value, not the value right now.

**To render a *controlled* select box, pass the `value` prop to it.** React will force the select box to always have the `value` you passed. Typically, you will control a select box by declaring a [state variable:](/reference/react/useState)

```
function FruitPicker() {

  const [selectedFruit, setSelectedFruit] = useState('orange'); // Declare a state variable...

  // ...

  return (

    <select

      value={selectedFruit} // ...force the select's value to match the state variable...

      onChange={e => setSelectedFruit(e.target.value)} // ... and update the state variable on any change!

    >

      <option value="apple">Apple</option>

      <option value="banana">Banana</option>

      <option value="orange">Orange</option>

    </select>

  );

}
```

This is useful if you want to re-render some part of the UI in response to every selection.

```
import { useState } from 'react';

export default function FruitPicker() {
  const [selectedFruit, setSelectedFruit] = useState('orange');
  const [selectedVegs, setSelectedVegs] = useState(['corn', 'tomato']);
  return (
    <>
      <label>
        Pick a fruit:
        <select
          value={selectedFruit}
          onChange={e => setSelectedFruit(e.target.value)}
        >
          <option value="apple">Apple</option>
          <option value="banana">Banana</option>
          <option value="orange">Orange</option>
        </select>
      </label>
      <hr />
      <label>
        Pick all your favorite vegetables:
        <select
          multiple={true}
          value={selectedVegs}
          onChange={e => {
            const options = [...e.target.selectedOptions];
            const values = options.map(option => option.value);
            setSelectedVegs(values);
          }}
        >
          <option value="cucumber">Cucumber</option>
          <option value="corn">Corn</option>
          <option value="tomato">Tomato</option>
        </select>
      </label>
      <hr />
      <p>Your favorite fruit: {selectedFruit}</p>
      <p>Your favorite vegetables: {selectedVegs.join(', ')}</p>
    </>
  );
}
```

### Pitfall

**If you pass `value` without `onChange`, it will be impossible to select an option.** When you control a select box by passing some `value` to it, you *force* it to always have the value you passed. So if you pass a state variable as a `value` but forget to update that state variable synchronously during the `onChange` event handler, React will revert the select box after every keystroke back to the `value` that you specified.

Unlike in HTML, passing a `selected` attribute to an individual `<option>` is not supported.

[Previous\<progress>](/reference/react-dom/components/progress)

[Next\<textarea>](/reference/react-dom/components/textarea)

***

----
url: https://legacy.reactjs.org/blog/2016/07/22/create-apps-with-no-configuration.html
----

July 22, 2016 by [Dan Abramov](https://twitter.com/dan_abramov)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

**[Create React App](https://github.com/facebookincubator/create-react-app)** is a new officially supported way to create single-page React applications. It offers a modern build setup with no configuration.

## [](#getting-started)Getting Started

### [](#installation)Installation

First, install the global package:

```
npm install -g create-react-app
```

Node.js 4.x or higher is required.

### [](#creating-an-app)Creating an App

Now you can use it to create a new app:

```
create-react-app hello-world
```

This will take a while as npm installs the transitive dependencies, but once it’s done, you will see a list of commands you can run in the created folder:

### [](#starting-the-server)Starting the Server

Run `npm start` to launch the development server. The browser will open automatically with the created app’s URL.

Create React App uses both webpack and Babel under the hood. The console output is tuned to be minimal to help you focus on the problems:

ESLint is also integrated so lint warnings are displayed right in the console:

We only picked a small subset of lint rules that often lead to bugs.

### [](#building-for-production)Building for Production

To build an optimized bundle, run `npm run build`:

It is minified, correctly envified, and the assets include content hashes for caching.

### [](#one-dependency)One Dependency

Your `package.json` contains only a single build dependency and a few scripts:

```
{
  "name": "hello-world",
  "dependencies": {
    "react": "^15.2.1",
    "react-dom": "^15.2.1"
  },
  "devDependencies": {
    "react-scripts": "0.1.0"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "eject": "react-scripts eject"
  }
}
```

We take care of updating Babel, ESLint, and webpack to stable compatible versions so you can update a single dependency to get them all.

### [](#zero-configuration)Zero Configuration

It is worth repeating: there are no configuration files or complicated folder structures. The tool only generates the files you need to build your app.

```
hello-world/
  README.md
  index.html
  favicon.ico
  node_modules/
  package.json
  src/
    App.css
    App.js
    index.css
    index.js
    logo.svg
```

All the build settings are preconfigured and can’t be changed. Some features, such as testing, are currently missing. This is an intentional limitation, and we recognize it might not work for everybody. And this brings us to the last point.

### [](#no-lock-in)No Lock-In

We first saw this feature in [Enclave](https://github.com/eanplatter/enclave), and we loved it. We talked to [Ean](https://twitter.com/EanPlatter), and he was excited to collaborate with us. He already sent a few pull requests!

“Ejecting” lets you leave the comfort of Create React App setup at any time. You run a single command, and all the build dependencies, configs, and scripts are moved right into your project. At this point you can customize everything you want, but effectively you are forking our configuration and going your own way. If you’re experienced with build tooling and prefer to fine-tune everything to your taste, this lets you use Create React App as a boilerplate generator.

We expect that at early stages, many people will “eject” for one reason or another, but as we learn from them, we will make the default setup more and more compelling while still providing no configuration.

## [](#try-it-out)Try It Out!

You can find [**Create React App**](https://github.com/facebookincubator/create-react-app) with additional instructions on GitHub.

This is an experiment, and only time will tell if it becomes a popular way of creating and building React apps, or fades into obscurity.

We welcome you to participate in this experiment. Help us build the React tooling that more people can use. We are always [open to feedback](https://github.com/facebookincubator/create-react-app/issues/11).

## [](#the-backstory)The Backstory

React was one of the first libraries to embrace transpiling JavaScript. As a result, even though you can [learn React without any tooling](https://github.com/facebook/react/blob/3fd582643ef3d222a00a0c756292c15b88f9f83c/examples/basic-jsx/index.html), the React ecosystem has commonly become associated with an overwhelming explosion of tools.

Eric Clemmons called this phenomenon the “[JavaScript Fatigue](https://medium.com/@ericclemmons/javascript-fatigue-48d4011b6fc4)”:

> Ultimately, the problem is that by choosing React (and inherently JSX), you’ve unwittingly opted into a confusing nest of build tools, boilerplate, linters, & time-sinks to deal with before you ever get to create anything.

It is tempting to write code in ES2015 and JSX. It is sensible to use a bundler to keep the codebase modular, and a linter to catch the common mistakes. It is nice to have a development server with fast rebuilds, and a command to produce optimized bundles for production.

Combining these tools requires some experience with each of them. Even so, it is far too easy to get dragged into fighting small incompatibilities, unsatisfied peerDependencies, and illegible configuration files.

Many of those tools are plugin platforms and don’t directly acknowledge each other’s existence. They leave it up to the users to wire them together. The tools mature and change independently, and tutorials quickly get out of date.

> Marc was almost ready to implement his "hello world" React app [pic.twitter.com/ptdg4yteF1](https://t.co/ptdg4yteF1)
>
> — Thomas Fuchs (@thomasfuchs) [March 12, 2016](https://twitter.com/thomasfuchs/status/708675139253174273)

This doesn’t mean those tools aren’t great. To many of us, they have become indispensable, and we very much appreciate the effort of their maintainers. They already have too much on their plates to worry about the state of the React ecosystem.

Still, we knew it was frustrating to spend days setting up a project when all you wanted was to learn React. We wanted to fix this.

## [](#could-we-fix-this)Could We Fix This?

We found ourselves in an unusual dilemma.

So far, [our strategy](/docs/design-principles.html#dogfooding) has been to only release the code that we are using at Facebook. This helped us ensure that every project is battle-tested and has clearly defined scope and priorities.

However, tooling at Facebook is different than at many smaller companies. Linting, transpilation, and packaging are all handled by powerful remote development servers, and product engineers don’t need to configure them. While we wish we could give a dedicated server to every user of React, even Facebook cannot scale that well!

The React community is very important to us. We knew that we couldn’t fix the problem within the limits of our open source philosophy. This is why we decided to make an exception, and to ship something that we didn’t use ourselves, but that we thought would be useful to the community.

## [](#the-quest-for-a-react-abbr-titlecommand-line-interfacecliabbr)The Quest for a React CLI

Having just attended [EmberCamp](http://embercamp.com/) a week ago, I was excited about [Ember CLI](https://ember-cli.com/). Ember users have a great “getting started” experience thanks to a curated set of tools united under a single command-line interface. I have heard similar feedback about [Elm Reactor](https://github.com/elm-lang/elm-reactor).

Providing a cohesive curated experience is valuable by itself, even if the user could in theory assemble those parts themselves. Kathy Sierra [explains it best](http://seriouspony.com/blog/2013/7/24/your-app-makes-me-fat):

> If your UX asks the user to make *choices*, for example, even if those choices are both clear and useful, the act of *deciding* is a cognitive drain. And not just *while* they’re deciding… even *after* we choose, an unconscious cognitive background thread is slowly consuming/leaking resources, “Was *that* the right choice?”

I never tried to write a command-line tool for React apps, and neither has [Christopher](https://twitter.com/vjeux). We were chatting on Messenger about this idea, and we decided to work together on it for a week as a hackathon project.

We knew that such projects traditionally haven’t been very successful in the React ecosystem. Christopher told me that multiple “React CLI” projects have started and failed at Facebook. The community tools with similar goals also exist, but so far they have not yet gained enough traction.

Still, we decided it was worth another shot. Christopher and I created a very rough proof of concept on the weekend, and [Kevin](https://twitter.com/lacker) soon joined us.

We invited some of the community members to collaborate with us, and we have spent this week working on this tool. We hope that you’ll enjoy using it! [Let us know what you think.](https://github.com/facebookincubator/create-react-app/issues/11)

We would like to express our gratitude to [Max Stoiber](https://twitter.com/mxstbr), [Jonny Buchanan](https://twitter.com/jbscript), [Ean Platter](https://twitter.com/eanplatter), [Tyler McGinnis](https://github.com/tylermcginnis), [Kent C. Dodds](https://github.com/kentcdodds), and [Eric Clemmons](https://twitter.com/ericclemmons) for their early feedback, ideas, and contributions.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2016-07-22-create-apps-with-no-configuration.md)

----
url: https://react.dev/reference/react-dom/unmountComponentAtNode
----

```
unmountComponentAtNode(domNode)
```

* [Reference](#reference)
  * [`unmountComponentAtNode(domNode)`](#unmountcomponentatnode)
* [Usage](#usage)
  * [Removing a React app from a DOM element](#removing-a-react-app-from-a-dom-element)

***

## Reference[](#reference "Link for Reference ")

### `unmountComponentAtNode(domNode)`[](#unmountcomponentatnode "Link for this heading")

Call `unmountComponentAtNode` to remove a mounted React component from the DOM and clean up its event handlers and state.

```
import { unmountComponentAtNode } from 'react-dom';



const domNode = document.getElementById('root');

render(<App />, domNode);



unmountComponentAtNode(domNode);
```

[See more examples below.](#usage)

#### Parameters[](#parameters "Link for Parameters ")

* `domNode`: A [DOM element.](https://developer.mozilla.org/en-US/docs/Web/API/Element) React will remove a mounted React component from this element.

#### Returns[](#returns "Link for Returns ")

`unmountComponentAtNode` returns `true` if a component was unmounted and `false` otherwise.

***

## Usage[](#usage "Link for Usage ")

Call `unmountComponentAtNode` to remove a mounted React component from a browser DOM node and clean up its event handlers and state.

```
import { render, unmountComponentAtNode } from 'react-dom';

import App from './App.js';



const rootNode = document.getElementById('root');

render(<App />, rootNode);



// ...

unmountComponentAtNode(rootNode);
```

### Removing a React app from a DOM element[](#removing-a-react-app-from-a-dom-element "Link for Removing a React app from a DOM element ")

Occasionally, you may want to “sprinkle” React on an existing page, or a page that is not fully written in React. In those cases, you may need to “stop” the React app, by removing all of the UI, state, and listeners from the DOM node it was rendered to.

In this example, clicking “Render React App” will render a React app. Click “Unmount React App” to destroy it:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import './styles.css';
import { render, unmountComponentAtNode } from 'react-dom';
import App from './App.js';

const domNode = document.getElementById('root');

document.getElementById('render').addEventListener('click', () => {
  render(<App />, domNode);
});

document.getElementById('unmount').addEventListener('click', () => {
  unmountComponentAtNode(domNode);
});
```

[Previousrender](/reference/react-dom/render)

[NextClient APIs](/reference/react-dom/client)

***

----
url: https://react.dev/reference/react-compiler/compiling-libraries
----

[API Reference](/reference/react)

# Compiling Libraries[](#undefined "Link for this heading")

This guide helps library authors understand how to use React Compiler to ship optimized library code to their users.

* [Why Ship Compiled Code?](#why-ship-compiled-code)

* [Setting Up Compilation](#setting-up-compilation)

* [Backwards Compatibility](#backwards-compatibility)

  * [1. Install the runtime package](#install-runtime-package)
  * [2. Configure the target version](#configure-target-version)

* [Testing Strategy](#testing-strategy)

* [Troubleshooting](#troubleshooting)

  * [Library doesn’t work with older React versions](#library-doesnt-work-with-older-react-versions)
  * [Compilation conflicts with other Babel plugins](#compilation-conflicts-with-other-babel-plugins)
  * [Runtime module not found](#runtime-module-not-found)

* [Next Steps](#next-steps)

## Why Ship Compiled Code?[](#why-ship-compiled-code "Link for Why Ship Compiled Code? ")

As a library author, you can compile your library code before publishing to npm. This provides several benefits:

* **Performance improvements for all users** - Your library users get optimized code even if they aren’t using React Compiler yet
* **No configuration required by users** - The optimizations work out of the box
* **Consistent behavior** - All users get the same optimized version regardless of their build setup

## Setting Up Compilation[](#setting-up-compilation "Link for Setting Up Compilation ")

Add React Compiler to your library’s build process:

Terminal

```
npm install -D babel-plugin-react-compiler@latest
```

Configure your build tool to compile your library. For example, with Babel:

```
// babel.config.js

module.exports = {

  plugins: [

    'babel-plugin-react-compiler',

  ],

  // ... other config

};
```

## Backwards Compatibility[](#backwards-compatibility "Link for Backwards Compatibility ")

If your library supports React versions below 19, you’ll need additional configuration:

### 1. Install the runtime package[](#install-runtime-package "Link for 1. Install the runtime package ")

We recommend installing react-compiler-runtime as a direct dependency:

Terminal

```
npm install react-compiler-runtime@latest
```

```
{

  "dependencies": {

    "react-compiler-runtime": "^1.0.0"

  },

  "peerDependencies": {

    "react": "^17.0.0 || ^18.0.0 || ^19.0.0"

  }

}
```

### 2. Configure the target version[](#configure-target-version "Link for 2. Configure the target version ")

Set the minimum React version your library supports:

```
{

  target: '17', // Minimum supported React version

}
```

## Testing Strategy[](#testing-strategy "Link for Testing Strategy ")

Test your library both with and without compilation to ensure compatibility. Run your existing test suite against the compiled code, and also create a separate test configuration that bypasses the compiler. This helps catch any issues that might arise from the compilation process and ensures your library works correctly in all scenarios.

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### Library doesn’t work with older React versions[](#library-doesnt-work-with-older-react-versions "Link for Library doesn’t work with older React versions ")

If your compiled library throws errors in React 17 or 18:

1. Verify you’ve installed `react-compiler-runtime` as a dependency
2. Check that your `target` configuration matches your minimum supported React version
3. Ensure the runtime package is included in your published bundle

### Compilation conflicts with other Babel plugins[](#compilation-conflicts-with-other-babel-plugins "Link for Compilation conflicts with other Babel plugins ")

Some Babel plugins may conflict with React Compiler:

1. Place `babel-plugin-react-compiler` early in your plugin list
2. Disable conflicting optimizations in other plugins
3. Test your build output thoroughly

### Runtime module not found[](#runtime-module-not-found "Link for Runtime module not found ")

If users see “Cannot find module ‘react-compiler-runtime’“:

1. Ensure the runtime is listed in `dependencies`, not `devDependencies`
2. Check that your bundler includes the runtime in the output
3. Verify the package is published to npm with your library

## Next Steps[](#next-steps "Link for Next Steps ")

* Learn about [debugging techniques](/learn/react-compiler/debugging) for compiled code
* Check the [configuration options](/reference/react-compiler/configuration) for all compiler options
* Explore [compilation modes](/reference/react-compiler/compilationMode) for selective optimization

[Previous"use no memo"](/reference/react-compiler/directives/use-no-memo)

***

----
url: https://react.dev/reference/react-dom/server/renderToStaticMarkup
----

[API Reference](/reference/react)

[Server APIs](/reference/react-dom/server)

# renderToStaticMarkup[](#undefined "Link for this heading")

`renderToStaticMarkup` renders a non-interactive React tree to an HTML string.

```
const html = renderToStaticMarkup(reactNode, options?)
```

* [Reference](#reference)
  * [`renderToStaticMarkup(reactNode, options?)`](#rendertostaticmarkup)
* [Usage](#usage)
  * [Rendering a non-interactive React tree as HTML to a string](#rendering-a-non-interactive-react-tree-as-html-to-a-string)

***

## Reference[](#reference "Link for Reference ")

### `renderToStaticMarkup(reactNode, options?)`[](#rendertostaticmarkup "Link for this heading")

On the server, call `renderToStaticMarkup` to render your app to HTML.

```
import { renderToStaticMarkup } from 'react-dom/server';



const html = renderToStaticMarkup(<Page />);
```

***

## Usage[](#usage "Link for Usage ")

### Rendering a non-interactive React tree as HTML to a string[](#rendering-a-non-interactive-react-tree-as-html-to-a-string "Link for Rendering a non-interactive React tree as HTML to a string ")

Call `renderToStaticMarkup` to render your app to an HTML string which you can send with your server response:

```
import { renderToStaticMarkup } from 'react-dom/server';



// The route handler syntax depends on your backend framework

app.use('/', (request, response) => {

  const html = renderToStaticMarkup(<Page />);

  response.send(html);

});
```

This will produce the initial non-interactive HTML output of your React components.

### Pitfall

This method renders **non-interactive HTML that cannot be hydrated.** This is useful if you want to use React as a simple static page generator, or if you’re rendering completely static content like emails.

Interactive apps should use [`renderToString`](/reference/react-dom/server/renderToString) on the server and [`hydrateRoot`](/reference/react-dom/client/hydrateRoot) on the client.

[PreviousrenderToReadableStream](/reference/react-dom/server/renderToReadableStream)

[NextrenderToString](/reference/react-dom/server/renderToString)

***

----
url: https://react.dev/reference/rsc/server-functions
----

[API Reference](/reference/react)

# Server Functions[](#undefined "Link for this heading")

### React Server Components

Server Functions are for use in [React Server Components](/reference/rsc/server-components).

**Note:** Until September 2024, we referred to all Server Functions as “Server Actions”. If a Server Function is passed to an action prop or called from inside an action then it is a Server Action, but not all Server Functions are Server Actions. The naming in this documentation has been updated to reflect that Server Functions can be used for multiple purposes.

Server Functions allow Client Components to call async functions executed on the server.

### Note

#### How do I build support for Server Functions?[](#how-do-i-build-support-for-server-functions "Link for How do I build support for Server Functions? ")

While Server Functions in React 19 are stable and will not break between minor versions, the underlying APIs used to implement Server Functions in a React Server Components bundler or framework do not follow semver and may break between minors in React 19.x.

To support Server Functions as a bundler or framework, we recommend pinning to a specific React version, or using the Canary release. We will continue working with bundlers and frameworks to stabilize the APIs used to implement Server Functions in the future.

When a Server Function is defined with the [`"use server"`](/reference/rsc/use-server) directive, your framework will automatically create a reference to the Server Function, and pass that reference to the Client Component. When that function is called on the client, React will send a request to the server to execute the function, and return the result.

Server Functions can be created in Server Components and passed as props to Client Components, or they can be imported and used in Client Components.

## Usage[](#usage "Link for Usage ")

### Creating a Server Function from a Server Component[](#creating-a-server-function-from-a-server-component "Link for Creating a Server Function from a Server Component ")

Server Components can define Server Functions with the `"use server"` directive:

```
// Server Component

import Button from './Button';



function EmptyNote () {

  async function createNoteAction() {

    // Server Function

    'use server';



    await db.notes.create();

  }



  return <Button onClick={createNoteAction}/>;

}
```

When React renders the `EmptyNote` Server Component, it will create a reference to the `createNoteAction` function, and pass that reference to the `Button` Client Component. When the button is clicked, React will send a request to the server to execute the `createNoteAction` function with the reference provided:

```
"use client";



export default function Button({onClick}) {

  console.log(onClick);

  // {$$typeof: Symbol.for("react.server.reference"), $$id: 'createNoteAction'}

  return <button onClick={() => onClick()}>Create Empty Note</button>

}
```

For more, see the docs for [`"use server"`](/reference/rsc/use-server).

### Importing Server Functions from Client Components[](#importing-server-functions-from-client-components "Link for Importing Server Functions from Client Components ")

Client Components can import Server Functions from files that use the `"use server"` directive:

```
"use server";



export async function createNote() {

  await db.notes.create();

}
```

When the bundler builds the `EmptyNote` Client Component, it will create a reference to the `createNote` function in the bundle. When the `button` is clicked, React will send a request to the server to execute the `createNote` function using the reference provided:

```
"use client";

import {createNote} from './actions';



function EmptyNote() {

  console.log(createNote);

  // {$$typeof: Symbol.for("react.server.reference"), $$id: 'createNote'}

  <button onClick={() => createNote()} />

}
```

For more, see the docs for [`"use server"`](/reference/rsc/use-server).

### Server Functions with Actions[](#server-functions-with-actions "Link for Server Functions with Actions ")

Server Functions can be called from Actions on the client:

```
"use server";



export async function updateName(name) {

  if (!name) {

    return {error: 'Name is required'};

  }

  await db.users.updateName(name);

}
```

```
"use client";



import {updateName} from './actions';



function UpdateName() {

  const [name, setName] = useState('');

  const [error, setError] = useState(null);



  const [isPending, startTransition] = useTransition();



  const submitAction = async () => {

    startTransition(async () => {

      const {error} = await updateName(name);

      if (error) {

        setError(error);

      } else {

        setName('');

      }

    })

  }



  return (

    <form action={submitAction}>

      <input type="text" name="name" disabled={isPending}/>

      {error && <span>Failed: {error}</span>}

    </form>

  )

}
```

This allows you to access the `isPending` state of the Server Function by wrapping it in an Action on the client.

For more, see the docs for [Calling a Server Function outside of `<form>`](/reference/rsc/use-server#calling-a-server-function-outside-of-form)

### Server Functions with Form Actions[](#using-server-functions-with-form-actions "Link for Server Functions with Form Actions ")

Server Functions work with the new Form features in React 19.

You can pass a Server Function to a Form to automatically submit the form to the server:

```
"use client";



import {updateName} from './actions';



function UpdateName() {

  return (

    <form action={updateName}>

      <input type="text" name="name" />

    </form>

  )

}
```

When the Form submission succeeds, React will automatically reset the form. You can add `useActionState` to access the pending state, last response, or to support progressive enhancement.

For more, see the docs for [Server Functions in Forms](/reference/rsc/use-server#server-functions-in-forms).

### Server Functions with `useActionState`[](#server-functions-with-use-action-state "Link for this heading")

You can call Server Functions with `useActionState` for the common case where you just need access to the action pending state and last returned response:

```
"use client";



import {updateName} from './actions';



function UpdateName() {

  const [state, submitAction, isPending] = useActionState(updateName, {error: null});



  return (

    <form action={submitAction}>

      <input type="text" name="name" disabled={isPending}/>

      {state.error && <span>Failed: {state.error}</span>}

    </form>

  );

}
```

When using `useActionState` with Server Functions, React will also automatically replay form submissions entered before hydration finishes. This means users can interact with your app even before the app has hydrated.

For more, see the docs for [`useActionState`](/reference/react/useActionState).

### Progressive enhancement with `useActionState`[](#progressive-enhancement-with-useactionstate "Link for this heading")

Server Functions also support progressive enhancement with the third argument of `useActionState`.

```
"use client";



import {updateName} from './actions';



function UpdateName() {

  const [, submitAction] = useActionState(updateName, null, `/name/update`);



  return (

    <form action={submitAction}>

      ...

    </form>

  );

}
```

When the permalink is provided to `useActionState`, React will redirect to the provided URL if the form is submitted before the JavaScript bundle loads.

For more, see the docs for [`useActionState`](/reference/react/useActionState).

[PreviousServer Components](/reference/rsc/server-components)

[NextDirectives](/reference/rsc/directives)

***

----
url: https://react.dev/reference/react-dom/components/option
----

[API Reference](/reference/react)

[Components](/reference/react-dom/components)

# \<option>[](#undefined "Link for this heading")

The [built-in browser `<option>` component](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/option) lets you render an option inside a [`<select>`](/reference/react-dom/components/select) box.

```
<select>

  <option value="someOption">Some option</option>

  <option value="otherOption">Other option</option>

</select>
```

* [Reference](#reference)
  * [`<option>`](#option)
* [Usage](#usage)
  * [Displaying a select box with options](#displaying-a-select-box-with-options)

***

## Reference[](#reference "Link for Reference ")

### `<option>`[](#option "Link for this heading")

The [built-in browser `<option>` component](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/option) lets you render an option inside a [`<select>`](/reference/react-dom/components/select) box.

```
<select>

  <option value="someOption">Some option</option>

  <option value="otherOption">Other option</option>

</select>
```

[See more examples below.](#usage)

#### Props[](#props "Link for Props ")

`<option>` supports all [common element props.](/reference/react-dom/components/common#common-props)

Additionally, `<option>` supports these props:

* [`disabled`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/option#disabled): A boolean. If `true`, the option will not be selectable and will appear dimmed.
* [`label`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/option#label): A string. Specifies the meaning of the option. If not specified, the text inside the option is used.
* [`value`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/option#value): The value to be used [when submitting the parent `<select>` in a form](/reference/react-dom/components/select#reading-the-select-box-value-when-submitting-a-form) if this option is selected.

#### Caveats[](#caveats "Link for Caveats ")

* React does not support the `selected` attribute on `<option>`. Instead, pass this option’s `value` to the parent [`<select defaultValue>`](/reference/react-dom/components/select#providing-an-initially-selected-option) for an uncontrolled select box, or [`<select value>`](/reference/react-dom/components/select#controlling-a-select-box-with-a-state-variable) for a controlled select.

***

## Usage[](#usage "Link for Usage ")

### Displaying a select box with options[](#displaying-a-select-box-with-options "Link for Displaying a select box with options ")

Render a `<select>` with a list of `<option>` components inside to display a select box. Give each `<option>` a `value` representing the data to be submitted with the form.

[Read more about displaying a `<select>` with a list of `<option>` components.](/reference/react-dom/components/select)

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
export default function FruitPicker() {
  return (
    <label>
      Pick a fruit:
      <select name="selectedFruit">
        <option value="apple">Apple</option>
        <option value="banana">Banana</option>
        <option value="orange">Orange</option>
      </select>
    </label>
  );
}
```

[Previous\<input>](/reference/react-dom/components/input)

[Next\<progress>](/reference/react-dom/components/progress)

***

----
url: https://legacy.reactjs.org/blog/2020/10/20/react-v17.html
----

October 20, 2020 by [Dan Abramov](https://twitter.com/dan_abramov) and [Rachel Nabors](https://twitter.com/rachelnabors)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

Today, we are releasing React 17! We’ve written at length about the role of the React 17 release and the changes it contains in [the React 17 RC blog post](/blog/2020/08/10/react-v17-rc.html). This post is a brief summary of it, so if you’ve already read the RC post, you can skip this one.

## [](#no-new-features)No New Features

The React 17 release is unusual because it doesn’t add any new developer-facing features. Instead, this release is primarily focused on **making it easier to upgrade React itself**.

In particular, React 17 is a “stepping stone” release that makes it safer to embed a tree managed by one version of React inside a tree managed by a different version of React.

It also makes it easier to embed React into apps built with other technologies.

## [](#gradual-upgrades)Gradual Upgrades

**React 17 enables gradual React upgrades.** When you upgrade from React 15 to 16 (or, this time, from React 16 to 17), you would usually upgrade your whole app at once. This works well for many apps. But it can get increasingly challenging if the codebase was written more than a few years ago and isn’t actively maintained. And while it’s possible to use two versions of React on the page, until React 17 this has been fragile and caused problems with events.

We’re fixing many of those problems with React 17. This means that **when React 18 and the next future versions come out, you will now have more options**. The first option will be to upgrade your whole app at once, like you might have done before. But you will also have an option to upgrade your app piece by piece. For example, you might decide to migrate most of your app to React 18, but keep some lazy-loaded dialog or a subroute on React 17.

This doesn’t mean you *have to* do gradual upgrades. **For most apps, upgrading all at once is still the best solution.** Loading two versions of React — even if one of them is loaded lazily on demand — is still not ideal. However, for larger apps that aren’t actively maintained, this option makes sense to consider, and React 17 lets those apps not get left behind.

We’ve prepared an [example repository](https://github.com/reactjs/react-gradual-upgrade-demo/) demonstrating how to lazy-load an older version of React if necessary. This demo uses Create React App, but it should be possible to follow a similar approach with any other tool. We welcome demos using other tooling as pull requests.

> Note
>
> We’ve **postponed other changes** until after React 17. The goal of this release is to enable gradual upgrades. If upgrading to React 17 were too difficult, it would defeat its purpose.

## [](#changes-to-event-delegation)Changes to Event Delegation

To enable gradual updates, we’ve needed to make some changes to the React event system. React 17 is a major release because these changes are potentially breaking. You can check out our [versioning FAQ](/docs/faq-versioning.html#breaking-changes) to learn more about our commitment to stability.

In React 17, React will no longer attach event handlers at the `document` level under the hood. Instead, it will attach them to the root DOM container into which your React tree is rendered:

```
const rootNode = document.getElementById('root');
ReactDOM.render(<App />, rootNode);
```

In React 16 and earlier, React would do `document.addEventListener()` for most events. React 17 will call `rootNode.addEventListener()` under the hood instead.

[](/static/bb4b10114882a50090b8ff61b3c4d0fd/31868/react_17_delegation.png)

We’ve confirmed that [numerous](https://github.com/facebook/react/issues/7094) [problems](https://github.com/facebook/react/issues/8693) [reported](https://github.com/facebook/react/issues/12518) [over](https://github.com/facebook/react/issues/13451) [the](https://github.com/facebook/react/issues/4335) [years](https://github.com/facebook/react/issues/1691) [on](https://github.com/facebook/react/issues/285#issuecomment-253502585) [our](https://github.com/facebook/react/pull/8117) [issue](https://github.com/facebook/react/issues/11530) [tracker](https://github.com/facebook/react/issues/7128) related to integrating React with non-React code have been fixed by the new behavior.

If you run into issues with this change, [here’s a common way to resolve them](/blog/2020/08/10/react-v17-rc.html#fixing-potential-issues).

## [](#other-breaking-changes)Other Breaking Changes

[The React 17 RC blog post](/blog/2020/08/10/react-v17-rc.html#other-breaking-changes) describes the rest of the breaking changes in React 17.

We’ve only had to change fewer than twenty components out of 100,000+ in the Facebook product code to work with these changes, so **we expect that most apps can upgrade to React 17 without too much trouble**. Please [tell us](https://github.com/facebook/react/issues) if you run into problems.

## [](#new-jsx-transform)New JSX Transform

React 17 supports the [new JSX transform](/blog/2020/09/22/introducing-the-new-jsx-transform.html). We’ve also backported support for it to React 16.14.0, React 15.7.0, and 0.14.10. Note that it is completely opt-in, and you don’t have to use it. The classic JSX transform will keep working, and there are no plans to stop supporting it.

## [](#react-native)React Native

React Native has a separate release schedule. We landed the support for React 17 in React Native 0.64. As always, you can track the release discussions on the React Native Community releases [issue tracker](https://github.com/react-native-community/releases).

## [](#installation)Installation

To install React 17 with npm, run:

```
npm install react@17.0.0 react-dom@17.0.0
```

To install React 17 with Yarn, run:

```
yarn add react@17.0.0 react-dom@17.0.0
```

We also provide UMD builds of React via a CDN:

```
<script crossorigin src="https://unpkg.com/react@17.0.0/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17.0.0/umd/react-dom.production.min.js"></script>
```

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2020-10-20-react-v17.md)

----
url: https://legacy.reactjs.org/docs/test-renderer.html
----

**Importing**

```
import TestRenderer from 'react-test-renderer'; // ES6
const TestRenderer = require('react-test-renderer'); // ES5 with npm
```

## [](#overview)Overview

This package provides a React renderer that can be used to render React components to pure JavaScript objects, without depending on the DOM or a native mobile environment.

Essentially, this package makes it easy to grab a snapshot of the platform view hierarchy (similar to a DOM tree) rendered by a React DOM or React Native component without using a browser or [jsdom](https://github.com/tmpvar/jsdom).

Example:

```
import TestRenderer from 'react-test-renderer';

function Link(props) {
  return <a href={props.page}>{props.children}</a>;
}

const testRenderer = TestRenderer.create(
  <Link page="https://www.facebook.com/">Facebook</Link>
);

console.log(testRenderer.toJSON());
// { type: 'a',
//   props: { href: 'https://www.facebook.com/' },
//   children: [ 'Facebook' ] }
```

You can use Jest’s snapshot testing feature to automatically save a copy of the JSON tree to a file and check in your tests that it hasn’t changed: [Learn more about it](https://jestjs.io/docs/en/snapshot-testing).

You can also traverse the output to find specific nodes and make assertions about them.

```
import TestRenderer from 'react-test-renderer';

function MyComponent() {
  return (
    <div>
      <SubComponent foo="bar" />
      <p className="my">Hello</p>
    </div>
  )
}

function SubComponent() {
  return (
    <p className="sub">Sub</p>
  );
}

const testRenderer = TestRenderer.create(<MyComponent />);
const testInstance = testRenderer.root;

expect(testInstance.findByType(SubComponent).props.foo).toBe('bar');
expect(testInstance.findByProps({className: "sub"}).children).toEqual(['Sub']);
```

### [](#testrenderer)TestRenderer

* [`TestRenderer.create()`](#testrenderercreate)
* [`TestRenderer.act()`](#testrendereract)

### [](#testrenderer-instance)TestRenderer instance

* [`testRenderer.toJSON()`](#testrenderertojson)
* [`testRenderer.toTree()`](#testrenderertotree)
* [`testRenderer.update()`](#testrendererupdate)
* [`testRenderer.unmount()`](#testrendererunmount)
* [`testRenderer.getInstance()`](#testrenderergetinstance)
* [`testRenderer.root`](#testrendererroot)

### [](#testinstance)TestInstance

* [`testInstance.find()`](#testinstancefind)
* [`testInstance.findByType()`](#testinstancefindbytype)
* [`testInstance.findByProps()`](#testinstancefindbyprops)
* [`testInstance.findAll()`](#testinstancefindall)
* [`testInstance.findAllByType()`](#testinstancefindallbytype)
* [`testInstance.findAllByProps()`](#testinstancefindallbyprops)
* [`testInstance.instance`](#testinstanceinstance)
* [`testInstance.type`](#testinstancetype)
* [`testInstance.props`](#testinstanceprops)
* [`testInstance.parent`](#testinstanceparent)
* [`testInstance.children`](#testinstancechildren)

## [](#reference)Reference

### [](#testrenderercreate)`TestRenderer.create()`

```
TestRenderer.create(element, options);
```

Create a `TestRenderer` instance with the passed React element. It doesn’t use the real DOM, but it still fully renders the component tree into memory so you can make assertions about it. Returns a [TestRenderer instance](#testrenderer-instance).

### [](#testrendereract)`TestRenderer.act()`

```
TestRenderer.act(callback);
```

Similar to the [`act()` helper from `react-dom/test-utils`](/docs/test-utils.html#act), `TestRenderer.act` prepares a component for assertions. Use this version of `act()` to wrap calls to `TestRenderer.create` and `testRenderer.update`.

```
import {create, act} from 'react-test-renderer';
import App from './app.js'; // The component being tested

// render the component
let root; 
act(() => {
  root = create(<App value={1}/>)
});

// make assertions on root 
expect(root.toJSON()).toMatchSnapshot();

// update with some different props
act(() => {
  root.update(<App value={2}/>);
})

// make assertions on root 
expect(root.toJSON()).toMatchSnapshot();
```

### [](#testrenderertojson)`testRenderer.toJSON()`

```
testRenderer.toJSON()
```

Return an object representing the rendered tree. This tree only contains the platform-specific nodes like `<div>` or `<View>` and their props, but doesn’t contain any user-written components. This is handy for [snapshot testing](https://facebook.github.io/jest/docs/en/snapshot-testing.html#snapshot-testing-with-jest).

### [](#testrenderertotree)`testRenderer.toTree()`

```
testRenderer.toTree()
```

Return an object representing the rendered tree. The representation is more detailed than the one provided by `toJSON()`, and includes the user-written components. You probably don’t need this method unless you’re writing your own assertion library on top of the test renderer.

### [](#testrendererupdate)`testRenderer.update()`

```
testRenderer.update(element)
```

Re-render the in-memory tree with a new root element. This simulates a React update at the root. If the new element has the same type and key as the previous element, the tree will be updated; otherwise, it will re-mount a new tree.

### [](#testrendererunmount)`testRenderer.unmount()`

```
testRenderer.unmount()
```

Unmount the in-memory tree, triggering the appropriate lifecycle events.

### [](#testrenderergetinstance)`testRenderer.getInstance()`

```
testRenderer.getInstance()
```

Return the instance corresponding to the root element, if available. This will not work if the root element is a function component because they don’t have instances.

### [](#testrendererroot)`testRenderer.root`

```
testRenderer.root
```

Returns the root “test instance” object that is useful for making assertions about specific nodes in the tree. You can use it to find other “test instances” deeper below.

### [](#testinstancefind)`testInstance.find()`

```
testInstance.find(test)
```

Find a single descendant test instance for which `test(testInstance)` returns `true`. If `test(testInstance)` does not return `true` for exactly one test instance, it will throw an error.

### [](#testinstancefindbytype)`testInstance.findByType()`

```
testInstance.findByType(type)
```

Find a single descendant test instance with the provided `type`. If there is not exactly one test instance with the provided `type`, it will throw an error.

### [](#testinstancefindbyprops)`testInstance.findByProps()`

```
testInstance.findByProps(props)
```

Find a single descendant test instance with the provided `props`. If there is not exactly one test instance with the provided `props`, it will throw an error.

### [](#testinstancefindall)`testInstance.findAll()`

```
testInstance.findAll(test)
```

Find all descendant test instances for which `test(testInstance)` returns `true`.

### [](#testinstancefindallbytype)`testInstance.findAllByType()`

```
testInstance.findAllByType(type)
```

Find all descendant test instances with the provided `type`.

### [](#testinstancefindallbyprops)`testInstance.findAllByProps()`

```
testInstance.findAllByProps(props)
```

Find all descendant test instances with the provided `props`.

### [](#testinstanceinstance)`testInstance.instance`

```
testInstance.instance
```

The component instance corresponding to this test instance. It is only available for class components, as function components don’t have instances. It matches the `this` value inside the given component.

### [](#testinstancetype)`testInstance.type`

```
testInstance.type
```

The component type corresponding to this test instance. For example, a `<Button />` component has a type of `Button`.

### [](#testinstanceprops)`testInstance.props`

```
testInstance.props
```

The props corresponding to this test instance. For example, a `<Button size="small" />` component has `{size: 'small'}` as props.

### [](#testinstanceparent)`testInstance.parent`

```
testInstance.parent
```

The parent test instance of this test instance.

### [](#testinstancechildren)`testInstance.children`

```
testInstance.children
```

The children test instances of this test instance.

## [](#ideas)Ideas

You can pass `createNodeMock` function to `TestRenderer.create` as the option, which allows for custom mock refs. `createNodeMock` accepts the current element and should return a mock ref object. This is useful when you test a component that relies on refs.

```
import TestRenderer from 'react-test-renderer';

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.input = null;
  }
  componentDidMount() {
    this.input.focus();
  }
  render() {
    return <input type="text" ref={el => this.input = el} />
  }
}

let focused = false;
TestRenderer.create(
  <MyComponent />,
  {
    createNodeMock: (element) => {
      if (element.type === 'input') {
        // mock a focus function
        return {
          focus: () => {
            focused = true;
          }
        };
      }
      return null;
    }
  }
);
expect(focused).toBe(true);
```

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/reference-test-renderer.md)

----
url: https://legacy.reactjs.org/docs/hooks-state.html
----

> These docs are old and won’t be updated. Go to [react.dev](https://react.dev/) for the new React docs.
>
> These new documentation pages teach modern React and include live examples:
>
> * [State: A Component’s Memory](https://react.dev/learn/state-a-components-memory)
> * [`useState`](https://react.dev/reference/react/useState)

*Hooks* are a new addition in React 16.8. They let you use state and other React features without writing a class.

The [introduction page](/docs/hooks-intro.html) used this example to get familiar with Hooks:

```
import React, { useState } from 'react';

function Example() {
  // Declare a new state variable, which we'll call "count"  const [count, setCount] = useState(0);
  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}
```

We’ll start learning about Hooks by comparing this code to an equivalent class example.

## [](#equivalent-class-example)Equivalent Class Example

If you used classes in React before, this code should look familiar:

```
class Example extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0
    };
  }

  render() {
    return (
      <div>
        <p>You clicked {this.state.count} times</p>
        <button onClick={() => this.setState({ count: this.state.count + 1 })}>
          Click me
        </button>
      </div>
    );
  }
}
```

The state starts as `{ count: 0 }`, and we increment `state.count` when the user clicks a button by calling `this.setState()`. We’ll use snippets from this class throughout the page.

> Note
>
> You might be wondering why we’re using a counter here instead of a more realistic example. This is to help us focus on the API while we’re still making our first steps with Hooks.

## [](#hooks-and-function-components)Hooks and Function Components

As a reminder, function components in React look like this:

```
const Example = (props) => {
  // You can use Hooks here!
  return <div />;
}
```

or this:

```
function Example(props) {
  // You can use Hooks here!
  return <div />;
}
```

You might have previously known these as “stateless components”. We’re now introducing the ability to use React state from these, so we prefer the name “function components”.

Hooks **don’t** work inside classes. But you can use them instead of writing classes.

## [](#whats-a-hook)What’s a Hook?

Our new example starts by importing the `useState` Hook from React:

```
import React, { useState } from 'react';
function Example() {
  // ...
}
```

**What is a Hook?** A Hook is a special function that lets you “hook into” React features. For example, `useState` is a Hook that lets you add React state to function components. We’ll learn other Hooks later.

**When would I use a Hook?** If you write a function component and realize you need to add some state to it, previously you had to convert it to a class. Now you can use a Hook inside the existing function component. We’re going to do that right now!

> Note:
>
> There are some special rules about where you can and can’t use Hooks within a component. We’ll learn them in [Rules of Hooks](/docs/hooks-rules.html).

## [](#declaring-a-state-variable)Declaring a State Variable

In a class, we initialize the `count` state to `0` by setting `this.state` to `{ count: 0 }` in the constructor:

```
class Example extends React.Component {
  constructor(props) {
    super(props);
    this.state = {      count: 0    };  }
```

In a function component, we have no `this`, so we can’t assign or read `this.state`. Instead, we call the `useState` Hook directly inside our component:

```
import React, { useState } from 'react';

function Example() {
  // Declare a new state variable, which we'll call "count"  const [count, setCount] = useState(0);
```

**What does calling `useState` do?** It declares a “state variable”. Our variable is called `count` but we could call it anything else, like `banana`. This is a way to “preserve” some values between the function calls — `useState` is a new way to use the exact same capabilities that `this.state` provides in a class. Normally, variables “disappear” when the function exits but state variables are preserved by React.

**What do we pass to `useState` as an argument?** The only argument to the `useState()` Hook is the initial state. Unlike with classes, the state doesn’t have to be an object. We can keep a number or a string if that’s all we need. In our example, we just want a number for how many times the user clicked, so pass `0` as initial state for our variable. (If we wanted to store two different values in state, we would call `useState()` twice.)

**What does `useState` return?** It returns a pair of values: the current state and a function that updates it. This is why we write `const [count, setCount] = useState()`. This is similar to `this.state.count` and `this.setState` in a class, except you get them in a pair. If you’re not familiar with the syntax we used, we’ll come back to it [at the bottom of this page](/docs/hooks-state.html#tip-what-do-square-brackets-mean).

Now that we know what the `useState` Hook does, our example should make more sense:

```
import React, { useState } from 'react';

function Example() {
  // Declare a new state variable, which we'll call "count"  const [count, setCount] = useState(0);
```

We declare a state variable called `count`, and set it to `0`. React will remember its current value between re-renders, and provide the most recent one to our function. If we want to update the current `count`, we can call `setCount`.

> Note
>
> You might be wondering: why is `useState` not named `createState` instead?
>
> “Create” wouldn’t be quite accurate because the state is only created the first time our component renders. During the next renders, `useState` gives us the current state. Otherwise it wouldn’t be “state” at all! There’s also a reason why Hook names *always* start with `use`. We’ll learn why later in the [Rules of Hooks](/docs/hooks-rules.html).

## [](#reading-state)Reading State

When we want to display the current count in a class, we read `this.state.count`:

```
  <p>You clicked {this.state.count} times</p>
```

In a function, we can use `count` directly:

```
  <p>You clicked {count} times</p>
```

## [](#updating-state)Updating State

In a class, we need to call `this.setState()` to update the `count` state:

```
  <button onClick={() => this.setState({ count: this.state.count + 1 })}>    Click me
  </button>
```

In a function, we already have `setCount` and `count` as variables so we don’t need `this`:

```
  <button onClick={() => setCount(count + 1)}>    Click me
  </button>
```

## [](#recap)Recap

Let’s now **recap what we learned line by line** and check our understanding.

```
 1:  import React, { useState } from 'react'; 2:
 3:  function Example() {
 4:    const [count, setCount] = useState(0); 5:
 6:    return (
 7:      <div>
 8:        <p>You clicked {count} times</p>
 9:        <button onClick={() => setCount(count + 1)}>10:         Click me
11:        </button>
12:      </div>
13:    );
14:  }
```

* **Line 1:** We import the `useState` Hook from React. It lets us keep local state in a function component.
* **Line 4:** Inside the `Example` component, we declare a new state variable by calling the `useState` Hook. It returns a pair of values, to which we give names. We’re calling our variable `count` because it holds the number of button clicks. We initialize it to zero by passing `0` as the only `useState` argument. The second returned item is itself a function. It lets us update the `count` so we’ll name it `setCount`.
* **Line 9:** When the user clicks, we call `setCount` with a new value. React will then re-render the `Example` component, passing the new `count` value to it.

This might seem like a lot to take in at first. Don’t rush it! If you’re lost in the explanation, look at the code above again and try to read it from top to bottom. We promise that once you try to “forget” how state works in classes, and look at this code with fresh eyes, it will make sense.

### [](#tip-what-do-square-brackets-mean)Tip: What Do Square Brackets Mean?

You might have noticed the square brackets when we declare a state variable:

```
  const [count, setCount] = useState(0);
```

The names on the left aren’t a part of the React API. You can name your own state variables:

```
  const [fruit, setFruit] = useState('banana');
```

This JavaScript syntax is called [“array destructuring”](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Array_destructuring). It means that we’re making two new variables `fruit` and `setFruit`, where `fruit` is set to the first value returned by `useState`, and `setFruit` is the second. It is equivalent to this code:

```
  var fruitStateVariable = useState('banana'); // Returns a pair
  var fruit = fruitStateVariable[0]; // First item in a pair
  var setFruit = fruitStateVariable[1]; // Second item in a pair
```

When we declare a state variable with `useState`, it returns a pair — an array with two items. The first item is the current value, and the second is a function that lets us update it. Using `[0]` and `[1]` to access them is a bit confusing because they have a specific meaning. This is why we use array destructuring instead.

> Note
>
> You might be curious how React knows which component `useState` corresponds to since we’re not passing anything like `this` back to React. We’ll answer [this question](/docs/hooks-faq.html#how-does-react-associate-hook-calls-with-components) and many others in the FAQ section.

### [](#tip-using-multiple-state-variables)Tip: Using Multiple State Variables

Declaring state variables as a pair of `[something, setSomething]` is also handy because it lets us give *different* names to different state variables if we want to use more than one:

```
function ExampleWithManyStates() {
  // Declare multiple state variables!
  const [age, setAge] = useState(42);
  const [fruit, setFruit] = useState('banana');
  const [todos, setTodos] = useState([{ text: 'Learn Hooks' }]);
```

In the above component, we have `age`, `fruit`, and `todos` as local variables, and we can update them individually:

```
  function handleOrangeClick() {
    // Similar to this.setState({ fruit: 'orange' })
    setFruit('orange');
  }
```

You **don’t have to** use many state variables. State variables can hold objects and arrays just fine, so you can still group related data together. However, unlike `this.setState` in a class, updating a state variable always *replaces* it instead of merging it.

We provide more recommendations on splitting independent state variables [in the FAQ](/docs/hooks-faq.html#should-i-use-one-or-many-state-variables).

## [](#next-steps)Next Steps

On this page we’ve learned about one of the Hooks provided by React, called `useState`. We’re also sometimes going to refer to it as the “State Hook”. It lets us add local state to React function components — which we did for the first time ever!

We also learned a little bit more about what Hooks are. Hooks are functions that let you “hook into” React features from function components. Their names always start with `use`, and there are more Hooks we haven’t seen yet.

**Now let’s continue by [learning the next Hook: `useEffect`.](/docs/hooks-effect.html)** It lets you perform side effects in components, and is similar to lifecycle methods in classes.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/hooks-state.md)

* Previous article

  [Hooks at a Glance](/docs/hooks-overview.html)

* Next article

  [Using the Effect Hook](/docs/hooks-effect.html)

----
url: https://18.react.dev/reference/react-dom/client/hydrateRoot
----

[API Reference](/reference/react)

[Client APIs](/reference/react-dom/client)

# hydrateRoot[](#undefined "Link for this heading")

`hydrateRoot` lets you display React components inside a browser DOM node whose HTML content was previously generated by [`react-dom/server`.](/reference/react-dom/server)

```
const root = hydrateRoot(domNode, reactNode, options?)
```

  * [Show a dialog for uncaught errors](#show-a-dialog-for-uncaught-errors)
  * [Displaying Error Boundary errors](#displaying-error-boundary-errors)
  * [Show a dialog for recoverable hydration mismatch errors](#show-a-dialog-for-recoverable-hydration-mismatch-errors)

* [Troubleshooting](#troubleshooting)
  * [I’m getting an error: “You passed a second argument to root.render”](#im-getting-an-error-you-passed-a-second-argument-to-root-render)

***

## Reference[](#reference "Link for Reference ")

### `hydrateRoot(domNode, reactNode, options?)`[](#hydrateroot "Link for this heading")

Call `hydrateRoot` to “attach” React to existing HTML that was already rendered by React in a server environment.

```
import { hydrateRoot } from 'react-dom/client';



const domNode = document.getElementById('root');

const root = hydrateRoot(domNode, reactNode);
```

React will attach to the HTML that exists inside the `domNode`, and take over managing the DOM inside it. An app fully built with React will usually only have one `hydrateRoot` call with its root component.

[See more examples below.](#usage)

#### Parameters[](#parameters "Link for Parameters ")

* `domNode`: A [DOM element](https://developer.mozilla.org/en-US/docs/Web/API/Element) that was rendered as the root element on the server.

* `reactNode`: The “React node” used to render the existing HTML. This will usually be a piece of JSX like `<App />` which was rendered with a `ReactDOM Server` method such as `renderToPipeableStream(<App />)`.

* **optional** `options`: An object with options for this React root.

  * Canary only **optional** `onCaughtError`: Callback called when React catches an error in an Error Boundary. Called with the `error` caught by the Error Boundary, and an `errorInfo` object containing the `componentStack`.
  * Canary only **optional** `onUncaughtError`: Callback called when an error is thrown and not caught by an Error Boundary. Called with the `error` that was thrown and an `errorInfo` object containing the `componentStack`.

***

### `root.render(reactNode)`[](#root-render "Link for this heading")

Call `root.render` to update a React component inside a hydrated React root for a browser DOM element.

```
root.render(<App />);
```

***

### `root.unmount()`[](#root-unmount "Link for this heading")

Call `root.unmount` to destroy a rendered tree inside a React root.

```
root.unmount();
```

***

## Usage[](#usage "Link for Usage ")

### Hydrating server-rendered HTML[](#hydrating-server-rendered-html "Link for Hydrating server-rendered HTML ")

If your app’s HTML was generated by [`react-dom/server`](/reference/react-dom/client/createRoot), you need to *hydrate* it on the client.

```
import { hydrateRoot } from 'react-dom/client';



hydrateRoot(document.getElementById('root'), <App />);
```

This will hydrate the server HTML inside the browser DOM node with the React component for your app. Usually, you will do it once at startup. If you use a framework, it might do this behind the scenes for you.

To hydrate your app, React will “attach” your components’ logic to the initial generated HTML from the server. Hydration turns the initial HTML snapshot from the server into a fully interactive app that runs in the browser.

```
import './styles.css';
import { hydrateRoot } from 'react-dom/client';
import App from './App.js';

hydrateRoot(
  document.getElementById('root'),
  <App />
);
```

***

### Hydrating an entire document[](#hydrating-an-entire-document "Link for Hydrating an entire document ")

Apps fully built with React can render the entire document as JSX, including the [`<html>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/html) tag:

```
function App() {

  return (

    <html>

      <head>

        <meta charSet="utf-8" />

        <meta name="viewport" content="width=device-width, initial-scale=1" />

        <link rel="stylesheet" href="/styles.css"></link>

        <title>My app</title>

      </head>

      <body>

        <Router />

      </body>

    </html>

  );

}
```

To hydrate the entire document, pass the [`document`](https://developer.mozilla.org/en-US/docs/Web/API/Window/document) global as the first argument to `hydrateRoot`:

```
import { hydrateRoot } from 'react-dom/client';

import App from './App.js';



hydrateRoot(document, <App />);
```

***

### Suppressing unavoidable hydration mismatch errors[](#suppressing-unavoidable-hydration-mismatch-errors "Link for Suppressing unavoidable hydration mismatch errors ")

If a single element’s attribute or text content is unavoidably different between the server and the client (for example, a timestamp), you may silence the hydration mismatch warning.

To silence hydration warnings on an element, add `suppressHydrationWarning={true}`:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?parameters=N4IgZglgNgpgziAXKOAnAxgeggOwCYwAeAdAFYLIjoD2OALjPUiBALYAO1qdABAOTFMcOgE9YcYujhw-AbgA6ONp249gPABYi8qAIYMAStWq8AvjzCpqrfqhi70dALR5rmdFAiM6cxcq68AILs7BZWNgKYwexkMgo4ilo6-jBGJgAUrugArqzexADmMHQAorB59ABCIgCSeOl8ViZ8AJQANDwAPNE8mAB8LfEgbSxwlbi6qCJIYLpQcDCmI-wOANa6RbG0SKA09N7MwIo8PPIgOLp5Z4inIHYOdMQEAG5nbce3zzCocBC017cAAzEYGAt4fM6sXS4AFnIQYbD4IixcE4E5nODoVAQdh0OAAo5ok63YSTOiwu72RxOTHY3FwHik7io4m3ABG2WgeAp92ptJxeJ4HK5LOJZwYwh5VOc_PpPAlvCcTkYzwAvORXKxReiQDBSDBHFKHjSsQKGXqDeSQB8lhCQAR2IwCDh0F58Ug1B8dbyrTczgA9ACMAA4QSDtbcfS5rBSg6HQRGzlHZXjYwBWMNg61E21Es4vAAiMEdSJdboJpkUpmGo3GFymMzmCyWIHY2TZniwuAIJA0dFYUB2VFoDCYiBAnQAhEqPgAJAAqAFkADI8Paj3i4X4ELp4CDPHgQPCqpPGK19YiXzqYPfPPofADuugZRRw3xSeDC1h4PTZIh4UaakI3xfKgxCKEq944J0t6Hsep4mGcfSdBogZ9AAwtkqB2PQPAFikNxTkqPCQYCgaYGRmAAEyAjR16ochN77lBNYQGMEwNogszzIsIxoFg0SxEO64HOORAqLwBCzNkUC8GA2QunQfxotE6QtJ6RJ2HQWFoukXpdKhjLZCEdjSLO2h6EptAAOqTEoOAFKqwB0Kg2SLFBrInJh2HeHhBFqG-D5-QwanEHQ1DLtQ6BzDA-EMAAyi5uAFGplZEic9FoR8gxVoorHsfW0xcU2vEgPxQiiOIkjSMJI6iSAABUGknGy1CEDSEAAF7JTcrWoAQqBOK1hDxGliitXg_6EicYAjk4sysNAIg3HAug4HANLfBAYDxCcUKoAUuA3DR7AjR8Kx4HuDk3ICo2KIkgbNTw-2HTgTjhewN27RYc2_J1MDHVRp13QkOAaFRT0vbg73UJ9PC3R8s30B1_3HYCwO5aDGgAMyQ5Mr0w3DCNEkjMpdQDPAhhjOBjWDAAseMHdDH1fYjv3kzcgYAGzU7TGhpozBMs_D32kyjFOBnTvP3WDXOC8zsOsyT7Oo5TQNnTTMs0Du00_cjf0S8QVEwKwIOKDJT0XVdBROLgnhvjSdBkmj0ug_ldaTEV3HNi2DAcFAKTMFi9gME4Ua6CEICmEAA\&query=file%3D%252Fsrc%252FApp.js%26utm_medium%3Dsandpack\&environment=create-react-app "Open in CodeSandbox")

```
export default function App() {
  return (
    <h1 suppressHydrationWarning={true}>
      Current Date: {new Date().toLocaleDateString()}
    </h1>
  );
}
```

This only works one level deep, and is intended to be an escape hatch. Don’t overuse it. Unless it’s text content, React still won’t attempt to patch it up, so it may remain inconsistent until future updates.

***

### Handling different client and server content[](#handling-different-client-and-server-content "Link for Handling different client and server content ")

If you intentionally need to render something different on the server and the client, you can do a two-pass rendering. Components that render something different on the client can read a [state variable](/reference/react/useState) like `isClient`, which you can set to `true` in an [Effect](/reference/react/useEffect):

[Fork](https://codesandbox.io/api/v1/sandboxes/define?parameters=N4IgZglgNgpgziAXKOAnAxgeggOwCYwAeAdAFYLIjoD2OALjPUiBALYAO1qdABAOTFMcOgE9YcYujhw-AbgA6ONp249gPABYi8qAIYMAStWq8AvjzCpqrfqhi70dALR5rmdFAiM6cxcq68AILs7BZWNgKYwexkMgo4ilo6-jBGJgAUrugArqzexADmMHQAorB59ABCIgCSeOl8ViZ8AJQANDwAPNE8mAB8LfEgbSxwlbi6qCJIYLpQcDCmI-wOANa6RbG0SKA09N7MwIo8PPIgOLp5Z4inIHYOdMQEAG5nbce3zzCocBC017cAAzEYGAt4fM6sXS4AFnIQYbD4IixcE4E5nODoVAQdh0OAAo5ok63YSTOiwu72RxOTHY3FwHik7io4m3ABG2WgeAp92ptJxeJ4HK5LOJZwYwh5VOc_PpPAlvCcTkYzwAvORXKxReiQDBSDBHFKHjSsQKGXqDeSQB8lhCQAR2IwCDh0F58Ug1B8dbyrTczgA9ACMAA4QSDtbcfS5rBSg6HQRGzlHZXjYwBWMNg61E21Es4vAAiMEdSJdboJpkUpmGo3GFymMzmCyWIHY2TZniwuAIJA0dFYUB2VFoDCYiBAnQAhEqPgAJAAqAFkADI8Paj3i4X4ELp4CDPHgQPCqpPGK19YiXzqYPfPPofADuugZRRw3xSeDC1h4PTZIh4UaakI3xfKgxCKEq944J0t6Hsep4mGcfSdBogZ9DUDIAMogd816ochN77lBNYQGMEwNogszzIsIxoFg0SxEO64HOO_iqOo2QLJhdApB0nEwCUYBgJaPDmJY35JtKZzxIoRAqLwBCzNkUC8GA2QunQfxotE6QtJ6RJ7MIPAANqkQAwp43gdAsdAYRZXj0AAujwqo8Px3EpOkVELIMigfPxgnCY46S6S5fT6ayNl2ZZ9DpHQqDZDAvk5h0xmOclHx2HQ2SoGi6Rel0-EFScwDmTFvAAPz8BhPD2d4fA8DcfA1dhqCgXwlZEiceFoR8yWdSRZH1tMlFNjRIB0UIojiJI0hMSOLEgAAVBFQrUIQNIQAAXrgBQ3GyXAEKgTgHYQ8SdYoB14P-hInGAI5OLMrDQCINxwLoOBwDS3wQGA8QnFCqAFLgNwAEyAuwZ0fCseB7jge08IC51-TgqGrYDwM4E4dDUOwNxIx8930JtW0wGDoOQ8jCSo6D6OTJj2O4_j_0WA9vyk2DENQzgF2owAzHTQO4IzeOIyzRMyttZM8CGlNVijGgACyCwzOOiwTRISyT0uBgAbHLPMK2mKvC2rzOE2zUs3IGisG7zGi6ybWNm2LFvE-zOsU9zvM0Dut2s-7Vsy8QoMwKwVOKMpq0w3DBROLgnhvjSPHcJzdso4NdaTCN3mLC2DAcFAKTMFi9gME4Ua6CEICmEAA\&query=file%3D%252Fsrc%252FApp.js%26utm_medium%3Dsandpack\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useEffect } from "react";

export default function App() {
  const [isClient, setIsClient] = useState(false);

  useEffect(() => {
    setIsClient(true);
  }, []);

  return (
    <h1>
      {isClient ? 'Is Client' : 'Is Server'}
    </h1>
  );
}
```

This way the initial render pass will render the same content as the server, avoiding mismatches, but an additional pass will happen synchronously right after hydration.

### Pitfall

This approach makes hydration slower because your components have to render twice. Be mindful of the user experience on slow connections. The JavaScript code may load significantly later than the initial HTML render, so rendering a different UI immediately after hydration may also feel jarring to the user.

***

### Updating a hydrated root component[](#updating-a-hydrated-root-component "Link for Updating a hydrated root component ")

After the root has finished hydrating, you can call [`root.render`](#root-render) to update the root React component. **Unlike with [`createRoot`](/reference/react-dom/client/createRoot), you don’t usually need to do this because the initial content was already rendered as HTML.**

If you call `root.render` at some point after hydration, and the component tree structure matches up with what was previously rendered, React will [preserve the state.](/learn/preserving-and-resetting-state) Notice how you can type in the input, which means that the updates from repeated `render` calls every second in this example are not destructive:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?parameters=N4IgZglgNgpgziAXKOAnAxgeggOwCYwAeAdAFYLIjoD2OALjPUiBALYAO1qdABMDwAsAnnlQBDBgCVq1XgF8eYVNVY8A5Khhj0dALR4VmdFAiM6agNwAdHG07d1xTHDpDYcYujhxLNu114AQXZ2RWVVNSdg9jIfaxwbGhwXHmVZHgBeQRFxKRk6AAobHh4DdABXVjNiAHMYOgBRWCr6ACEhAEk8Ao18tQBKABpingAeaJ4acvoYVAzgAAYFTAA-G374m1heCEyeBfi4eo6Z1AA3MSgCgv7Mlb4RtLpiTXxZgvGQyepphjngCDLFYbEYQADUYPickGPAAjAsESCcCBBiw4K1cGJUEIkGBLkdoSB2NoANZiOqxWhIUBJBhMRAgYAjKwgHBiKosxA8FmabTPAhnFnDHAlFlnWZwCC0TnckALYjyhZC5kgVhiXAylnODDYN4kcjKkWyuDoVAQdh0OAyplG0UgFxYuiakC8nS6E1mi1wHgO7iGkp2gBG5WgeGdrr0HvNlp4wdD_oDLIYLnDWjdUa9PGTvF0ukYZwy5AMrATdpgpBgOlTfPdpuj3vLladIBG0JVBHYjAIOHQpitSAettlEedAD1YQAOBUK0vDtN6YtjyfTpUokZ2iO1z2WscAVhXLNbwrtAoAIjBO28e33rXIbHIUWiMWzsbj8TBCexyoGTFhcAQSAEOhWCgakqFoOk6GYUYAEJcxGQIoCgHgAAkABUAFkABlvhmegeFwSUCDGPAIDOAi8AyHl8hZFZiHo0ZMFIs57gAdzEK0jTqHBZgkGA8FjIRUi7WZcBqMYJlWHhWIgOgBGEmti2cWZxVQYgbFzNYcFGZiKKol0aJAFZRgEWEVhQmAkOoGFWK4KA8BgsY4N0HhNIWRjTOM3Av14dgoG0GABGoezZn0tChE7H0VHqAQxMEWYYC1YymLIrTHwgdFMVfRA8SgAlUTQLBoliMDaTMZgiHsXgCDxcooF4MBph0KURWiApgCmU45FuG0Sk0OhylQEUiiHUYtIDAMTLMiyrJsuyHL4Tq_jkDyzPXSbvPKXz_PQQLgoIOYWXCyK4GiuS4oEBKWR4VZ1sY8aeCRO9kVRDLnyxHEcvfQlCucVx3E8bxSog8qGQAKkHEpA2oQh3QgAAvMSuWh1ADt0aHCChGwbGhvAhN6xQIN0PFWGgIQuTgMRkndUSwHiEo1VQGpcC5AAmBZ2ExkZiTwUicBqLkDnvbGcFMyGeEZ5mcF0OhqHYQX6cJ-g4fhmA2dZzmsYSUXWfFyXcBluWFZGMAiclVW2Y5rmcGemwBAAZj1rEpcN-X9kV03lfNtW4QnTXhe1gQABYnaZg3ZbdoWjU9yMEZ92EADZ_ZtkWBF3UOXYj43o7NuOuVhIPk9t0WE4z8Ojfdk3c4tuENet4uaGIgmY5V-PiFZmBWC1mw6vFnm-ZqXRcBMHj3ToR1LaLkX0syl9PtyglCQYDh_IYZhTS0BhdE3MQQhAOQgA\&query=file%3D%252Fsrc%252Findex.js%26utm_medium%3Dsandpack\&environment=create-react-app "Open in CodeSandbox")

```
import { hydrateRoot } from 'react-dom/client';
import './styles.css';
import App from './App.js';

const root = hydrateRoot(
  document.getElementById('root'),
  <App counter={0} />
);

let i = 0;
setInterval(() => {
  root.render(<App counter={i} />);
  i++;
}, 1000);
```

It is uncommon to call [`root.render`](#root-render) on a hydrated root. Usually, you’ll [update state](/reference/react/useState) inside one of the components instead.

### Show a dialog for uncaught errors[](#show-a-dialog-for-uncaught-errors "Link for Show a dialog for uncaught errors ")

### Canary

`onUncaughtError` is only available in the latest React Canary release.

By default, React will log all uncaught errors to the console. To implement your own error reporting, you can provide the optional `onUncaughtError` root option:

```
import { hydrateRoot } from 'react-dom/client';



const root = hydrateRoot(

  document.getElementById('root'),

  <App />,

  {

    onUncaughtError: (error, errorInfo) => {

      console.error(

        'Uncaught error',

        error,

        errorInfo.componentStack

      );

    }

  }

);

root.render(<App />);
```

The onUncaughtError option is a function called with two arguments:

1. The error that was thrown.
2. An errorInfo object that contains the componentStack of the error.

You can use the `onUncaughtError` root option to display error dialogs:

```
import { hydrateRoot } from "react-dom/client";
import App from "./App.js";
import {reportUncaughtError} from "./reportError";
import "./styles.css";
import {renderToString} from 'react-dom/server';

const container = document.getElementById("root");
const root = hydrateRoot(container, <App />, {
  onUncaughtError: (error, errorInfo) => {
    if (error.message !== 'Known error') {
      reportUncaughtError({
        error,
        componentStack: errorInfo.componentStack
      });
    }
  }
});
```

### Displaying Error Boundary errors[](#displaying-error-boundary-errors "Link for Displaying Error Boundary errors ")

### Canary

`onCaughtError` is only available in the latest React Canary release.

By default, React will log all errors caught by an Error Boundary to `console.error`. To override this behavior, you can provide the optional `onCaughtError` root option for errors caught by an [Error Boundary](/reference/react/Component#catching-rendering-errors-with-an-error-boundary):

```
import { hydrateRoot } from 'react-dom/client';



const root = hydrateRoot(

  document.getElementById('root'),

  <App />,

  {

    onCaughtError: (error, errorInfo) => {

      console.error(

        'Caught error',

        error,

        errorInfo.componentStack

      );

    }

  }

);

root.render(<App />);
```

The onCaughtError option is a function called with two arguments:

1. The error that was caught by the boundary.
2. An errorInfo object that contains the componentStack of the error.

You can use the `onCaughtError` root option to display error dialogs or filter known errors from logging:

```
import { hydrateRoot } from "react-dom/client";
import App from "./App.js";
import {reportCaughtError} from "./reportError";
import "./styles.css";

const container = document.getElementById("root");
const root = hydrateRoot(container, <App />, {
  onCaughtError: (error, errorInfo) => {
    if (error.message !== 'Known error') {
      reportCaughtError({
        error,
        componentStack: errorInfo.componentStack
      });
    }
  }
});
```

### Show a dialog for recoverable hydration mismatch errors[](#show-a-dialog-for-recoverable-hydration-mismatch-errors "Link for Show a dialog for recoverable hydration mismatch errors ")

When React encounters a hydration mismatch, it will automatically attempt to recover by rendering on the client. By default, React will log hydration mismatch errors to `console.error`. To override this behavior, you can provide the optional `onRecoverableError` root option:

```
import { hydrateRoot } from 'react-dom/client';



const root = hydrateRoot(

  document.getElementById('root'),

  <App />,

  {

    onRecoverableError: (error, errorInfo) => {

      console.error(

        'Caught error',

        error,

        error.cause,

        errorInfo.componentStack

      );

    }

  }

);
```

The onRecoverableError option is a function called with two arguments:

1. The error React throws. Some errors may include the original cause as error.cause.
2. An errorInfo object that contains the componentStack of the error.

You can use the `onRecoverableError` root option to display error dialogs for hydration mismatches:

```
import { hydrateRoot } from "react-dom/client";
import App from "./App.js";
import {reportRecoverableError} from "./reportError";
import "./styles.css";

const container = document.getElementById("root");
const root = hydrateRoot(container, <App />, {
  onRecoverableError: (error, errorInfo) => {
    reportRecoverableError({
      error,
      cause: error.cause,
      componentStack: errorInfo.componentStack
    });
  }
});
```

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### I’m getting an error: “You passed a second argument to root.render”[](#im-getting-an-error-you-passed-a-second-argument-to-root-render "Link for I’m getting an error: “You passed a second argument to root.render” ")

A common mistake is to pass the options for `hydrateRoot` to `root.render(...)`:

Console

Warning: You passed a second argument to root.render(…) but it only accepts one argument.

To fix, pass the root options to `hydrateRoot(...)`, not `root.render(...)`:

```
// 🚩 Wrong: root.render only takes one argument.

root.render(App, {onUncaughtError});



// ✅ Correct: pass options to createRoot.

const root = hydrateRoot(container, <App />, {onUncaughtError});
```

[PreviouscreateRoot](/reference/react-dom/client/createRoot)

[NextServer APIs](/reference/react-dom/server)

***

----
url: https://18.react.dev/reference/react-dom/client/createRoot
----

[API Reference](/reference/react)

[Client APIs](/reference/react-dom/client)

# createRoot[](#undefined "Link for this heading")

`createRoot` lets you create a root to display React components inside a browser DOM node.

```
const root = createRoot(domNode, options?)
```

  * [Show a dialog for uncaught errors](#show-a-dialog-for-uncaught-errors)
  * [Displaying Error Boundary errors](#displaying-error-boundary-errors)
  * [Displaying a dialog for recoverable errors](#displaying-a-dialog-for-recoverable-errors)

* [Troubleshooting](#troubleshooting)

  * [I’ve created a root, but nothing is displayed](#ive-created-a-root-but-nothing-is-displayed)
  * [I’m getting an error: “You passed a second argument to root.render”](#im-getting-an-error-you-passed-a-second-argument-to-root-render)
  * [I’m getting an error: “Target container is not a DOM element”](#im-getting-an-error-target-container-is-not-a-dom-element)
  * [I’m getting an error: “Functions are not valid as a React child.”](#im-getting-an-error-functions-are-not-valid-as-a-react-child)
  * [My server-rendered HTML gets re-created from scratch](#my-server-rendered-html-gets-re-created-from-scratch)

***

## Reference[](#reference "Link for Reference ")

### `createRoot(domNode, options?)`[](#createroot "Link for this heading")

Call `createRoot` to create a React root for displaying content inside a browser DOM element.

```
import { createRoot } from 'react-dom/client';



const domNode = document.getElementById('root');

const root = createRoot(domNode);
```

React will create a root for the `domNode`, and take over managing the DOM inside it. After you’ve created a root, you need to call [`root.render`](#root-render) to display a React component inside of it:

```
root.render(<App />);
```

An app fully built with React will usually only have one `createRoot` call for its root component. A page that uses “sprinkles” of React for parts of the page may have as many separate roots as needed.

[See more examples below.](#usage)

#### Parameters[](#parameters "Link for Parameters ")

* `domNode`: A [DOM element.](https://developer.mozilla.org/en-US/docs/Web/API/Element) React will create a root for this DOM element and allow you to call functions on the root, such as `render` to display rendered React content.

* **optional** `options`: An object with options for this React root.

  * Canary only **optional** `onCaughtError`: Callback called when React catches an error in an Error Boundary. Called with the `error` caught by the Error Boundary, and an `errorInfo` object containing the `componentStack`.
  * Canary only **optional** `onUncaughtError`: Callback called when an error is thrown and not caught by an Error Boundary. Called with the `error` that was thrown, and an `errorInfo` object containing the `componentStack`.

***

### `root.render(reactNode)`[](#root-render "Link for this heading")

Call `root.render` to display a piece of [JSX](/learn/writing-markup-with-jsx) (“React node”) into the React root’s browser DOM node.

```
root.render(<App />);
```

***

### `root.unmount()`[](#root-unmount "Link for this heading")

Call `root.unmount` to destroy a rendered tree inside a React root.

```
root.unmount();
```

***

## Usage[](#usage "Link for Usage ")

### Rendering an app fully built with React[](#rendering-an-app-fully-built-with-react "Link for Rendering an app fully built with React ")

If your app is fully built with React, create a single root for your entire app.

```
import { createRoot } from 'react-dom/client';



const root = createRoot(document.getElementById('root'));

root.render(<App />);
```

Usually, you only need to run this code once at startup. It will:

1. Find the browser DOM node defined in your HTML.
2. Display the React component for your app inside.

```
import { createRoot } from 'react-dom/client';
import App from './App.js';
import './styles.css';

const root = createRoot(document.getElementById('root'));
root.render(<App />);
```

**If your app is fully built with React, you shouldn’t need to create any more roots, or to call [`root.render`](#root-render) again.**

From this point on, React will manage the DOM of your entire app. To add more components, [nest them inside the `App` component.](/learn/importing-and-exporting-components) When you need to update the UI, each of your components can do this by [using state.](/reference/react/useState) When you need to display extra content like a modal or a tooltip outside the DOM node, [render it with a portal.](/reference/react-dom/createPortal)

### Note

When your HTML is empty, the user sees a blank page until the app’s JavaScript code loads and runs:

```
<div id="root"></div>
```

This can feel very slow! To solve this, you can generate the initial HTML from your components [on the server or during the build.](/reference/react-dom/server) Then your visitors can read text, see images, and click links before any of the JavaScript code loads. We recommend [using a framework](/learn/start-a-new-react-project#production-grade-react-frameworks) that does this optimization out of the box. Depending on when it runs, this is called *server-side rendering (SSR)* or *static site generation (SSG).*

### Pitfall

**Apps using server rendering or static generation must call [`hydrateRoot`](/reference/react-dom/client/hydrateRoot) instead of `createRoot`.** React will then *hydrate* (reuse) the DOM nodes from your HTML instead of destroying and re-creating them.

***

### Rendering a page partially built with React[](#rendering-a-page-partially-built-with-react "Link for Rendering a page partially built with React ")

If your page [isn’t fully built with React](/learn/add-react-to-an-existing-project#using-react-for-a-part-of-your-existing-page), you can call `createRoot` multiple times to create a root for each top-level piece of UI managed by React. You can display different content in each root by calling [`root.render`.](#root-render)

Here, two different React components are rendered into two DOM nodes defined in the `index.html` file:

```
import './styles.css';
import { createRoot } from 'react-dom/client';
import { Comments, Navigation } from './Components.js';

const navDomNode = document.getElementById('navigation');
const navRoot = createRoot(navDomNode); 
navRoot.render(<Navigation />);

const commentDomNode = document.getElementById('comments');
const commentRoot = createRoot(commentDomNode); 
commentRoot.render(<Comments />);
```

You could also create a new DOM node with [`document.createElement()`](https://developer.mozilla.org/en-US/docs/Web/API/Document/createElement) and add it to the document manually.

```
const domNode = document.createElement('div');

const root = createRoot(domNode); 

root.render(<Comment />);

document.body.appendChild(domNode); // You can add it anywhere in the document
```

To remove the React tree from the DOM node and clean up all the resources used by it, call [`root.unmount`.](#root-unmount)

```
root.unmount();
```

This is mostly useful if your React components are inside an app written in a different framework.

***

### Updating a root component[](#updating-a-root-component "Link for Updating a root component ")

You can call `render` more than once on the same root. As long as the component tree structure matches up with what was previously rendered, React will [preserve the state.](/learn/preserving-and-resetting-state) Notice how you can type in the input, which means that the updates from repeated `render` calls every second in this example are not destructive:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?parameters=N4IgZglgNgpgziAXKOAnAxgeggOwCYwAeAdAFYLIjoD2OALjPUiBALYAO1qdABMD-lQwAhgwBK1arwC-PMKmqseAciHD0dALR5FmdFAiM6ygNwAdHG07cVxTHDoBPWHGLo4cUxatdeAQXZ2OQUlZTsA9jJPcxwLGhwHHgUpHgBeATVxSToACh10AFdWI2IAcxg6AFFYYvoAIUcASTwc1WzlAEoOmItYXgg0ngAGGLgKxvoYVAA3YSgcnI60gD4-Cx4k7OIhfCmcgB4IgWoCydRU4AhZTGXu9Z4IAGpHmOkAGh4ARiGfu5wQN4sOB1XDCVCOJBgOZjd4gdjqADWwnKUVoSFA8QYTEQIGA9zMIBwwmKBMQPAJag0xAI0wJb3xIGmUzgEFopPJICGxC5QzpDNYwlw7IJ9gw2F2JHIfJwGwJcEEEHYdDg7LxMo2HIcYLowpAlK08tQiuVPC13GlGo5ACMCtA8Lr9ZpDca4DwbXaLRqCQwHA6RBonQqla6fbxNJpGNNUuQdKxPbKQDBSDANH71AagyakymdSB7u8GQR2IwCDh0IYVUg1uqE_rdQA9T4ADm53PjHMdsYbzdbvIB91r_ozRuDDYArL2Cfn6eqCTSACIwYu7MsV1XSCzSAFAkFE8GQ6EwWHsApWgxYXAEEgACzorCg6KotCxdGY-wAhPOAPIAYQAKgAmgACpUPC3veywWPs4FQDwUDCDgpSpASjAEpBODQSIeDoRs-zFHQwgCNeYJjHQyEgAAqn-ABimhNmh9x4RUhFEsU5HTIYADu1i5sckz0ORnEQHgdDXqkNIQOgMCaEJInXh8uAQHQEBzIGcwwKknxtiAOE8Psyl0LAyzztQhS1HQ-yYAZRlQZg15Yeh-xWtQeCOLp-x4BA0wPHg5HJLmyyWZ50yOZgzmuaFMHLNuEDAqC-6IFCUAwoCaBYBEUSPpiRjMEQPE8AQUIFFAvBgKcGisjKEQ5MANCnAwqDSEsaobEIdAFKgMo5AOem6Za0GfMsAASMBQFA1AfJxXBQHg758HVZzSJZ16DT1uG4CevDsPBUnXtQM1TORf6OMWpqKBU164KUYFTDABI8DcPWWbpfwbv8gKxbuYIQolh6wml9hOC4bgeFlz45TiABU1YbM5hBOhAABeV1ks5qAEKgmhw68FgWOFjgw3Iz6aFCrDQI4ZJwAhcBOlMEBgDEGwCqgpS4GSABMQzsIQjM8PCeCeYhZIjJuuM4CthPM6zOCaHQ1DsMLvNgMTLKIzAHPs9zOOxOL7OS2C0uy_Liv3Mr9AI2rHNczzos69eADM-ss7gRsK8MSsq0j6tfE2Wu2xY14ACxO4bctuyL6pmwaXtkp8ABsfs4G9AdjiHLthybkee5bXyB4nyfi3Hacyxn7um9n3ufJrNtJ2LNAEITUcW5XxDszArDaxYxWE_zgulJouAGDg0lmnQVv52LMVxXuP1JTCsIMBw8EMMwggiAwmiOsIgQgNIQA\&query=file%3D%252Fsrc%252Findex.js%26utm_medium%3Dsandpack\&environment=create-react-app "Open in CodeSandbox")

```
import { createRoot } from 'react-dom/client';
import './styles.css';
import App from './App.js';

const root = createRoot(document.getElementById('root'));

let i = 0;
setInterval(() => {
  root.render(<App counter={i} />);
  i++;
}, 1000);
```

It is uncommon to call `render` multiple times. Usually, your components will [update state](/reference/react/useState) instead.

### Show a dialog for uncaught errors[](#show-a-dialog-for-uncaught-errors "Link for Show a dialog for uncaught errors ")

### Canary

`onUncaughtError` is only available in the latest React Canary release.

By default, React will log all uncaught errors to the console. To implement your own error reporting, you can provide the optional `onUncaughtError` root option:

```
import { createRoot } from 'react-dom/client';



const root = createRoot(

  document.getElementById('root'),

  {

    onUncaughtError: (error, errorInfo) => {

      console.error(

        'Uncaught error',

        error,

        errorInfo.componentStack

      );

    }

  }

);

root.render(<App />);
```

The onUncaughtError option is a function called with two arguments:

1. The error that was thrown.
2. An errorInfo object that contains the componentStack of the error.

You can use the `onUncaughtError` root option to display error dialogs:

```
import { createRoot } from "react-dom/client";
import App from "./App.js";
import {reportUncaughtError} from "./reportError";
import "./styles.css";

const container = document.getElementById("root");
const root = createRoot(container, {
  onUncaughtError: (error, errorInfo) => {
    if (error.message !== 'Known error') {
      reportUncaughtError({
        error,
        componentStack: errorInfo.componentStack
      });
    }
  }
});
root.render(<App />);
```

### Displaying Error Boundary errors[](#displaying-error-boundary-errors "Link for Displaying Error Boundary errors ")

### Canary

`onCaughtError` is only available in the latest React Canary release.

By default, React will log all errors caught by an Error Boundary to `console.error`. To override this behavior, you can provide the optional `onCaughtError` root option to handle errors caught by an [Error Boundary](/reference/react/Component#catching-rendering-errors-with-an-error-boundary):

```
import { createRoot } from 'react-dom/client';



const root = createRoot(

  document.getElementById('root'),

  {

    onCaughtError: (error, errorInfo) => {

      console.error(

        'Caught error',

        error,

        errorInfo.componentStack

      );

    }

  }

);

root.render(<App />);
```

The onCaughtError option is a function called with two arguments:

1. The error that was caught by the boundary.
2. An errorInfo object that contains the componentStack of the error.

You can use the `onCaughtError` root option to display error dialogs or filter known errors from logging:

```
import { createRoot } from "react-dom/client";
import App from "./App.js";
import {reportCaughtError} from "./reportError";
import "./styles.css";

const container = document.getElementById("root");
const root = createRoot(container, {
  onCaughtError: (error, errorInfo) => {
    if (error.message !== 'Known error') {
      reportCaughtError({
        error, 
        componentStack: errorInfo.componentStack,
      });
    }
  }
});
root.render(<App />);
```

### Displaying a dialog for recoverable errors[](#displaying-a-dialog-for-recoverable-errors "Link for Displaying a dialog for recoverable errors ")

React may automatically render a component a second time to attempt to recover from an error thrown in render. If successful, React will log a recoverable error to the console to notify the developer. To override this behavior, you can provide the optional `onRecoverableError` root option:

```
import { createRoot } from 'react-dom/client';



const root = createRoot(

  document.getElementById('root'),

  {

    onRecoverableError: (error, errorInfo) => {

      console.error(

        'Recoverable error',

        error,

        error.cause,

        errorInfo.componentStack,

      );

    }

  }

);

root.render(<App />);
```

The onRecoverableError option is a function called with two arguments:

1. The error that React throws. Some errors may include the original cause as error.cause.
2. An errorInfo object that contains the componentStack of the error.

You can use the `onRecoverableError` root option to display error dialogs:

```
import { createRoot } from "react-dom/client";
import App from "./App.js";
import {reportRecoverableError} from "./reportError";
import "./styles.css";

const container = document.getElementById("root");
const root = createRoot(container, {
  onRecoverableError: (error, errorInfo) => {
    reportRecoverableError({
      error,
      cause: error.cause,
      componentStack: errorInfo.componentStack,
    });
  }
});
root.render(<App />);
```

***

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### I’ve created a root, but nothing is displayed[](#ive-created-a-root-but-nothing-is-displayed "Link for I’ve created a root, but nothing is displayed ")

Make sure you haven’t forgotten to actually *render* your app into the root:

```
import { createRoot } from 'react-dom/client';

import App from './App.js';



const root = createRoot(document.getElementById('root'));

root.render(<App />);
```

Until you do that, nothing is displayed.

***

### I’m getting an error: “You passed a second argument to root.render”[](#im-getting-an-error-you-passed-a-second-argument-to-root-render "Link for I’m getting an error: “You passed a second argument to root.render” ")

A common mistake is to pass the options for `createRoot` to `root.render(...)`:

Console

Warning: You passed a second argument to root.render(…) but it only accepts one argument.

To fix, pass the root options to `createRoot(...)`, not `root.render(...)`:

```
// 🚩 Wrong: root.render only takes one argument.

root.render(App, {onUncaughtError});



// ✅ Correct: pass options to createRoot.

const root = createRoot(container, {onUncaughtError}); 

root.render(<App />);
```

***

### I’m getting an error: “Target container is not a DOM element”[](#im-getting-an-error-target-container-is-not-a-dom-element "Link for I’m getting an error: “Target container is not a DOM element” ")

This error means that whatever you’re passing to `createRoot` is not a DOM node.

If you’re not sure what’s happening, try logging it:

```
const domNode = document.getElementById('root');

console.log(domNode); // ???

const root = createRoot(domNode);

root.render(<App />);
```

For example, if `domNode` is `null`, it means that [`getElementById`](https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementById) returned `null`. This will happen if there is no node in the document with the given ID at the time of your call. There may be a few reasons for it:

1. The ID you’re looking for might differ from the ID you used in the HTML file. Check for typos!
2. Your bundle’s `<script>` tag cannot “see” any DOM nodes that appear *after* it in the HTML.

Another common way to get this error is to write `createRoot(<App />)` instead of `createRoot(domNode)`.

***

### I’m getting an error: “Functions are not valid as a React child.”[](#im-getting-an-error-functions-are-not-valid-as-a-react-child "Link for I’m getting an error: “Functions are not valid as a React child.” ")

This error means that whatever you’re passing to `root.render` is not a React component.

This may happen if you call `root.render` with `Component` instead of `<Component />`:

```
// 🚩 Wrong: App is a function, not a Component.

root.render(App);



// ✅ Correct: <App /> is a component.

root.render(<App />);
```

Or if you pass a function to `root.render`, instead of the result of calling it:

```
// 🚩 Wrong: createApp is a function, not a component.

root.render(createApp);



// ✅ Correct: call createApp to return a component.

root.render(createApp());
```

***

### My server-rendered HTML gets re-created from scratch[](#my-server-rendered-html-gets-re-created-from-scratch "Link for My server-rendered HTML gets re-created from scratch ")

If your app is server-rendered and includes the initial HTML generated by React, you might notice that creating a root and calling `root.render` deletes all that HTML, and then re-creates all the DOM nodes from scratch. This can be slower, resets focus and scroll positions, and may lose other user input.

Server-rendered apps must use [`hydrateRoot`](/reference/react-dom/client/hydrateRoot) instead of `createRoot`:

```
import { hydrateRoot } from 'react-dom/client';

import App from './App.js';



hydrateRoot(

  document.getElementById('root'),

  <App />

);
```

Note that its API is different. In particular, usually there will be no further `root.render` call.

[PreviousClient APIs](/reference/react-dom/client)

[NexthydrateRoot](/reference/react-dom/client/hydrateRoot)

***

----
url: https://18.react.dev/learn/passing-props-to-a-component
----

```
function Avatar() {
  return (
    <img
      className="avatar"
      src="https://i.imgur.com/1bX5QH6.jpg"
      alt="Lin Lanying"
      width={100}
      height={100}
    />
  );
}

export default function Profile() {
  return (
    <Avatar />
  );
}
```

The props you can pass to an `<img>` tag are predefined (ReactDOM conforms to [the HTML standard](https://www.w3.org/TR/html52/semantics-embedded-content.html#the-img-element)). But you can pass any props to *your own* components, such as `<Avatar>`, to customize them. Here’s how!

## Passing props to a component[](#passing-props-to-a-component "Link for Passing props to a component ")

In this code, the `Profile` component isn’t passing any props to its child component, `Avatar`:

```
export default function Profile() {

  return (

    <Avatar />

  );

}
```

You can give `Avatar` some props in two steps.

### Step 1: Pass props to the child component[](#step-1-pass-props-to-the-child-component "Link for Step 1: Pass props to the child component ")

First, pass some props to `Avatar`. For example, let’s pass two props: `person` (an object), and `size` (a number):

```
export default function Profile() {

  return (

    <Avatar

      person={{ name: 'Lin Lanying', imageId: '1bX5QH6' }}

      size={100}

    />

  );

}
```

### Note

If double curly braces after `person=` confuse you, recall [they’re merely an object](/learn/javascript-in-jsx-with-curly-braces#using-double-curlies-css-and-other-objects-in-jsx) inside the JSX curlies.

Now you can read these props inside the `Avatar` component.

### Step 2: Read props inside the child component[](#step-2-read-props-inside-the-child-component "Link for Step 2: Read props inside the child component ")

You can read these props by listing their names `person, size` separated by the commas inside `({` and `})` directly after `function Avatar`. This lets you use them inside the `Avatar` code, like you would with a variable.

```
function Avatar({ person, size }) {

  // person and size are available here

}
```

Add some logic to `Avatar` that uses the `person` and `size` props for rendering, and you’re done.

Now you can configure `Avatar` to render in many different ways with different props. Try tweaking the values!

```
import { getImageUrl } from './utils.js';

function Avatar({ person, size }) {
  return (
    <img
      className="avatar"
      src={getImageUrl(person)}
      alt={person.name}
      width={size}
      height={size}
    />
  );
}

export default function Profile() {
  return (
    <div>
      <Avatar
        size={100}
        person={{ 
          name: 'Katsuko Saruhashi', 
          imageId: 'YfeOqp2'
        }}
      />
      <Avatar
        size={80}
        person={{
          name: 'Aklilu Lemma', 
          imageId: 'OKS67lh'
        }}
      />
      <Avatar
        size={50}
        person={{ 
          name: 'Lin Lanying',
          imageId: '1bX5QH6'
        }}
      />
    </div>
  );
}
```

Props let you think about parent and child components independently. For example, you can change the `person` or the `size` props inside `Profile` without having to think about how `Avatar` uses them. Similarly, you can change how the `Avatar` uses these props, without looking at the `Profile`.

You can think of props like “knobs” that you can adjust. They serve the same role as arguments serve for functions—in fact, props *are* the only argument to your component! React component functions accept a single argument, a `props` object:

```
function Avatar(props) {

  let person = props.person;

  let size = props.size;

  // ...

}
```

Usually you don’t need the whole `props` object itself, so you destructure it into individual props.

### Pitfall

**Don’t miss the pair of `{` and `}` curlies** inside of `(` and `)` when declaring props:

```
function Avatar({ person, size }) {

  // ...

}
```

This syntax is called [“destructuring”](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Unpacking_fields_from_objects_passed_as_a_function_parameter) and is equivalent to reading properties from a function parameter:

```
function Avatar(props) {

  let person = props.person;

  let size = props.size;

  // ...

}
```

## Specifying a default value for a prop[](#specifying-a-default-value-for-a-prop "Link for Specifying a default value for a prop ")

If you want to give a prop a default value to fall back on when no value is specified, you can do it with the destructuring by putting `=` and the default value right after the parameter:

```
function Avatar({ person, size = 100 }) {

  // ...

}
```

Now, if `<Avatar person={...} />` is rendered with no `size` prop, the `size` will be set to `100`.

The default value is only used if the `size` prop is missing or if you pass `size={undefined}`. But if you pass `size={null}` or `size={0}`, the default value will **not** be used.

## Forwarding props with the JSX spread syntax[](#forwarding-props-with-the-jsx-spread-syntax "Link for Forwarding props with the JSX spread syntax ")

Sometimes, passing props gets very repetitive:

```
function Profile({ person, size, isSepia, thickBorder }) {

  return (

    <div className="card">

      <Avatar

        person={person}

        size={size}

        isSepia={isSepia}

        thickBorder={thickBorder}

      />

    </div>

  );

}
```

There’s nothing wrong with repetitive code—it can be more legible. But at times you may value conciseness. Some components forward all of their props to their children, like how this `Profile` does with `Avatar`. Because they don’t use any of their props directly, it can make sense to use a more concise “spread” syntax:

```
function Profile(props) {

  return (

    <div className="card">

      <Avatar {...props} />

    </div>

  );

}
```

This forwards all of `Profile`’s props to the `Avatar` without listing each of their names.

**Use spread syntax with restraint.** If you’re using it in every other component, something is wrong. Often, it indicates that you should split your components and pass children as JSX. More on that next!

## Passing JSX as children[](#passing-jsx-as-children "Link for Passing JSX as children ")

It is common to nest built-in browser tags:

```
<div>

  <img />

</div>
```

Sometimes you’ll want to nest your own components the same way:

```
<Card>

  <Avatar />

</Card>
```

When you nest content inside a JSX tag, the parent component will receive that content in a prop called `children`. For example, the `Card` component below will receive a `children` prop set to `<Avatar />` and render it in a wrapper div:

```
import Avatar from './Avatar.js';

function Card({ children }) {
  return (
    <div className="card">
      {children}
    </div>
  );
}

export default function Profile() {
  return (
    <Card>
      <Avatar
        size={100}
        person={{ 
          name: 'Katsuko Saruhashi',
          imageId: 'YfeOqp2'
        }}
      />
    </Card>
  );
}
```

Try replacing the `<Avatar>` inside `<Card>` with some text to see how the `Card` component can wrap any nested content. It doesn’t need to “know” what’s being rendered inside of it. You will see this flexible pattern in many places.

You can think of a component with a `children` prop as having a “hole” that can be “filled in” by its parent components with arbitrary JSX. You will often use the `children` prop for visual wrappers: panels, grids, etc.

Illustrated by [Rachel Lee Nabors](https://nearestnabors.com/)

## How props change over time[](#how-props-change-over-time "Link for How props change over time ")

The `Clock` component below receives two props from its parent component: `color` and `time`. (The parent component’s code is omitted because it uses [state](/learn/state-a-components-memory), which we won’t dive into just yet.)

Try changing the color in the select box below:

```
export default function Clock({ color, time }) {
  return (
    <h1 style={{ color: color }}>
      {time}
    </h1>
  );
}
```

```
import { getImageUrl } from './utils.js';

export default function Gallery() {
  return (
    <div>
      <h1>Notable Scientists</h1>
      <section className="profile">
        <h2>Maria Skłodowska-Curie</h2>
        <img
          className="avatar"
          src={getImageUrl('szV5sdG')}
          alt="Maria Skłodowska-Curie"
          width={70}
          height={70}
        />
        <ul>
          <li>
            <b>Profession: </b> 
            physicist and chemist
          </li>
          <li>
            <b>Awards: 4 </b> 
            (Nobel Prize in Physics, Nobel Prize in Chemistry, Davy Medal, Matteucci Medal)
          </li>
          <li>
            <b>Discovered: </b>
            polonium (chemical element)
          </li>
        </ul>
      </section>
      <section className="profile">
        <h2>Katsuko Saruhashi</h2>
        <img
          className="avatar"
          src={getImageUrl('YfeOqp2')}
          alt="Katsuko Saruhashi"
          width={70}
          height={70}
        />
        <ul>
          <li>
            <b>Profession: </b> 
            geochemist
          </li>
          <li>
            <b>Awards: 2 </b> 
            (Miyake Prize for geochemistry, Tanaka Prize)
          </li>
          <li>
            <b>Discovered: </b>
            a method for measuring carbon dioxide in seawater
          </li>
        </ul>
      </section>
    </div>
  );
}
```

[PreviousJavaScript in JSX with Curly Braces](/learn/javascript-in-jsx-with-curly-braces)

[NextConditional Rendering](/learn/conditional-rendering)

***

----
url: https://legacy.reactjs.org/docs/pure-render-mixin.html
----

> Note:
>
> `PureRenderMixin` is a legacy add-on. Use [`React.PureComponent`](/docs/react-api.html#reactpurecomponent) instead.

**Importing**

```
import PureRenderMixin from 'react-addons-pure-render-mixin'; // ES6
var PureRenderMixin = require('react-addons-pure-render-mixin'); // ES5 with npm
```

## [](#overview)Overview

If your React component’s render function renders the same result given the same props and state, you can use this mixin for a performance boost in some cases.

Example:

```
const createReactClass = require('create-react-class');

createReactClass({
  mixins: [PureRenderMixin],

  render: function() {
    return <div className={this.props.className}>foo</div>;
  }
});
```

Under the hood, the mixin implements [shouldComponentUpdate](/docs/component-specs.html#updating-shouldcomponentupdate), in which it compares the current props and state with the next ones and returns `false` if the equalities pass.

> Note:
>
> This only shallowly compares the objects. If these contain complex data structures, it may produce false-negatives for deeper differences. Only mix into components which have simple props and state, or use `forceUpdate()` when you know deep data structures have changed. Or, consider using [immutable objects](https://immutable-js.com/) to facilitate fast comparisons of nested data.
>
> Furthermore, `shouldComponentUpdate` skips updates for the whole component subtree. Make sure all the children components are also “pure”.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/addons-pure-render-mixin.md)

----
url: https://react.dev/blog/2025/12/11/denial-of-service-and-source-code-exposure-in-react-server-components
----

[Blog](/blog)

# Denial of Service and Source Code Exposure in React Server Components[](#undefined "Link for this heading")

December 11, 2025 by [The React Team](/community/team)

*Updated January 26, 2026.*

***

Security researchers have found and disclosed two additional vulnerabilities in React Server Components while attempting to exploit the patches in last week’s critical vulnerability.

**These new vulnerabilities do not allow for Remote Code Execution.** The patch for React2Shell remains effective at mitigating the Remote Code Execution exploit.

***

The new vulnerabilities are disclosed as:

* **Denial of Service - High Severity**: [CVE-2025-55184](https://www.cve.org/CVERecord?id=CVE-2025-55184), [CVE-2025-67779](https://www.cve.org/CVERecord?id=CVE-2025-67779), and [CVE-2026-23864](https://www.cve.org/CVERecord?id=CVE-2026-23864) (CVSS 7.5)
* **Source Code Exposure - Medium Severity**: [CVE-2025-55183](https://www.cve.org/CVERecord?id=CVE-2025-55183) (CVSS 5.3)

We recommend upgrading immediately due to the severity of the newly disclosed vulnerabilities.

### Note

#### The patches published earlier are vulnerable.[](#the-patches-published-earlier-are-vulnerable "Link for The patches published earlier are vulnerable. ")

If you already updated for the previous vulnerabilities, you will need to update again.

If you updated to 19.0.3, 19.1.4, and 19.2.3, [these are incomplete](#additional-fix-published), and you will need to update again.

Please see [the instructions in the previous post](/blog/2025/12/03/critical-security-vulnerability-in-react-server-components#update-instructions) for upgrade steps.

***

*Updated January 26, 2026.*

Further details of these vulnerabilities will be provided after the rollout of the fixes are complete.

## Immediate Action Required[](#immediate-action-required "Link for Immediate Action Required ")

These vulnerabilities are present in the same packages and versions as [CVE-2025-55182](/blog/2025/12/03/critical-security-vulnerability-in-react-server-components).

This includes 19.0.0, 19.0.1, 19.0.2, 19.0.3, 19.1.0, 19.1.1, 19.1.2, 19.1.3, 19.2.0, 19.2.1, 19.2.2, and 19.2.3 of:

* [react-server-dom-webpack](https://www.npmjs.com/package/react-server-dom-webpack)
* [react-server-dom-parcel](https://www.npmjs.com/package/react-server-dom-parcel)
* [react-server-dom-turbopack](https://www.npmjs.com/package/react-server-dom-turbopack?activeTab=readme)

Fixes were backported to versions 19.0.4, 19.1.5, and 19.2.4. If you are using any of the above packages please upgrade to any of the fixed versions immediately.

As before, if your app’s React code does not use a server, your app is not affected by these vulnerabilities. If your app does not use a framework, bundler, or bundler plugin that supports React Server Components, your app is not affected by these vulnerabilities.

### Note

#### It’s common for critical CVEs to uncover follow‑up vulnerabilities.[](#its-common-for-critical-cves-to-uncover-followup-vulnerabilities "Link for It’s common for critical CVEs to uncover follow‑up vulnerabilities. ")

When a critical vulnerability is disclosed, researchers scrutinize adjacent code paths looking for variant exploit techniques to test whether the initial mitigation can be bypassed.

This pattern shows up across the industry, not just in JavaScript. For example, after [Log4Shell](https://nvd.nist.gov/vuln/detail/cve-2021-44228), additional CVEs ([1](https://nvd.nist.gov/vuln/detail/cve-2021-45046), [2](https://nvd.nist.gov/vuln/detail/cve-2021-45105)) were reported as the community probed the original fix.

Additional disclosures can be frustrating, but they are generally a sign of a healthy response cycle.

### Affected frameworks and bundlers[](#affected-frameworks-and-bundlers "Link for Affected frameworks and bundlers ")

Some React frameworks and bundlers depended on, had peer dependencies for, or included the vulnerable React packages. The following React frameworks & bundlers are affected: [next](https://www.npmjs.com/package/next), [react-router](https://www.npmjs.com/package/react-router), [waku](https://www.npmjs.com/package/waku), [@parcel/rsc](https://www.npmjs.com/package/@parcel/rsc), [@vite/rsc-plugin](https://www.npmjs.com/package/@vitejs/plugin-rsc), and [rwsdk](https://www.npmjs.com/package/rwsdk).

Please see [the instructions in the previous post](/blog/2025/12/03/critical-security-vulnerability-in-react-server-components#update-instructions) for upgrade steps.

### Hosting Provider Mitigations[](#hosting-provider-mitigations "Link for Hosting Provider Mitigations ")

As before, we have worked with a number of hosting providers to apply temporary mitigations.

You should not depend on these to secure your app, and still update immediately.

### React Native[](#react-native "Link for React Native ")

For React Native users not using a monorepo or `react-dom`, your `react` version should be pinned in your `package.json`, and there are no additional steps needed.

If you are using React Native in a monorepo, you should update *only* the impacted packages if they are installed:

* `react-server-dom-webpack`
* `react-server-dom-parcel`
* `react-server-dom-turbopack`

This is required to mitigate the security advisories, but you do not need to update `react` and `react-dom` so this will not cause the version mismatch error in React Native.

See [this issue](https://github.com/facebook/react-native/issues/54772#issuecomment-3617929832) for more information.

***

## High Severity: Multiple Denial of Service[](#high-severity-multiple-denial-of-service "Link for High Severity: Multiple Denial of Service ")

**CVEs:** [CVE-2026-23864](https://www.cve.org/CVERecord?id=CVE-2026-23864) **Base Score:** 7.5 (High) **Date**: January 26, 2026

Security researchers discovered additional DoS vulnerabilities still exist in React Server Components.

The vulnerabilities are triggered by sending specially crafted HTTP requests to Server Function endpoints, and could lead to server crashes, out-of-memory exceptions or excessive CPU usage; depending on the vulnerable code path being exercised, the application configuration and application code.

The patches published January 26th mitigate these DoS vulnerabilities.

### Note

#### Additional fixes published[](#additional-fix-published "Link for Additional fixes published ")

The original fix addressing the DoS in [CVE-2025-55184](https://www.cve.org/CVERecord?id=CVE-2025-55184) was incomplete.

This left previous versions vulnerable. Versions 19.0.4, 19.1.5, 19.2.4 are safe.

***

*Updated January 26, 2026.*

***

## High Severity: Denial of Service[](#high-severity-denial-of-service "Link for High Severity: Denial of Service ")

**CVEs:** [CVE-2025-55184](https://www.cve.org/CVERecord?id=CVE-2025-55184) and [CVE-2025-67779](https://www.cve.org/CVERecord?id=CVE-2025-67779) **Base Score:** 7.5 (High)

Security researchers have discovered that a malicious HTTP request can be crafted and sent to any Server Functions endpoint that, when deserialized by React, can cause an infinite loop that hangs the server process and consumes CPU. Even if your app does not implement any React Server Function endpoints it may still be vulnerable if your app supports React Server Components.

This creates a vulnerability vector where an attacker may be able to deny users from accessing the product, and potentially have a performance impact on the server environment.

The patches published today mitigate by preventing the infinite loop.

## Medium Severity: Source Code Exposure[](#low-severity-source-code-exposure "Link for Medium Severity: Source Code Exposure ")

**CVE:** [CVE-2025-55183](https://www.cve.org/CVERecord?id=CVE-2025-55183) **Base Score**: 5.3 (Medium)

A security researcher has discovered that a malicious HTTP request sent to a vulnerable Server Function may unsafely return the source code of any Server Function. Exploitation requires the existence of a Server Function which explicitly or implicitly exposes a stringified argument:

```
'use server';



export async function serverFunction(name) {

  const conn = db.createConnection('SECRET KEY');

  const user = await conn.createUser(name); // implicitly stringified, leaked in db



  return {

   id: user.id,

   message: `Hello, ${name}!` // explicitly stringified, leaked in reply

  }}
```

An attacker may be able to leak the following:

```
0:{"a":"$@1","f":"","b":"Wy43RxUKdxmr5iuBzJ1pN"}

1:{"id":"tva1sfodwq","message":"Hello, async function(a){console.log(\"serverFunction\");let b=i.createConnection(\"SECRET KEY\");return{id:(await b.createUser(a)).id,message:`Hello, ${a}!`}}!"}
```

The patches published today prevent stringifying the Server Function source code.

### Note

#### Only secrets in source code may be exposed.[](#only-secrets-in-source-code-may-be-exposed "Link for Only secrets in source code may be exposed. ")

Secrets hardcoded in source code may be exposed, but runtime secrets such as `process.env.SECRET` are not affected.

The scope of the exposed code is limited to the code inside the Server Function, which may include other functions depending on the amount of inlining your bundler provides.

Always verify against production bundles.

***

## Timeline[](#timeline "Link for Timeline ")

* **December 3rd**: Leak reported to Vercel and [Meta Bug Bounty](https://bugbounty.meta.com/) by [Andrew MacPherson](https://github.com/AndrewMohawk).
* **December 4th**: Initial DoS reported to [Meta Bug Bounty](https://bugbounty.meta.com/) by [RyotaK](https://ryotak.net).
* **December 6th**: Both issues confirmed by the React team, and the team began investigating.
* **December 7th**: Initial fixes created and the React team began verifying and planning new patch.
* **December 8th**: Affected hosting providers and open source projects notified.
* **December 10th**: Hosting provider mitigations in place and patches verified.
* **December 11th**: Additional DoS reported to [Meta Bug Bounty](https://bugbounty.meta.com/) by Shinsaku Nomura.
* **December 11th**: Patches published and publicly disclosed as [CVE-2025-55183](https://www.cve.org/CVERecord?id=CVE-2025-55183) and [CVE-2025-55184](https://www.cve.org/CVERecord?id=CVE-2025-55184).
* **December 11th**: Missing DoS case found internally, patched and publicly disclosed as [CVE-2025-67779](https://www.cve.org/CVERecord?id=CVE-2025-67779).
* **January 26th**: Additional DoS cases found, patched, and publicly disclosed as [CVE-2026-23864](https://www.cve.org/CVERecord?id=CVE-2026-23864).

***

## Attribution[](#attribution "Link for Attribution ")

Thank you to [Andrew MacPherson (AndrewMohawk)](https://github.com/AndrewMohawk) for reporting the Source Code Exposure, [RyotaK](https://ryotak.net) from GMO Flatt Security Inc and Shinsaku Nomura of Bitforest Co., Ltd. for reporting the Denial of Service vulnerabilities. Thank you to [Mufeed VH](https://x.com/mufeedvh) from [Winfunc Research](https://winfunc.com), [Joachim Viide](https://jviide.iki.fi), [RyotaK](https://ryotak.net) from [GMO Flatt Security Inc](https://flatt.tech/en/) and Xiangwei Zhang of Tencent Security YUNDING LAB for reporting the additional DoS vulnerabilities.

[PreviousThe React Foundation: A New Home for React Hosted by the Linux Foundation](/blog/2026/02/24/the-react-foundation)

[NextCritical Security Vulnerability in React Server Components](/blog/2025/12/03/critical-security-vulnerability-in-react-server-components)

***

----
url: https://react.dev/reference/react/Profiler
----

[API Reference](/reference/react)

[Components](/reference/react/components)

# \<Profiler>[](#undefined "Link for this heading")

`<Profiler>` lets you measure rendering performance of a React tree programmatically.

```
<Profiler id="App" onRender={onRender}>

  <App />

</Profiler>
```

* [Reference](#reference)

  * [`<Profiler>`](#profiler)
  * [`onRender` callback](#onrender-callback)

* [Usage](#usage)

  * [Measuring rendering performance programmatically](#measuring-rendering-performance-programmatically)
  * [Measuring different parts of the application](#measuring-different-parts-of-the-application)

***

## Reference[](#reference "Link for Reference ")

### `<Profiler>`[](#profiler "Link for this heading")

Wrap a component tree in a `<Profiler>` to measure its rendering performance.

```
<Profiler id="App" onRender={onRender}>

  <App />

</Profiler>
```

#### Props[](#props "Link for Props ")

* `id`: A string identifying the part of the UI you are measuring.
* `onRender`: An [`onRender` callback](#onrender-callback) that React calls every time components within the profiled tree update. It receives information about what was rendered and how much time it took.

#### Caveats[](#caveats "Link for Caveats ")

* Profiling adds some additional overhead, so **it is disabled in the production build by default.** To opt into production profiling, you need to enable a [special production build with profiling enabled.](/reference/dev-tools/react-performance-tracks#using-profiling-builds)

***

### `onRender` callback[](#onrender-callback "Link for this heading")

React will call your `onRender` callback with information about what was rendered.

```
function onRender(id, phase, actualDuration, baseDuration, startTime, commitTime) {

  // Aggregate or log render timings...

}
```

***

## Usage[](#usage "Link for Usage ")

### Measuring rendering performance programmatically[](#measuring-rendering-performance-programmatically "Link for Measuring rendering performance programmatically ")

Wrap the `<Profiler>` component around a React tree to measure its rendering performance.

```
<App>

  <Profiler id="Sidebar" onRender={onRender}>

    <Sidebar />

  </Profiler>

  <PageContent />

</App>
```

It requires two props: an `id` (string) and an `onRender` callback (function) which React calls any time a component within the tree “commits” an update.

### Pitfall

Profiling adds some additional overhead, so **it is disabled in the production build by default.** To opt into production profiling, you need to enable a [special production build with profiling enabled.](/reference/dev-tools/react-performance-tracks#using-profiling-builds)

### Note

`<Profiler>` lets you gather measurements programmatically. If you’re looking for an interactive profiler, try the Profiler tab in [React Developer Tools](/learn/react-developer-tools). It exposes similar functionality as a browser extension.

Components wrapped in `<Profiler>` will also be marked in the [Component tracks](/reference/dev-tools/react-performance-tracks#components) of React Performance tracks even in profiling builds. In development builds, all components are marked in the Components track regardless of whether they’re wrapped in `<Profiler>`.

***

### Measuring different parts of the application[](#measuring-different-parts-of-the-application "Link for Measuring different parts of the application ")

You can use multiple `<Profiler>` components to measure different parts of your application:

```
<App>

  <Profiler id="Sidebar" onRender={onRender}>

    <Sidebar />

  </Profiler>

  <Profiler id="Content" onRender={onRender}>

    <Content />

  </Profiler>

</App>
```

You can also nest `<Profiler>` components:

```
<App>

  <Profiler id="Sidebar" onRender={onRender}>

    <Sidebar />

  </Profiler>

  <Profiler id="Content" onRender={onRender}>

    <Content>

      <Profiler id="Editor" onRender={onRender}>

        <Editor />

      </Profiler>

      <Preview />

    </Content>

  </Profiler>

</App>
```

Although `<Profiler>` is a lightweight component, it should be used only when necessary. Each use adds some CPU and memory overhead to an application.

***

[Previous\<Fragment> (<>)](/reference/react/Fragment)

[Next\<StrictMode>](/reference/react/StrictMode)

***

----
url: https://18.react.dev/reference/react/useOptimistic
----

[API Reference](/reference/react)

[Hooks](/reference/react/hooks)

# useOptimistic[](#undefined "Link for this heading")

### Canary

The `useOptimistic` Hook is currently only available in React’s Canary and experimental channels. Learn more about [React’s release channels here](/community/versioning-policy#all-release-channels).

`useOptimistic` is a React Hook that lets you optimistically update the UI.

```
  const [optimisticState, addOptimistic] = useOptimistic(state, updateFn);
```

* [Reference](#reference)
  * [`useOptimistic(state, updateFn)`](#use)
* [Usage](#usage)
  * [Optimistically updating forms](#optimistically-updating-with-forms)

***

## Reference[](#reference "Link for Reference ")

### `useOptimistic(state, updateFn)`[](#use "Link for this heading")

`useOptimistic` is a React Hook that lets you show a different state while an async action is underway. It accepts some state as an argument and returns a copy of that state that can be different during the duration of an async action such as a network request. You provide a function that takes the current state and the input to the action, and returns the optimistic state to be used while the action is pending.

This state is called the “optimistic” state because it is usually used to immediately present the user with the result of performing an action, even though the action actually takes time to complete.

```
import { useOptimistic } from 'react';



function AppContainer() {

  const [optimisticState, addOptimistic] = useOptimistic(

    state,

    // updateFn

    (currentState, optimisticValue) => {

      // merge and return new state

      // with optimistic value

    }

  );

}
```

[See more examples below.](#usage)

#### Parameters[](#parameters "Link for Parameters ")

* `state`: the value to be returned initially and whenever no action is pending.
* `updateFn(currentState, optimisticValue)`: a function that takes the current state and the optimistic value passed to `addOptimistic` and returns the resulting optimistic state. It must be a pure function. `updateFn` takes in two parameters. The `currentState` and the `optimisticValue`. The return value will be the merged value of the `currentState` and `optimisticValue`.

#### Returns[](#returns "Link for Returns ")

* `optimisticState`: The resulting optimistic state. It is equal to `state` unless an action is pending, in which case it is equal to the value returned by `updateFn`.
* `addOptimistic`: `addOptimistic` is the dispatching function to call when you have an optimistic update. It takes one argument, `optimisticValue`, of any type and will call the `updateFn` with `state` and `optimisticValue`.

***

## Usage[](#usage "Link for Usage ")

### Optimistically updating forms[](#optimistically-updating-with-forms "Link for Optimistically updating forms ")

The `useOptimistic` Hook provides a way to optimistically update the user interface before a background operation, like a network request, completes. In the context of forms, this technique helps to make apps feel more responsive. When a user submits a form, instead of waiting for the server’s response to reflect the changes, the interface is immediately updated with the expected outcome.

For example, when a user types a message into the form and hits the “Send” button, the `useOptimistic` Hook allows the message to immediately appear in the list with a “Sending…” label, even before the message is actually sent to a server. This “optimistic” approach gives the impression of speed and responsiveness. The form then attempts to truly send the message in the background. Once the server confirms the message has been received, the “Sending…” label is removed.

```
import { useOptimistic, useState, useRef } from "react";
import { deliverMessage } from "./actions.js";

function Thread({ messages, sendMessage }) {
  const formRef = useRef();
  async function formAction(formData) {
    addOptimisticMessage(formData.get("message"));
    formRef.current.reset();
    await sendMessage(formData);
  }
  const [optimisticMessages, addOptimisticMessage] = useOptimistic(
    messages,
    (state, newMessage) => [
      ...state,
      {
        text: newMessage,
        sending: true
      }
    ]
  );

  return (
    <>
      {optimisticMessages.map((message, index) => (
        <div key={index}>
          {message.text}
          {!!message.sending && <small> (Sending...)</small>}
        </div>
      ))}
      <form action={formAction} ref={formRef}>
        <input type="text" name="message" placeholder="Hello!" />
        <button type="submit">Send</button>
      </form>
    </>
  );
}

export default function App() {
  const [messages, setMessages] = useState([
    { text: "Hello there!", sending: false, key: 1 }
  ]);
  async function sendMessage(formData) {
    const sentMessage = await deliverMessage(formData.get("message"));
    setMessages((messages) => [...messages, { text: sentMessage }]);
  }
  return <Thread messages={messages} sendMessage={sendMessage} />;
}
```

[PrevioususeMemo](/reference/react/useMemo)

[NextuseReducer](/reference/react/useReducer)

***

----
url: https://18.react.dev/reference/react/useSyncExternalStore
----

[API Reference](/reference/react)

[Hooks](/reference/react/hooks)

# useSyncExternalStore[](#undefined "Link for this heading")

`useSyncExternalStore` is a React Hook that lets you subscribe to an external store.

```
const snapshot = useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot?)
```

***

## Reference[](#reference "Link for Reference ")

### `useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot?)`[](#usesyncexternalstore "Link for this heading")

Call `useSyncExternalStore` at the top level of your component to read a value from an external data store.

```
import { useSyncExternalStore } from 'react';

import { todosStore } from './todoStore.js';



function TodosApp() {

  const todos = useSyncExternalStore(todosStore.subscribe, todosStore.getSnapshot);

  // ...

}
```

  ```
  const LazyProductDetailPage = lazy(() => import('./ProductDetailPage.js'));



  function ShoppingApp() {

    const selectedProductId = useSyncExternalStore(...);



    // ❌ Calling `use` with a Promise dependent on `selectedProductId`

    const data = use(fetchItem(selectedProductId))



    // ❌ Conditionally rendering a lazy component based on `selectedProductId`

    return selectedProductId != null ? <LazyProductDetailPage /> : <FeaturedProducts />;

  }
  ```

***

## Usage[](#usage "Link for Usage ")

### Subscribing to an external store[](#subscribing-to-an-external-store "Link for Subscribing to an external store ")

Most of your React components will only read data from their [props,](/learn/passing-props-to-a-component) [state,](/reference/react/useState) and [context.](/reference/react/useContext) However, sometimes a component needs to read some data from some store outside of React that changes over time. This includes:

* Third-party state management libraries that hold state outside of React.
* Browser APIs that expose a mutable value and events to subscribe to its changes.

Call `useSyncExternalStore` at the top level of your component to read a value from an external data store.

```
import { useSyncExternalStore } from 'react';

import { todosStore } from './todoStore.js';



function TodosApp() {

  const todos = useSyncExternalStore(todosStore.subscribe, todosStore.getSnapshot);

  // ...

}
```

It returns the snapshot of the data in the store. You need to pass two functions as arguments:

1. The `subscribe` function should subscribe to the store and return a function that unsubscribes.
2. The `getSnapshot` function should read a snapshot of the data from the store.

React will use these functions to keep your component subscribed to the store and re-render it on changes.

For example, in the sandbox below, `todosStore` is implemented as an external store that stores data outside of React. The `TodosApp` component connects to that external store with the `useSyncExternalStore` Hook.

```
import { useSyncExternalStore } from 'react';
import { todosStore } from './todoStore.js';

export default function TodosApp() {
  const todos = useSyncExternalStore(todosStore.subscribe, todosStore.getSnapshot);
  return (
    <>
      <button onClick={() => todosStore.addTodo()}>Add todo</button>
      <hr />
      <ul>
        {todos.map(todo => (
          <li key={todo.id}>{todo.text}</li>
        ))}
      </ul>
    </>
  );
}
```

### Note

When possible, we recommend using built-in React state with [`useState`](/reference/react/useState) and [`useReducer`](/reference/react/useReducer) instead. The `useSyncExternalStore` API is mostly useful if you need to integrate with existing non-React code.

***

### Subscribing to a browser API[](#subscribing-to-a-browser-api "Link for Subscribing to a browser API ")

Another reason to add `useSyncExternalStore` is when you want to subscribe to some value exposed by the browser that changes over time. For example, suppose that you want your component to display whether the network connection is active. The browser exposes this information via a property called [`navigator.onLine`.](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/onLine)

This value can change without React’s knowledge, so you should read it with `useSyncExternalStore`.

```
import { useSyncExternalStore } from 'react';



function ChatIndicator() {

  const isOnline = useSyncExternalStore(subscribe, getSnapshot);

  // ...

}
```

To implement the `getSnapshot` function, read the current value from the browser API:

```
function getSnapshot() {

  return navigator.onLine;

}
```

Next, you need to implement the `subscribe` function. For example, when `navigator.onLine` changes, the browser fires the [`online`](https://developer.mozilla.org/en-US/docs/Web/API/Window/online_event) and [`offline`](https://developer.mozilla.org/en-US/docs/Web/API/Window/offline_event) events on the `window` object. You need to subscribe the `callback` argument to the corresponding events, and then return a function that cleans up the subscriptions:

```
function subscribe(callback) {

  window.addEventListener('online', callback);

  window.addEventListener('offline', callback);

  return () => {

    window.removeEventListener('online', callback);

    window.removeEventListener('offline', callback);

  };

}
```

Now React knows how to read the value from the external `navigator.onLine` API and how to subscribe to its changes. Disconnect your device from the network and notice that the component re-renders in response:

```
import { useSyncExternalStore } from 'react';

export default function ChatIndicator() {
  const isOnline = useSyncExternalStore(subscribe, getSnapshot);
  return <h1>{isOnline ? '✅ Online' : '❌ Disconnected'}</h1>;
}

function getSnapshot() {
  return navigator.onLine;
}

function subscribe(callback) {
  window.addEventListener('online', callback);
  window.addEventListener('offline', callback);
  return () => {
    window.removeEventListener('online', callback);
    window.removeEventListener('offline', callback);
  };
}
```

***

### Extracting the logic to a custom Hook[](#extracting-the-logic-to-a-custom-hook "Link for Extracting the logic to a custom Hook ")

Usually you won’t write `useSyncExternalStore` directly in your components. Instead, you’ll typically call it from your own custom Hook. This lets you use the same external store from different components.

For example, this custom `useOnlineStatus` Hook tracks whether the network is online:

```
import { useSyncExternalStore } from 'react';



export function useOnlineStatus() {

  const isOnline = useSyncExternalStore(subscribe, getSnapshot);

  return isOnline;

}



function getSnapshot() {

  // ...

}



function subscribe(callback) {

  // ...

}
```

Now different components can call `useOnlineStatus` without repeating the underlying implementation:

```
import { useOnlineStatus } from './useOnlineStatus.js';

function StatusBar() {
  const isOnline = useOnlineStatus();
  return <h1>{isOnline ? '✅ Online' : '❌ Disconnected'}</h1>;
}

function SaveButton() {
  const isOnline = useOnlineStatus();

  function handleSaveClick() {
    console.log('✅ Progress saved');
  }

  return (
    <button disabled={!isOnline} onClick={handleSaveClick}>
      {isOnline ? 'Save progress' : 'Reconnecting...'}
    </button>
  );
}

export default function App() {
  return (
    <>
      <SaveButton />
      <StatusBar />
    </>
  );
}
```

***

### Adding support for server rendering[](#adding-support-for-server-rendering "Link for Adding support for server rendering ")

If your React app uses [server rendering,](/reference/react-dom/server) your React components will also run outside the browser environment to generate the initial HTML. This creates a few challenges when connecting to an external store:

* If you’re connecting to a browser-only API, it won’t work because it does not exist on the server.
* If you’re connecting to a third-party data store, you’ll need its data to match between the server and client.

To solve these issues, pass a `getServerSnapshot` function as the third argument to `useSyncExternalStore`:

```
import { useSyncExternalStore } from 'react';



export function useOnlineStatus() {

  const isOnline = useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);

  return isOnline;

}



function getSnapshot() {

  return navigator.onLine;

}



function getServerSnapshot() {

  return true; // Always show "Online" for server-generated HTML

}



function subscribe(callback) {

  // ...

}
```

The `getServerSnapshot` function is similar to `getSnapshot`, but it runs only in two situations:

* It runs on the server when generating the HTML.
* It runs on the client during [hydration](/reference/react-dom/client/hydrateRoot), i.e. when React takes the server HTML and makes it interactive.

This lets you provide the initial snapshot value which will be used before the app becomes interactive. If there is no meaningful initial value for the server rendering, omit this argument to [force rendering on the client.](/reference/react/Suspense#providing-a-fallback-for-server-errors-and-client-only-content)

### Note

Make sure that `getServerSnapshot` returns the same exact data on the initial client render as it returned on the server. For example, if `getServerSnapshot` returned some prepopulated store content on the server, you need to transfer this content to the client. One way to do this is to emit a `<script>` tag during server rendering that sets a global like `window.MY_STORE_DATA`, and read from that global on the client in `getServerSnapshot`. Your external store should provide instructions on how to do that.

***

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### I’m getting an error: “The result of `getSnapshot` should be cached”[](#im-getting-an-error-the-result-of-getsnapshot-should-be-cached "Link for this heading")

This error means your `getSnapshot` function returns a new object every time it’s called, for example:

```
function getSnapshot() {

  // 🔴 Do not return always different objects from getSnapshot

  return {

    todos: myStore.todos

  };

}
```

React will re-render the component if `getSnapshot` return value is different from the last time. This is why, if you always return a different value, you will enter an infinite loop and get this error.

Your `getSnapshot` object should only return a different object if something has actually changed. If your store contains immutable data, you can return that data directly:

```
function getSnapshot() {

  // ✅ You can return immutable data

  return myStore.todos;

}
```

If your store data is mutable, your `getSnapshot` function should return an immutable snapshot of it. This means it *does* need to create new objects, but it shouldn’t do this for every single call. Instead, it should store the last calculated snapshot, and return the same snapshot as the last time if the data in the store has not changed. How you determine whether mutable data has changed depends on your mutable store.

***

### My `subscribe` function gets called after every re-render[](#my-subscribe-function-gets-called-after-every-re-render "Link for this heading")

This `subscribe` function is defined *inside* a component so it is different on every re-render:

```
function ChatIndicator() {

  const isOnline = useSyncExternalStore(subscribe, getSnapshot);

  

  // 🚩 Always a different function, so React will resubscribe on every re-render

  function subscribe() {

    // ...

  }



  // ...

}
```

React will resubscribe to your store if you pass a different `subscribe` function between re-renders. If this causes performance issues and you’d like to avoid resubscribing, move the `subscribe` function outside:

```
function ChatIndicator() {

  const isOnline = useSyncExternalStore(subscribe, getSnapshot);

  // ...

}



// ✅ Always the same function, so React won't need to resubscribe

function subscribe() {

  // ...

}
```

Alternatively, wrap `subscribe` into [`useCallback`](/reference/react/useCallback) to only resubscribe when some argument changes:

```
function ChatIndicator({ userId }) {

  const isOnline = useSyncExternalStore(subscribe, getSnapshot);

  

  // ✅ Same function as long as userId doesn't change

  const subscribe = useCallback(() => {

    // ...

  }, [userId]);



  // ...

}
```

[PrevioususeState](/reference/react/useState)

[NextuseTransition](/reference/react/useTransition)

***

----
url: https://18.react.dev/learn/react-compiler
----

[Learn React](/learn)

[Installation](/learn/installation)

# React Compiler[](#undefined "Link for this heading")

This page will give you an introduction to React Compiler and how to try it out successfully.

### Under Construction

These docs are still a work in progress. More documentation is available in the [React Compiler Working Group repo](https://github.com/reactwg/react-compiler/discussions), and will be upstreamed into these docs when they are more stable.

### You will learn

* Getting started with the compiler
* Installing the compiler and ESLint plugin
* Troubleshooting

### Note

React Compiler is a new compiler currently in Beta, that we’ve open sourced to get early feedback from the community. While it has been used in production at companies like Meta, rolling out the compiler to production for your app will depend on the health of your codebase and how well you’ve followed the [Rules of React](/reference/rules).

The latest Beta release can be found with the `@beta` tag, and daily experimental releases with `@experimental`.

React Compiler is a new compiler that we’ve open sourced to get early feedback from the community. It is a build-time only tool that automatically optimizes your React app. It works with plain JavaScript, and understands the [Rules of React](/reference/rules), so you don’t need to rewrite any code to use it.

The compiler also includes an [ESLint plugin](#installing-eslint-plugin-react-compiler) that surfaces the analysis from the compiler right in your editor. **We strongly recommend everyone use the linter today.** The linter does not require that you have the compiler installed, so you can use it even if you are not ready to try out the compiler.

The compiler is currently released as `beta`, and is available to try out on React 17+ apps and libraries. To install the Beta:

Terminal

npm install -D babel-plugin-react-compiler\@beta eslint-plugin-react-compiler\@beta

Or, if you’re using Yarn:

Terminal

yarn add -D babel-plugin-react-compiler\@beta eslint-plugin-react-compiler\@beta

If you are not using React 19 yet, please see [the section below](#using-react-compiler-with-react-17-or-18) for further instructions.

### What does the compiler do?[](#what-does-the-compiler-do "Link for What does the compiler do? ")

In order to optimize applications, React Compiler automatically memoizes your code. You may be familiar today with memoization through APIs such as `useMemo`, `useCallback`, and `React.memo`. With these APIs you can tell React that certain parts of your application don’t need to recompute if their inputs haven’t changed, reducing work on updates. While powerful, it’s easy to forget to apply memoization or apply them incorrectly. This can lead to inefficient updates as React has to check parts of your UI that don’t have any *meaningful* changes.

The compiler uses its knowledge of JavaScript and React’s rules to automatically memoize values or groups of values within your components and hooks. If it detects breakages of the rules, it will automatically skip over just those components or hooks, and continue safely compiling other code.

### Note

React Compiler can statically detect when Rules of React are broken, and safely opt-out of optimizing just the affected components or hooks. It is not necessary for the compiler to optimize 100% of your codebase.

If your codebase is already very well-memoized, you might not expect to see major performance improvements with the compiler. However, in practice memoizing the correct dependencies that cause performance issues is tricky to get right by hand.

##### Deep Dive#### What kind of memoization does React Compiler add?[](#what-kind-of-memoization-does-react-compiler-add "Link for What kind of memoization does React Compiler add? ")

The initial release of React Compiler is primarily focused on **improving update performance** (re-rendering existing components), so it focuses on these two use cases:

1. **Skipping cascading re-rendering of components**
   * Re-rendering `<Parent />` causes many components in its component tree to re-render, even though only `<Parent />` has changed
2. **Skipping expensive calculations from outside of React**
   * For example, calling `expensivelyProcessAReallyLargeArrayOfObjects()` inside of your component or hook that needs that data

#### Optimizing Re-renders[](#optimizing-re-renders "Link for Optimizing Re-renders ")

React lets you express your UI as a function of their current state (more concretely: their props, state, and context). In its current implementation, when a component’s state changes, React will re-render that component *and all of its children* — unless you have applied some form of manual memoization with `useMemo()`, `useCallback()`, or `React.memo()`. For example, in the following example, `<MessageButton>` will re-render whenever `<FriendList>`’s state changes:

```
function FriendList({ friends }) {

  const onlineCount = useFriendOnlineCount();

  if (friends.length === 0) {

    return <NoFriends />;

  }

  return (

    <div>

      <span>{onlineCount} online</span>

      {friends.map((friend) => (

        <FriendListCard key={friend.id} friend={friend} />

      ))}

      <MessageButton />

    </div>

  );

}
```

[*See this example in the React Compiler Playground*](https://playground.react.dev/#N4Igzg9grgTgxgUxALhAMygOzgFwJYSYAEAYjHgpgCYAyeYOAFMEWuZVWEQL4CURwADrEicQgyKEANnkwIAwtEw4iAXiJQwCMhWoB5TDLmKsTXgG5hRInjRFGbXZwB0UygHMcACzWr1ABn4hEWsYBBxYYgAeADkIHQ4uAHoAPksRbisiMIiYYkYs6yiqPAA3FMLrIiiwAAcAQ0wU4GlZBSUcbklDNqikusaKkKrgR0TnAFt62sYHdmp+VRT7SqrqhOo6Bnl6mCoiAGsEAE9VUfmqZzwqLrHqM7ubolTVol5eTOGigFkEMDB6u4EAAhKA4HCEZ5DNZ9ErlLIWYTcEDcIA)

React Compiler automatically applies the equivalent of manual memoization, ensuring that only the relevant parts of an app re-render as state changes, which is sometimes referred to as “fine-grained reactivity”. In the above example, React Compiler determines that the return value of `<FriendListCard />` can be reused even as `friends` changes, and can avoid recreating this JSX *and* avoid re-rendering `<MessageButton>` as the count changes.

#### Expensive calculations also get memoized[](#expensive-calculations-also-get-memoized "Link for Expensive calculations also get memoized ")

The compiler can also automatically memoize for expensive calculations used during rendering:

```
// **Not** memoized by React Compiler, since this is not a component or hook

function expensivelyProcessAReallyLargeArrayOfObjects() { /* ... */ }



// Memoized by React Compiler since this is a component

function TableContainer({ items }) {

  // This function call would be memoized:

  const data = expensivelyProcessAReallyLargeArrayOfObjects(items);

  // ...

}
```

[*See this example in the React Compiler Playground*](https://playground.react.dev/#N4Igzg9grgTgxgUxALhAejQAgFTYHIQAuumAtgqRAJYBeCAJpgEYCemASggIZyGYDCEUgAcqAGwQwANJjBUAdokyEAFlTCZ1meUUxdMcIcIjyE8vhBiYVECAGsAOvIBmURYSonMCAB7CzcgBuCGIsAAowEIhgYACCnFxioQAyXDAA5gixMDBcLADyzvlMAFYIvGAAFACUmMCYaNiYAHStOFgAvk5OGJgAshTUdIysHNy8AkbikrIKSqpaWvqGIiZmhE6u7p7ymAAqXEwSguZcCpKV9VSEFBodtcBOmAYmYHz0XIT6ALzefgFUYKhCJRBAxeLcJIsVIZLI5PKFYplCqVa63aoAbm6u0wMAQhFguwAPPRAQA+YAfL4dIloUmBMlODogDpAA)

However, if `expensivelyProcessAReallyLargeArrayOfObjects` is truly an expensive function, you may want to consider implementing its own memoization outside of React, because:

* React Compiler only memoizes React components and hooks, not every function
* React Compiler’s memoization is not shared across multiple components or hooks

So if `expensivelyProcessAReallyLargeArrayOfObjects` was used in many different components, even if the same exact items were passed down, that expensive calculation would be run repeatedly. We recommend [profiling](https://react.dev/reference/react/useMemo#how-to-tell-if-a-calculation-is-expensive) first to see if it really is that expensive before making code more complicated.

### Should I try out the compiler?[](#should-i-try-out-the-compiler "Link for Should I try out the compiler? ")

Please note that the compiler is still in Beta and has many rough edges. While it has been used in production at companies like Meta, rolling out the compiler to production for your app will depend on the health of your codebase and how well you’ve followed the [Rules of React](/reference/rules).

**You don’t have to rush into using the compiler now. It’s okay to wait until it reaches a stable release before adopting it.** However, we do appreciate trying it out in small experiments in your apps so that you can [provide feedback](#reporting-issues) to us to help make the compiler better.

## Getting Started[](#getting-started "Link for Getting Started ")

In addition to these docs, we recommend checking the [React Compiler Working Group](https://github.com/reactwg/react-compiler) for additional information and discussion about the compiler.

### Installing eslint-plugin-react-compiler[](#installing-eslint-plugin-react-compiler "Link for Installing eslint-plugin-react-compiler ")

React Compiler also powers an ESLint plugin. The ESLint plugin can be used **independently** of the compiler, meaning you can use the ESLint plugin even if you don’t use the compiler.

Terminal

npm install -D eslint-plugin-react-compiler\@beta

Then, add it to your ESLint config:

```
import reactCompiler from 'eslint-plugin-react-compiler'



export default [

  {

    plugins: {

      'react-compiler': reactCompiler,

    },

    rules: {

      'react-compiler/react-compiler': 'error',

    },

  },

]
```

Or, in the deprecated eslintrc config format:

```
module.exports = {

  plugins: [

    'eslint-plugin-react-compiler',

  ],

  rules: {

    'react-compiler/react-compiler': 'error',

  },

}
```

The ESLint plugin will display any violations of the rules of React in your editor. When it does this, it means that the compiler has skipped over optimizing that component or hook. This is perfectly okay, and the compiler can recover and continue optimizing other components in your codebase.

### Note

**You don’t have to fix all ESLint violations straight away.** You can address them at your own pace to increase the amount of components and hooks being optimized, but it is not required to fix everything before you can use the compiler.

### Rolling out the compiler to your codebase[](#using-the-compiler-effectively "Link for Rolling out the compiler to your codebase ")

#### Existing projects[](#existing-projects "Link for Existing projects ")

The compiler is designed to compile functional components and hooks that follow the [Rules of React](/reference/rules). It can also handle code that breaks those rules by bailing out (skipping over) those components or hooks. However, due to the flexible nature of JavaScript, the compiler cannot catch every possible violation and may compile with false negatives: that is, the compiler may accidentally compile a component/hook that breaks the Rules of React which can lead to undefined behavior.

For this reason, to adopt the compiler successfully on existing projects, we recommend running it on a small directory in your product code first. You can do this by configuring the compiler to only run on a specific set of directories:

```
const ReactCompilerConfig = {

  sources: (filename) => {

    return filename.indexOf('src/path/to/dir') !== -1;

  },

};
```

When you have more confidence with rolling out the compiler, you can expand coverage to other directories as well and slowly roll it out to your whole app.

#### New projects[](#new-projects "Link for New projects ")

If you’re starting a new project, you can enable the compiler on your entire codebase, which is the default behavior.

### Using React Compiler with React 17 or 18[](#using-react-compiler-with-react-17-or-18 "Link for Using React Compiler with React 17 or 18 ")

React Compiler works best with React 19 RC. If you are unable to upgrade, you can install the extra `react-compiler-runtime` package which will allow the compiled code to run on versions prior to 19. However, note that the minimum supported version is 17.

Terminal

npm install react-compiler-runtime\@beta

You should also add the correct `target` to your compiler config, where `target` is the major version of React you are targeting:

```
// babel.config.js

const ReactCompilerConfig = {

  target: '18' // '17' | '18' | '19'

};



module.exports = function () {

  return {

    plugins: [

      ['babel-plugin-react-compiler', ReactCompilerConfig],

    ],

  };

};
```

### Using the compiler on libraries[](#using-the-compiler-on-libraries "Link for Using the compiler on libraries ")

React Compiler can also be used to compile libraries. Because React Compiler needs to run on the original source code prior to any code transformations, it is not possible for an application’s build pipeline to compile the libraries they use. Hence, our recommendation is for library maintainers to independently compile and test their libraries with the compiler, and ship compiled code to npm.

Because your code is pre-compiled, users of your library will not need to have the compiler enabled in order to benefit from the automatic memoization applied to your library. If your library targets apps not yet on React 19, specify a minimum [`target` and add `react-compiler-runtime` as a direct dependency](#using-react-compiler-with-react-17-or-18). The runtime package will use the correct implementation of APIs depending on the application’s version, and polyfill the missing APIs if necessary.

Library code can often require more complex patterns and usage of escape hatches. For this reason, we recommend ensuring that you have sufficient testing in order to identify any issues that might arise from using the compiler on your library. If you identify any issues, you can always opt-out the specific components or hooks with the [`'use no memo'` directive](#something-is-not-working-after-compilation).

Similarly to apps, it is not necessary to fully compile 100% of your components or hooks to see benefits in your library. A good starting point might be to identify the most performance sensitive parts of your library and ensuring that they don’t break the [Rules of React](/reference/rules), which you can use `eslint-plugin-react-compiler` to identify.

## Usage[](#installation "Link for Usage ")

### Babel[](#usage-with-babel "Link for Babel ")

Terminal

npm install babel-plugin-react-compiler\@beta

The compiler includes a Babel plugin which you can use in your build pipeline to run the compiler.

After installing, add it to your Babel config. Please note that it’s critical that the compiler run **first** in the pipeline:

```
// babel.config.js

const ReactCompilerConfig = { /* ... */ };



module.exports = function () {

  return {

    plugins: [

      ['babel-plugin-react-compiler', ReactCompilerConfig], // must run first!

      // ...

    ],

  };

};
```

`babel-plugin-react-compiler` should run first before other Babel plugins as the compiler requires the input source information for sound analysis.

### Vite[](#usage-with-vite "Link for Vite ")

If you use Vite, you can add the plugin to vite-plugin-react:

```
// vite.config.js

const ReactCompilerConfig = { /* ... */ };



export default defineConfig(() => {

  return {

    plugins: [

      react({

        babel: {

          plugins: [

            ["babel-plugin-react-compiler", ReactCompilerConfig],

          ],

        },

      }),

    ],

    // ...

  };

});
```

### Next.js[](#usage-with-nextjs "Link for Next.js ")

Please refer to the [Next.js docs](https://nextjs.org/docs/app/api-reference/next-config-js/reactCompiler) for more information.

### Remix[](#usage-with-remix "Link for Remix ")

Install `vite-plugin-babel`, and add the compiler’s Babel plugin to it:

Terminal

npm install vite-plugin-babel

```
// vite.config.js

import babel from "vite-plugin-babel";



const ReactCompilerConfig = { /* ... */ };



export default defineConfig({

  plugins: [

    remix({ /* ... */}),

    babel({

      filter: /\.[jt]sx?$/,

      babelConfig: {

        presets: ["@babel/preset-typescript"], // if you use TypeScript

        plugins: [

          ["babel-plugin-react-compiler", ReactCompilerConfig],

        ],

      },

    }),

  ],

});
```

### Webpack[](#usage-with-webpack "Link for Webpack ")

A community Webpack loader is [now available here](https://github.com/SukkaW/react-compiler-webpack).

### Expo[](#usage-with-expo "Link for Expo ")

Please refer to [Expo’s docs](https://docs.expo.dev/guides/react-compiler/) to enable and use the React Compiler in Expo apps.

### Metro (React Native)[](#usage-with-react-native-metro "Link for Metro (React Native) ")

React Native uses Babel via Metro, so refer to the [Usage with Babel](#usage-with-babel) section for installation instructions.

### Rspack[](#usage-with-rspack "Link for Rspack ")

Please refer to [Rspack’s docs](https://rspack.dev/guide/tech/react#react-compiler) to enable and use the React Compiler in Rspack apps.

### Rsbuild[](#usage-with-rsbuild "Link for Rsbuild ")

Please refer to [Rsbuild’s docs](https://rsbuild.dev/guide/framework/react#react-compiler) to enable and use the React Compiler in Rsbuild apps.

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

To report issues, please first create a minimal repro on the [React Compiler Playground](https://playground.react.dev/) and include it in your bug report. You can open issues in the [facebook/react](https://github.com/facebook/react/issues) repo.

You can also provide feedback in the React Compiler Working Group by applying to be a member. Please see [the README for more details on joining](https://github.com/reactwg/react-compiler).

### What does the compiler assume?[](#what-does-the-compiler-assume "Link for What does the compiler assume? ")

React Compiler assumes that your code:

1. Is valid, semantic JavaScript.
2. Tests that nullable/optional values and properties are defined before accessing them (for example, by enabling [`strictNullChecks`](https://www.typescriptlang.org/tsconfig/#strictNullChecks) if using TypeScript), i.e., `if (object.nullableProperty) { object.nullableProperty.foo }` or with optional-chaining `object.nullableProperty?.foo`.
3. Follows the [Rules of React](https://react.dev/reference/rules).

React Compiler can verify many of the Rules of React statically, and will safely skip compilation when it detects an error. To see the errors we recommend also installing [eslint-plugin-react-compiler](https://www.npmjs.com/package/eslint-plugin-react-compiler).

### How do I know my components have been optimized?[](#how-do-i-know-my-components-have-been-optimized "Link for How do I know my components have been optimized? ")

[React Devtools](/learn/react-developer-tools) (v5.0+) has built-in support for React Compiler and will display a “Memo ✨” badge next to components that have been optimized by the compiler.

### Something is not working after compilation[](#something-is-not-working-after-compilation "Link for Something is not working after compilation ")

If you have eslint-plugin-react-compiler installed, the compiler will display any violations of the rules of React in your editor. When it does this, it means that the compiler has skipped over optimizing that component or hook. This is perfectly okay, and the compiler can recover and continue optimizing other components in your codebase. **You don’t have to fix all ESLint violations straight away.** You can address them at your own pace to increase the amount of components and hooks being optimized.

Due to the flexible and dynamic nature of JavaScript however, it’s not possible to comprehensively detect all cases. Bugs and undefined behavior such as infinite loops may occur in those cases.

If your app doesn’t work properly after compilation and you aren’t seeing any ESLint errors, the compiler may be incorrectly compiling your code. To confirm this, try to make the issue go away by aggressively opting out any component or hook you think might be related via the [`"use no memo"` directive](#opt-out-of-the-compiler-for-a-component).

```
function SuspiciousComponent() {

  "use no memo"; // opts out this component from being compiled by React Compiler

  // ...

}
```

### Note

#### `"use no memo"`[](#use-no-memo "Link for this heading")

`"use no memo"` is a *temporary* escape hatch that lets you opt-out components and hooks from being compiled by the React Compiler. This directive is not meant to be long lived the same way as eg [`"use client"`](/reference/rsc/use-client) is.

It is not recommended to reach for this directive unless it’s strictly necessary. Once you opt-out a component or hook, it is opted-out forever until the directive is removed. This means that even if you fix the code, the compiler will still skip over compiling it unless you remove the directive.

When you make the error go away, confirm that removing the opt out directive makes the issue come back. Then share a bug report with us (you can try to reduce it to a small repro, or if it’s open source code you can also just paste the entire source) using the [React Compiler Playground](https://playground.react.dev) so we can identify and help fix the issue.

### Other issues[](#other-issues "Link for Other issues ")

Please see <https://github.com/reactwg/react-compiler/discussions/7>.

[PreviousReact Developer Tools](/learn/react-developer-tools)

***

----
url: https://react.dev/learn/updating-arrays-in-state
----

|           | avoid (mutates the array)           | prefer (returns a new array)                                        |
| --------- | ----------------------------------- | ------------------------------------------------------------------- |
| adding    | `push`, `unshift`                   | `concat`, `[...arr]` spread syntax ([example](#adding-to-an-array)) |
| removing  | `pop`, `shift`, `splice`            | `filter`, `slice` ([example](#removing-from-an-array))              |
| replacing | `splice`, `arr[i] = ...` assignment | `map` ([example](#replacing-items-in-an-array))                     |
| sorting   | `reverse`, `sort`                   | copy the array first ([example](#making-other-changes-to-an-array)) |

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

let nextId = 0;

export default function List() {
  const [name, setName] = useState('');
  const [artists, setArtists] = useState([]);

  return (
    <>
      <h1>Inspiring sculptors:</h1>
      <input
        value={name}
        onChange={e => setName(e.target.value)}
      />
      <button onClick={() => {
        artists.push({
          id: nextId++,
          name: name,
        });
      }}>Add</button>
      <ul>
        {artists.map(artist => (
          <li key={artist.id}>{artist.name}</li>
        ))}
      </ul>
    </>
  );
}
```

Instead, create a *new* array which contains the existing items *and* a new item at the end. There are multiple ways to do this, but the easiest one is to use the `...` [array spread](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax#spread_in_array_literals) syntax:

```
setArtists( // Replace the state

  [ // with a new array

    ...artists, // that contains all the old items

    { id: nextId++, name: name } // and one new item at the end

  ]

);
```

Now it works correctly:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

let nextId = 0;

export default function List() {
  const [name, setName] = useState('');
  const [artists, setArtists] = useState([]);

  return (
    <>
      <h1>Inspiring sculptors:</h1>
      <input
        value={name}
        onChange={e => setName(e.target.value)}
      />
      <button onClick={() => {
        setArtists([
          ...artists,
          { id: nextId++, name: name }
        ]);
      }}>Add</button>
      <ul>
        {artists.map(artist => (
          <li key={artist.id}>{artist.name}</li>
        ))}
      </ul>
    </>
  );
}
```

The array spread syntax also lets you prepend an item by placing it *before* the original `...artists`:

```
setArtists([

  { id: nextId++, name: name },

  ...artists // Put old items at the end

]);
```

In this way, spread can do the job of both `push()` by adding to the end of an array and `unshift()` by adding to the beginning of an array. Try it in the sandbox above!

### Removing from an array[](#removing-from-an-array "Link for Removing from an array ")

The easiest way to remove an item from an array is to *filter it out*. In other words, you will produce a new array that will not contain that item. To do this, use the `filter` method, for example:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

let initialArtists = [
  { id: 0, name: 'Marta Colvin Andrade' },
  { id: 1, name: 'Lamidi Olonade Fakeye'},
  { id: 2, name: 'Louise Nevelson'},
];

export default function List() {
  const [artists, setArtists] = useState(
    initialArtists
  );

  return (
    <>
      <h1>Inspiring sculptors:</h1>
      <ul>
        {artists.map(artist => (
          <li key={artist.id}>
            {artist.name}{' '}
            <button onClick={() => {
              setArtists(
                artists.filter(a =>
                  a.id !== artist.id
                )
              );
            }}>
              Delete
            </button>
          </li>
        ))}
      </ul>
    </>
  );
}
```

Click the “Delete” button a few times, and look at its click handler.

```
setArtists(

  artists.filter(a => a.id !== artist.id)

);
```

Here, `artists.filter(a => a.id !== artist.id)` means “create an array that consists of those `artists` whose IDs are different from `artist.id`”. In other words, each artist’s “Delete” button will filter *that* artist out of the array, and then request a re-render with the resulting array. Note that `filter` does not modify the original array.

### Transforming an array[](#transforming-an-array "Link for Transforming an array ")

If you want to change some or all items of the array, you can use `map()` to create a **new** array. The function you will pass to `map` can decide what to do with each item, based on its data or its index (or both).

In this example, an array holds coordinates of two circles and a square. When you press the button, it moves only the circles down by 50 pixels. It does this by producing a new array of data using `map()`:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

let initialShapes = [
  { id: 0, type: 'circle', x: 50, y: 100 },
  { id: 1, type: 'square', x: 150, y: 100 },
  { id: 2, type: 'circle', x: 250, y: 100 },
];

export default function ShapeEditor() {
  const [shapes, setShapes] = useState(
    initialShapes
  );

  function handleClick() {
    const nextShapes = shapes.map(shape => {
      if (shape.type === 'square') {
        // No change
        return shape;
      } else {
        // Return a new circle 50px below
        return {
          ...shape,
          y: shape.y + 50,
        };
      }
    });
    // Re-render with the new array
    setShapes(nextShapes);
  }

  return (
    <>
      <button onClick={handleClick}>
        Move circles down!
      </button>
      {shapes.map(shape => (
        <div
          key={shape.id}
          style={{
          background: 'purple',
          position: 'absolute',
          left: shape.x,
          top: shape.y,
          borderRadius:
            shape.type === 'circle'
              ? '50%' : '',
          width: 20,
          height: 20,
        }} />
      ))}
    </>
  );
}
```

### Replacing items in an array[](#replacing-items-in-an-array "Link for Replacing items in an array ")

It is particularly common to want to replace one or more items in an array. Assignments like `arr[0] = 'bird'` are mutating the original array, so instead you’ll want to use `map` for this as well.

To replace an item, create a new array with `map`. Inside your `map` call, you will receive the item index as the second argument. Use it to decide whether to return the original item (the first argument) or something else:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

let initialCounters = [
  0, 0, 0
];

export default function CounterList() {
  const [counters, setCounters] = useState(
    initialCounters
  );

  function handleIncrementClick(index) {
    const nextCounters = counters.map((c, i) => {
      if (i === index) {
        // Increment the clicked counter
        return c + 1;
      } else {
        // The rest haven't changed
        return c;
      }
    });
    setCounters(nextCounters);
  }

  return (
    <ul>
      {counters.map((counter, i) => (
        <li key={i}>
          {counter}
          <button onClick={() => {
            handleIncrementClick(i);
          }}>+1</button>
        </li>
      ))}
    </ul>
  );
}
```

### Inserting into an array[](#inserting-into-an-array "Link for Inserting into an array ")

Sometimes, you may want to insert an item at a particular position that’s neither at the beginning nor at the end. To do this, you can use the `...` array spread syntax together with the `slice()` method. The `slice()` method lets you cut a “slice” of the array. To insert an item, you will create an array that spreads the slice *before* the insertion point, then the new item, and then the rest of the original array.

In this example, the Insert button always inserts at the index `1`:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

let nextId = 3;
const initialArtists = [
  { id: 0, name: 'Marta Colvin Andrade' },
  { id: 1, name: 'Lamidi Olonade Fakeye'},
  { id: 2, name: 'Louise Nevelson'},
];

export default function List() {
  const [name, setName] = useState('');
  const [artists, setArtists] = useState(
    initialArtists
  );

  function handleClick() {
    const insertAt = 1; // Could be any index
    const nextArtists = [
      // Items before the insertion point:
      ...artists.slice(0, insertAt),
      // New item:
      { id: nextId++, name: name },
      // Items after the insertion point:
      ...artists.slice(insertAt)
    ];
    setArtists(nextArtists);
    setName('');
  }

  return (
    <>
      <h1>Inspiring sculptors:</h1>
      <input
        value={name}
        onChange={e => setName(e.target.value)}
      />
      <button onClick={handleClick}>
        Insert
      </button>
      <ul>
        {artists.map(artist => (
          <li key={artist.id}>{artist.name}</li>
        ))}
      </ul>
    </>
  );
}
```

### Making other changes to an array[](#making-other-changes-to-an-array "Link for Making other changes to an array ")

There are some things you can’t do with the spread syntax and non-mutating methods like `map()` and `filter()` alone. For example, you may want to reverse or sort an array. The JavaScript `reverse()` and `sort()` methods are mutating the original array, so you can’t use them directly.

**However, you can copy the array first, and then make changes to it.**

For example:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

const initialList = [
  { id: 0, title: 'Big Bellies' },
  { id: 1, title: 'Lunar Landscape' },
  { id: 2, title: 'Terracotta Army' },
];

export default function List() {
  const [list, setList] = useState(initialList);

  function handleClick() {
    const nextList = [...list];
    nextList.reverse();
    setList(nextList);
  }

  return (
    <>
      <button onClick={handleClick}>
        Reverse
      </button>
      <ul>
        {list.map(artwork => (
          <li key={artwork.id}>{artwork.title}</li>
        ))}
      </ul>
    </>
  );
}
```

Here, you use the `[...list]` spread syntax to create a copy of the original array first. Now that you have a copy, you can use mutating methods like `nextList.reverse()` or `nextList.sort()`, or even assign individual items with `nextList[0] = "something"`.

However, **even if you copy an array, you can’t mutate existing items *inside* of it directly.** This is because copying is shallow—the new array will contain the same items as the original one. So if you modify an object inside the copied array, you are mutating the existing state. For example, code like this is a problem.

```
const nextList = [...list];

nextList[0].seen = true; // Problem: mutates list[0]

setList(nextList);
```

Although `nextList` and `list` are two different arrays, **`nextList[0]` and `list[0]` point to the same object.** So by changing `nextList[0].seen`, you are also changing `list[0].seen`. This is a state mutation, which you should avoid! You can solve this issue in a similar way to [updating nested JavaScript objects](/learn/updating-objects-in-state#updating-a-nested-object)—by copying individual items you want to change instead of mutating them. Here’s how.

## Updating objects inside arrays[](#updating-objects-inside-arrays "Link for Updating objects inside arrays ")

Objects are not *really* located “inside” arrays. They might appear to be “inside” in code, but each object in an array is a separate value, to which the array “points”. This is why you need to be careful when changing nested fields like `list[0]`. Another person’s artwork list may point to the same element of the array!

**When updating nested state, you need to create copies from the point where you want to update, and all the way up to the top level.** Let’s see how this works.

In this example, two separate artwork lists have the same initial state. They are supposed to be isolated, but because of a mutation, their state is accidentally shared, and checking a box in one list affects the other list:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

let nextId = 3;
const initialList = [
  { id: 0, title: 'Big Bellies', seen: false },
  { id: 1, title: 'Lunar Landscape', seen: false },
  { id: 2, title: 'Terracotta Army', seen: true },
];

export default function BucketList() {
  const [myList, setMyList] = useState(initialList);
  const [yourList, setYourList] = useState(
    initialList
  );

  function handleToggleMyList(artworkId, nextSeen) {
    const myNextList = [...myList];
    const artwork = myNextList.find(
      a => a.id === artworkId
    );
    artwork.seen = nextSeen;
    setMyList(myNextList);
  }

  function handleToggleYourList(artworkId, nextSeen) {
    const yourNextList = [...yourList];
    const artwork = yourNextList.find(
      a => a.id === artworkId
    );
    artwork.seen = nextSeen;
    setYourList(yourNextList);
  }

  return (
    <>
      <h1>Art Bucket List</h1>
      <h2>My list of art to see:</h2>
      <ItemList
        artworks={myList}
        onToggle={handleToggleMyList} />
      <h2>Your list of art to see:</h2>
      <ItemList
        artworks={yourList}
        onToggle={handleToggleYourList} />
    </>
  );
}

function ItemList({ artworks, onToggle }) {
  return (
    <ul>
      {artworks.map(artwork => (
        <li key={artwork.id}>
          <label>
            <input
              type="checkbox"
              checked={artwork.seen}
              onChange={e => {
                onToggle(
                  artwork.id,
                  e.target.checked
                );
              }}
            />
            {artwork.title}
          </label>
        </li>
      ))}
    </ul>
  );
}
```

The problem is in code like this:

```
const myNextList = [...myList];

const artwork = myNextList.find(a => a.id === artworkId);

artwork.seen = nextSeen; // Problem: mutates an existing item

setMyList(myNextList);
```

Although the `myNextList` array itself is new, the *items themselves* are the same as in the original `myList` array. So changing `artwork.seen` changes the *original* artwork item. That artwork item is also in `yourList`, which causes the bug. Bugs like this can be difficult to think about, but thankfully they disappear if you avoid mutating state.

**You can use `map` to substitute an old item with its updated version without mutation.**

```
setMyList(myList.map(artwork => {

  if (artwork.id === artworkId) {

    // Create a *new* object with changes

    return { ...artwork, seen: nextSeen };

  } else {

    // No changes

    return artwork;

  }

}));
```

Here, `...` is the object spread syntax used to [create a copy of an object.](/learn/updating-objects-in-state#copying-objects-with-the-spread-syntax)

With this approach, none of the existing state items are being mutated, and the bug is fixed:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

let nextId = 3;
const initialList = [
  { id: 0, title: 'Big Bellies', seen: false },
  { id: 1, title: 'Lunar Landscape', seen: false },
  { id: 2, title: 'Terracotta Army', seen: true },
];

export default function BucketList() {
  const [myList, setMyList] = useState(initialList);
  const [yourList, setYourList] = useState(
    initialList
  );

  function handleToggleMyList(artworkId, nextSeen) {
    setMyList(myList.map(artwork => {
      if (artwork.id === artworkId) {
        // Create a *new* object with changes
        return { ...artwork, seen: nextSeen };
      } else {
        // No changes
        return artwork;
      }
    }));
  }

  function handleToggleYourList(artworkId, nextSeen) {
    setYourList(yourList.map(artwork => {
      if (artwork.id === artworkId) {
        // Create a *new* object with changes
        return { ...artwork, seen: nextSeen };
      } else {
        // No changes
        return artwork;
      }
    }));
  }

  return (
    <>
      <h1>Art Bucket List</h1>
      <h2>My list of art to see:</h2>
      <ItemList
        artworks={myList}
        onToggle={handleToggleMyList} />
      <h2>Your list of art to see:</h2>
      <ItemList
        artworks={yourList}
        onToggle={handleToggleYourList} />
    </>
  );
}

function ItemList({ artworks, onToggle }) {
  return (
    <ul>
      {artworks.map(artwork => (
        <li key={artwork.id}>
          <label>
            <input
              type="checkbox"
              checked={artwork.seen}
              onChange={e => {
                onToggle(
                  artwork.id,
                  e.target.checked
                );
              }}
            />
            {artwork.title}
          </label>
        </li>
      ))}
    </ul>
  );
}
```

In general, **you should only mutate objects that you have just created.** If you were inserting a *new* artwork, you could mutate it, but if you’re dealing with something that’s already in state, you need to make a copy.

### Write concise update logic with Immer[](#write-concise-update-logic-with-immer "Link for Write concise update logic with Immer ")

Updating nested arrays without mutation can get a little bit repetitive. [Just as with objects](/learn/updating-objects-in-state#write-concise-update-logic-with-immer):

* Generally, you shouldn’t need to update state more than a couple of levels deep. If your state objects are very deep, you might want to [restructure them differently](/learn/choosing-the-state-structure#avoid-deeply-nested-state) so that they are flat.
* If you don’t want to change your state structure, you might prefer to use [Immer](https://github.com/immerjs/use-immer), which lets you write using the convenient but mutating syntax and takes care of producing the copies for you.

Here is the Art Bucket List example rewritten with Immer:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
{
  "dependencies": {
    "immer": "1.7.3",
    "react": "latest",
    "react-dom": "latest",
    "react-scripts": "latest",
    "use-immer": "0.5.1"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject"
  },
  "devDependencies": {}
}
```

Note how with Immer, **mutation like `artwork.seen = nextSeen` is now okay:**

```
updateMyTodos(draft => {

  const artwork = draft.find(a => a.id === artworkId);

  artwork.seen = nextSeen;

});
```

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

const initialProducts = [{
  id: 0,
  name: 'Baklava',
  count: 1,
}, {
  id: 1,
  name: 'Cheese',
  count: 5,
}, {
  id: 2,
  name: 'Spaghetti',
  count: 2,
}];

export default function ShoppingCart() {
  const [
    products,
    setProducts
  ] = useState(initialProducts)

  function handleIncreaseClick(productId) {

  }

  return (
    <ul>
      {products.map(product => (
        <li key={product.id}>
          {product.name}
          {' '}
          (<b>{product.count}</b>)
          <button onClick={() => {
            handleIncreaseClick(product.id);
          }}>
            +
          </button>
        </li>
      ))}
    </ul>
  );
}
```

[PreviousUpdating Objects in State](/learn/updating-objects-in-state)

[NextManaging State](/learn/managing-state)

***

----
url: https://react.dev/reference/eslint-plugin-react-hooks/lints/exhaustive-deps
----

[API Reference](/reference/react)

[Lints](/reference/eslint-plugin-react-hooks)

# exhaustive-deps[](#undefined "Link for this heading")

Validates that dependency arrays for React hooks contain all necessary dependencies.

## Rule Details[](#rule-details "Link for Rule Details ")

React hooks like `useEffect`, `useMemo`, and `useCallback` accept dependency arrays. When a value referenced inside these hooks isn’t included in the dependency array, React won’t re-run the effect or recalculate the value when that dependency changes. This causes stale closures where the hook uses outdated values.

## Common Violations[](#common-violations "Link for Common Violations ")

This error often happens when you try to “trick” React about dependencies to control when an effect runs. Effects should synchronize your component with external systems. The dependency array tells React which values the effect uses, so React knows when to re-synchronize.

If you find yourself fighting with the linter, you likely need to restructure your code. See [Removing Effect Dependencies](/learn/removing-effect-dependencies) to learn how.

### Invalid[](#invalid "Link for Invalid ")

Examples of incorrect code for this rule:

```
// ❌ Missing dependency

useEffect(() => {

  console.log(count);

}, []); // Missing 'count'



// ❌ Missing prop

useEffect(() => {

  fetchUser(userId);

}, []); // Missing 'userId'



// ❌ Incomplete dependencies

useMemo(() => {

  return items.sort(sortOrder);

}, [items]); // Missing 'sortOrder'
```

### Valid[](#valid "Link for Valid ")

Examples of correct code for this rule:

```
// ✅ All dependencies included

useEffect(() => {

  console.log(count);

}, [count]);



// ✅ All dependencies included

useEffect(() => {

  fetchUser(userId);

}, [userId]);
```

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### Adding a function dependency causes infinite loops[](#function-dependency-loops "Link for Adding a function dependency causes infinite loops ")

You have an effect, but you’re creating a new function on every render:

```
// ❌ Causes infinite loop

const logItems = () => {

  console.log(items);

};



useEffect(() => {

  logItems();

}, [logItems]); // Infinite loop!
```

In most cases, you don’t need the effect. Call the function where the action happens instead:

```
// ✅ Call it from the event handler

const logItems = () => {

  console.log(items);

};



return <button onClick={logItems}>Log</button>;



// ✅ Or derive during render if there's no side effect

items.forEach(item => {

  console.log(item);

});
```

If you genuinely need the effect (for example, to subscribe to something external), make the dependency stable:

```
// ✅ useCallback keeps the function reference stable

const logItems = useCallback(() => {

  console.log(items);

}, [items]);



useEffect(() => {

  logItems();

}, [logItems]);



// ✅ Or move the logic straight into the effect

useEffect(() => {

  console.log(items);

}, [items]);
```

### Running an effect only once[](#effect-on-mount "Link for Running an effect only once ")

You want to run an effect once on mount, but the linter complains about missing dependencies:

```
// ❌ Missing dependency

useEffect(() => {

  sendAnalytics(userId);

}, []); // Missing 'userId'
```

Either include the dependency (recommended) or use a ref if you truly need to run once:

```
// ✅ Include dependency

useEffect(() => {

  sendAnalytics(userId);

}, [userId]);



// ✅ Or use a ref guard inside an effect

const sent = useRef(false);



useEffect(() => {

  if (sent.current) {

    return;

  }



  sent.current = true;

  sendAnalytics(userId);

}, [userId]);
```

## Options[](#options "Link for Options ")

You can configure custom effect hooks using shared ESLint settings (available in `eslint-plugin-react-hooks` 6.1.1 and later):

```
{

  "settings": {

    "react-hooks": {

      "additionalEffectHooks": "(useMyEffect|useCustomEffect)"

    }

  }

}
```

* `additionalEffectHooks`: Regex pattern matching custom hooks that should be checked for exhaustive dependencies. This configuration is shared across all `react-hooks` rules.

For backward compatibility, this rule also accepts a rule-level option:

```
{

  "rules": {

    "react-hooks/exhaustive-deps": ["warn", {

      "additionalHooks": "(useMyCustomHook|useAnotherHook)"

    }]

  }

}
```

* `additionalHooks`: Regex for hooks that should be checked for exhaustive dependencies. **Note:** If this rule-level option is specified, it takes precedence over the shared `settings` configuration.

[PreviousLints](/reference/eslint-plugin-react-hooks)

[Nextrules-of-hooks](/reference/eslint-plugin-react-hooks/lints/rules-of-hooks)

***

----
url: https://legacy.reactjs.org/blog/2015/02/20/introducing-relay-and-graphql.html
----

February 20, 2015 by [Greg Hurrell](https://twitter.com/wincent)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

## [](#data-fetching-for-react-applications)Data fetching for React applications

There’s more to building an application than creating a user interface. Data fetching is still a tricky problem, especially as applications become more complicated. At [React.js Conf](http://conf.reactjs.com/) we announced two projects we’ve created at Facebook to make data fetching simple for developers, even as a product grows to include dozens of contributors and the application becomes as complex as Facebook itself.

The two projects — Relay and GraphQL — have been in use in production at Facebook for some time, and we’re excited to be bringing them to the world as open source in the future. In the meantime, we wanted to share some additional information about the projects here.

## [](#what-is-relay)What is Relay?

Relay is a new framework from Facebook that provides data-fetching functionality for React applications. It was announced at React.js Conf (January 2015).

Each component specifies its own data dependencies declaratively using a query language called GraphQL. The data is made available to the component via properties on `this.props`.

Developers compose these React components naturally, and Relay takes care of composing the data queries into efficient batches, providing each component with exactly the data that it requested (and no more), updating those components when the data changes, and maintaining a client-side store (cache) of all data.

## [](#what-is-graphql)What is GraphQL?

GraphQL is a data querying language designed to describe the complex, nested data dependencies of modern applications. It’s been in production use in Facebook’s native apps for several years.

On the server, we configure the GraphQL system to map queries to underlying data-fetching code. This configuration layer allows GraphQL to work with arbitrary underlying storage mechanisms. Relay uses GraphQL as its query language, but it is not tied to a specific implementation of GraphQL.

## [](#the-value-proposition)The value proposition

Relay was born out of our experiences building large applications at Facebook. Our overarching goal is to enable developers to create correct, high-performance applications in a straightforward and obvious way. The design enables even large teams to make changes with a high degree of isolation and confidence. Fetching data is hard, dealing with ever-changing data is hard, and performance is hard. Relay aims to reduce these problems to simple ones, moving the tricky bits into the framework and freeing you to concentrate on building your application.

By co-locating the queries with the view code, the developer can reason about what a component is doing by looking at it in isolation; it’s not necessary to consider the context where the component was rendered in order to understand it. Components can be moved anywhere in a render hierarchy without having to apply a cascade of modifications to parent components or to the server code which prepares the data payload.

Co-location leads developers to fall into the “pit of success”, because they get exactly the data they asked for and the data they asked for is explicitly defined right next to where it is used. This means that performance becomes the default (it becomes much harder to accidentally over-fetch), and components are more robust (under-fetching is also less likely for the same reason, so components won’t try to render missing data and blow up at runtime).

Relay provides a predictable environment for developers by maintaining an invariant: a component won’t be rendered until all the data it requested is available. Additionally, queries are defined statically (ie. we can extract queries from a component tree before rendering) and the GraphQL schema provides an authoritative description of what queries are valid, so we can validate queries early and fail fast when the developer makes a mistake.

Only the fields of an object that a component explicitly asks for will be accessible to that component, even if other fields are known and cached in the store (because another component requested them). This makes it impossible for implicit data dependency bugs to exist latently in the system.

By handling all data-fetching via a single abstraction, we’re able to handle a bunch of things that would otherwise have to be dealt with repeatedly and pervasively across the application:

* **Performance:** All queries flow through the framework code, where things that would otherwise be inefficient, repeated query patterns get automatically collapsed and batched into efficient, minimal queries. Likewise, the framework knows which data have been previously requested, or for which requests are currently “in flight”, so queries can be automatically de-duplicated and the minimal queries can be produced.
* **Subscriptions:** All data flows into a single store, and all reads from the store are via the framework. This means the framework knows which components care about which data and which should be re-rendered when data changes; components never have to set up individual subscriptions.
* **Common patterns:** We can make common patterns easy. Pagination is the example that [Jing](https://twitter.com/jingc) gave at the conference: if you have 10 records initially, getting the next page just means declaring you want 15 records in total, and the framework automatically constructs the minimal query to grab the delta between what you have and what you need, requests it, and re-renders your view when the data become available.
* **Simplified server implementation:** Rather than having a proliferation of end-points (per action, per route), a single GraphQL endpoint can serve as a facade for any number of underlying resources.
* **Uniform mutations:** There is one consistent pattern for performing mutations (writes), and it is conceptually baked into the data querying model itself. You can think of a mutation as a query with side-effects: you provide some parameters that describe the change to be made (eg. attaching a comment to a record) and a query that specifies the data you’ll need to update your view of the world after the mutation completes (eg. the comment count on the record), and the data flows through the system using the normal flow. We can do an immediate “optimistic” update on the client (ie. update the view under the assumption that the write will succeed), and finally commit it, retry it or roll it back in the event of an error when the server payload comes back.

## [](#how-does-it-relate-to-flux)How does it relate to Flux?

In some ways Relay is inspired by Flux, but the mental model is much simpler. Instead of multiple stores, there is one central store that caches all GraphQL data. Instead of explicit subscriptions, the framework itself can track which data each component requests, and which components should be updated whenever the data change. Instead of actions, modifications take the form of mutations.

At Facebook, we have apps built entirely using Flux, entirely using Relay, or with both. One pattern we see emerging is letting Relay manage the bulk of the data flow for an application, but using Flux stores on the side to handle a subset of application state.

## [](#open-source-plans)Open source plans

We’re working very hard right now on getting both GraphQL (a spec, and a reference implementation) and Relay ready for public release (no specific dates yet, but we are super excited about getting these out there).

In the meantime, we’ll be providing more and more information in the form of blog posts (and in [other channels](https://gist.github.com/wincent/598fa75e22bdfa44cf47)). As we get closer to the open source release, you can expect more concrete details, syntax and API descriptions and more.

Watch this space!

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2015-02-20-introducing-relay-and-graphql.md)

----
url: https://react.dev/reference/eslint-plugin-react-hooks/lints/incompatible-library
----

[API Reference](/reference/react)

[Lints](/reference/eslint-plugin-react-hooks)

# incompatible-library[](#undefined "Link for this heading")

Validates against usage of libraries which are incompatible with memoization (manual or automatic).

### Note

These libraries were designed before React’s memoization rules were fully documented. They made the correct choices at the time to optimize for ergonomic ways to keep components just the right amount of reactive as app state changes. While these legacy patterns worked, we have since discovered that it’s incompatible with React’s programming model. We will continue working with library authors to migrate these libraries to use patterns that follow the Rules of React.

## Rule Details[](#rule-details "Link for Rule Details ")

Some libraries use patterns that aren’t supported by React. When the linter detects usages of these APIs from a [known list](https://github.com/facebook/react/blob/main/compiler/packages/babel-plugin-react-compiler/src/HIR/DefaultModuleTypeProvider.ts), it flags them under this rule. This means that React Compiler can automatically skip over components that use these incompatible APIs, in order to avoid breaking your app.

```
// Example of how memoization breaks with these libraries

function Form() {

  const { watch } = useForm();



  // ❌ This value will never update, even when 'name' field changes

  const name = useMemo(() => watch('name'), [watch]);



  return <div>Name: {name}</div>; // UI appears "frozen"

}
```

React Compiler automatically memoizes values following the Rules of React. If something breaks with manual `useMemo`, it will also break the compiler’s automatic optimization. This rule helps identify these problematic patterns.

##### Deep Dive#### Designing APIs that follow the Rules of React[](#designing-apis-that-follow-the-rules-of-react "Link for Designing APIs that follow the Rules of React ")

One question to think about when designing a library API or hook is whether calling the API can be safely memoized with `useMemo`. If it can’t, then both manual and React Compiler memoizations will break your user’s code.

For example, one such incompatible pattern is “interior mutability”. Interior mutability is when an object or function keeps its own hidden state that changes over time, even though the reference to it stays the same. Think of it like a box that looks the same on the outside but secretly rearranges its contents. React can’t tell anything changed because it only checks if you gave it a different box, not what’s inside. This breaks memoization, since React relies on the outer object (or function) changing if part of its value has changed.

As a rule of thumb, when designing React APIs, think about whether `useMemo` would break it:

```
function Component() {

  const { someFunction } = useLibrary();

  // it should always be safe to memoize functions like this

  const result = useMemo(() => someFunction(), [someFunction]);

}
```

Instead, design APIs that return immutable state and use explicit update functions:

```
// ✅ Good: Return immutable state that changes reference when updated

function Component() {

  const { field, updateField } = useLibrary();

  // this is always safe to memo

  const greeting = useMemo(() => `Hello, ${field.name}!`, [field.name]);



  return (

    <div>

      <input

        value={field.name}

        onChange={(e) => updateField('name', e.target.value)}

      />

      <p>{greeting}</p>

    </div>

  );

}
```

### Invalid[](#invalid "Link for Invalid ")

Examples of incorrect code for this rule:

```
// ❌ react-hook-form `watch`

function Component() {

  const {watch} = useForm();

  const value = watch('field'); // Interior mutability

  return <div>{value}</div>;

}



// ❌ TanStack Table `useReactTable`

function Component({data}) {

  const table = useReactTable({

    data,

    columns,

    getCoreRowModel: getCoreRowModel(),

  });

  // table instance uses interior mutability

  return <Table table={table} />;

}
```

### Pitfall

#### MobX[](#mobx "Link for MobX ")

MobX patterns like `observer` also break memoization assumptions, but the linter does not yet detect them. If you rely on MobX and find that your app doesn’t work with React Compiler, you may need to use the `"use no memo" directive`.

```
// ❌ MobX `observer`

const Component = observer(() => {

  const [timer] = useState(() => new Timer());

  return <span>Seconds passed: {timer.secondsPassed}</span>;

});
```

### Valid[](#valid "Link for Valid ")

Examples of correct code for this rule:

```
// ✅ For react-hook-form, use `useWatch`:

function Component() {

  const {register, control} = useForm();

  const watchedValue = useWatch({

    control,

    name: 'field'

  });



  return (

    <>

      <input {...register('field')} />

      <div>Current value: {watchedValue}</div>

    </>

  );

}
```

Some other libraries do not yet have alternative APIs that are compatible with React’s memoization model. If the linter doesn’t automatically skip over your components or hooks that call these APIs, please [file an issue](https://github.com/facebook/react/issues) so we can add it to the linter.

[Previousimmutability](/reference/eslint-plugin-react-hooks/lints/immutability)

[Nextpreserve-manual-memoization](/reference/eslint-plugin-react-hooks/lints/preserve-manual-memoization)

***

----
url: https://react.dev/learn/writing-markup-with-jsx
----

```
<h1>Hedy Lamarr's Todos</h1>

<img

  src="https://react.dev/images/docs/scientists/yXOvdOSs.jpg"

  alt="Hedy Lamarr"

  class="photo"

>

<ul>

    <li>Invent new traffic lights

    <li>Rehearse a movie scene

    <li>Improve the spectrum technology

</ul>
```

And you want to put it into your component:

```
export default function TodoList() {

  return (

    // ???

  )

}
```

If you copy and paste it as is, it will not work:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
export default function TodoList() {
  return (
    // This doesn't quite work!
    <h1>Hedy Lamarr's Todos</h1>
    <img
      src="https://react.dev/images/docs/scientists/yXOvdOSs.jpg"
      alt="Hedy Lamarr"
      class="photo"
    >
    <ul>
      <li>Invent new traffic lights
      <li>Rehearse a movie scene
      <li>Improve the spectrum technology
    </ul>
```

```
<div>

  <h1>Hedy Lamarr's Todos</h1>

  <img

    src="https://react.dev/images/docs/scientists/yXOvdOSs.jpg"

    alt="Hedy Lamarr"

    class="photo"

  >

  <ul>

    ...

  </ul>

</div>
```

If you don’t want to add an extra `<div>` to your markup, you can write `<>` and `</>` instead:

```
<>

  <h1>Hedy Lamarr's Todos</h1>

  <img

    src="https://react.dev/images/docs/scientists/yXOvdOSs.jpg"

    alt="Hedy Lamarr"

    class="photo"

  >

  <ul>

    ...

  </ul>

</>
```

This empty tag is called a *[Fragment.](/reference/react/Fragment)* Fragments let you group things without leaving any trace in the browser HTML tree.

##### Deep Dive#### Why do multiple JSX tags need to be wrapped?[](#why-do-multiple-jsx-tags-need-to-be-wrapped "Link for Why do multiple JSX tags need to be wrapped? ")

JSX looks like HTML, but under the hood it is transformed into plain JavaScript objects. You can’t return two objects from a function without wrapping them into an array. This explains why you also can’t return two JSX tags without wrapping them into another tag or a Fragment.

### 2. Close all the tags[](#2-close-all-the-tags "Link for 2. Close all the tags ")

JSX requires tags to be explicitly closed: self-closing tags like `<img>` must become `<img />`, and wrapping tags like `<li>oranges` must be written as `<li>oranges</li>`.

This is how Hedy Lamarr’s image and list items look closed:

```
<>

  <img

    src="https://react.dev/images/docs/scientists/yXOvdOSs.jpg"

    alt="Hedy Lamarr"

    class="photo"

   />

  <ul>

    <li>Invent new traffic lights</li>

    <li>Rehearse a movie scene</li>

    <li>Improve the spectrum technology</li>

  </ul>

</>
```

### 3. camelCase ~~all~~ most of the things\![](#3-camelcase-salls-most-of-the-things "Link for this heading")

JSX turns into JavaScript and attributes written in JSX become keys of JavaScript objects. In your own components, you will often want to read those attributes into variables. But JavaScript has limitations on variable names. For example, their names can’t contain dashes or be reserved words like `class`.

This is why, in React, many HTML and SVG attributes are written in camelCase. For example, instead of `stroke-width` you use `strokeWidth`. Since `class` is a reserved word, in React you write `className` instead, named after the [corresponding DOM property](https://developer.mozilla.org/en-US/docs/Web/API/Element/className):

```
<img

  src="https://react.dev/images/docs/scientists/yXOvdOSs.jpg"

  alt="Hedy Lamarr"

  className="photo"

/>
```

You can [find all these attributes in the list of DOM component props.](/reference/react-dom/components/common) If you get one wrong, don’t worry—React will print a message with a possible correction to the [browser console.](https://developer.mozilla.org/docs/Tools/Browser_Console)

### Pitfall

For historical reasons, [`aria-*`](https://developer.mozilla.org/docs/Web/Accessibility/ARIA) and [`data-*`](https://developer.mozilla.org/docs/Learn/HTML/Howto/Use_data_attributes) attributes are written as in HTML with dashes.

### Pro-tip: Use a JSX Converter[](#pro-tip-use-a-jsx-converter "Link for Pro-tip: Use a JSX Converter ")

Converting all these attributes in existing markup can be tedious! We recommend using a [converter](https://transform.tools/html-to-jsx) to translate your existing HTML and SVG to JSX. Converters are very useful in practice, but it’s still worth understanding what is going on so that you can comfortably write JSX on your own.

Here is your final result:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
export default function TodoList() {
  return (
    <>
      <h1>Hedy Lamarr's Todos</h1>
      <img
        src="https://react.dev/images/docs/scientists/yXOvdOSs.jpg"
        alt="Hedy Lamarr"
        className="photo"
      />
      <ul>
        <li>Invent new traffic lights</li>
        <li>Rehearse a movie scene</li>
        <li>Improve the spectrum technology</li>
      </ul>
    </>
  );
}
```

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
export default function Bio() {
  return (
    <div class="intro">
      <h1>Welcome to my website!</h1>
    </div>
    <p class="summary">
      You can find my thoughts here.
      <br><br>
      <b>And <i>pictures</b></i> of scientists!
    </p>
  );
}
```

Whether to do it by hand or using the converter is up to you!

[PreviousImporting and Exporting Components](/learn/importing-and-exporting-components)

[NextJavaScript in JSX with Curly Braces](/learn/javascript-in-jsx-with-curly-braces)

***

----
url: https://react.dev/learn/render-and-commit
----

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import Image from './Image.js';
import { createRoot } from 'react-dom/client';

const root = createRoot(document.getElementById('root'))
root.render(<Image />);
```

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
export default function Gallery() {
  return (
    <section>
      <h1>Inspiring Sculptures</h1>
      <Image />
      <Image />
      <Image />
    </section>
  );
}

function Image() {
  return (
    <img
      src="https://react.dev/images/docs/scientists/ZF6s192.jpg"
      alt="'Floralis Genérica' by Eduardo Catalano: a gigantic metallic flower sculpture with reflective petals"
    />
  );
}
```

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
export default function Clock({ time }) {
  return (
    <>
      <h1>{time}</h1>
      <input />
    </>
  );
}
```

***

----
url: https://react.dev/learn/scaling-up-with-reducer-and-context
----

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useReducer } from 'react';
import AddTask from './AddTask.js';
import TaskList from './TaskList.js';

export default function TaskApp() {
  const [tasks, dispatch] = useReducer(
    tasksReducer,
    initialTasks
  );

  function handleAddTask(text) {
    dispatch({
      type: 'added',
      id: nextId++,
      text: text,
    });
  }

  function handleChangeTask(task) {
    dispatch({
      type: 'changed',
      task: task
    });
  }

  function handleDeleteTask(taskId) {
    dispatch({
      type: 'deleted',
      id: taskId
    });
  }

  return (
    <>
      <h1>Day off in Kyoto</h1>
      <AddTask
        onAddTask={handleAddTask}
      />
      <TaskList
        tasks={tasks}
        onChangeTask={handleChangeTask}
        onDeleteTask={handleDeleteTask}
      />
    </>
  );
}

function tasksReducer(tasks, action) {
  switch (action.type) {
    case 'added': {
      return [...tasks, {
        id: action.id,
        text: action.text,
        done: false
      }];
    }
    case 'changed': {
      return tasks.map(t => {
        if (t.id === action.task.id) {
          return action.task;
        } else {
          return t;
        }
      });
    }
    case 'deleted': {
      return tasks.filter(t => t.id !== action.id);
    }
    default: {
      throw Error('Unknown action: ' + action.type);
    }
  }
}

let nextId = 3;
const initialTasks = [
  { id: 0, text: 'Philosopher’s Path', done: true },
  { id: 1, text: 'Visit the temple', done: false },
  { id: 2, text: 'Drink matcha', done: false }
];
```

A reducer helps keep the event handlers short and concise. However, as your app grows, you might run into another difficulty. **Currently, the `tasks` state and the `dispatch` function are only available in the top-level `TaskApp` component.** To let other components read the list of tasks or change it, you have to explicitly [pass down](/learn/passing-props-to-a-component) the current state and the event handlers that change it as props.

For example, `TaskApp` passes a list of tasks and the event handlers to `TaskList`:

```
<TaskList

  tasks={tasks}

  onChangeTask={handleChangeTask}

  onDeleteTask={handleDeleteTask}

/>
```

And `TaskList` passes the event handlers to `Task`:

```
<Task

  task={task}

  onChange={onChangeTask}

  onDelete={onDeleteTask}

/>
```

```
const [tasks, dispatch] = useReducer(tasksReducer, initialTasks);
```

To pass them down the tree, you will [create](/learn/passing-data-deeply-with-context#step-2-use-the-context) two separate contexts:

* `TasksContext` provides the current list of tasks.
* `TasksDispatchContext` provides the function that lets components dispatch actions.

Export them from a separate file so that you can later import them from other files:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { createContext } from 'react';

export const TasksContext = createContext(null);
export const TasksDispatchContext = createContext(null);
```

Here, you’re passing `null` as the default value to both contexts. The actual values will be provided by the `TaskApp` component.

### Step 2: Put state and dispatch into context[](#step-2-put-state-and-dispatch-into-context "Link for Step 2: Put state and dispatch into context ")

Now you can import both contexts in your `TaskApp` component. Take the `tasks` and `dispatch` returned by `useReducer()` and [provide them](/learn/passing-data-deeply-with-context#step-3-provide-the-context) to the entire tree below:

```
import { TasksContext, TasksDispatchContext } from './TasksContext.js';



export default function TaskApp() {

  const [tasks, dispatch] = useReducer(tasksReducer, initialTasks);

  // ...

  return (

    <TasksContext value={tasks}>

      <TasksDispatchContext value={dispatch}>

        ...

      </TasksDispatchContext>

    </TasksContext>

  );

}
```

For now, you pass the information both via props and in context:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useReducer } from 'react';
import AddTask from './AddTask.js';
import TaskList from './TaskList.js';
import { TasksContext, TasksDispatchContext } from './TasksContext.js';

export default function TaskApp() {
  const [tasks, dispatch] = useReducer(
    tasksReducer,
    initialTasks
  );

  function handleAddTask(text) {
    dispatch({
      type: 'added',
      id: nextId++,
      text: text,
    });
  }

  function handleChangeTask(task) {
    dispatch({
      type: 'changed',
      task: task
    });
  }

  function handleDeleteTask(taskId) {
    dispatch({
      type: 'deleted',
      id: taskId
    });
  }

  return (
    <TasksContext value={tasks}>
      <TasksDispatchContext value={dispatch}>
        <h1>Day off in Kyoto</h1>
        <AddTask
          onAddTask={handleAddTask}
        />
        <TaskList
          tasks={tasks}
          onChangeTask={handleChangeTask}
          onDeleteTask={handleDeleteTask}
        />
      </TasksDispatchContext>
    </TasksContext>
  );
}

function tasksReducer(tasks, action) {
  switch (action.type) {
    case 'added': {
      return [...tasks, {
        id: action.id,
        text: action.text,
        done: false
      }];
    }
    case 'changed': {
      return tasks.map(t => {
        if (t.id === action.task.id) {
          return action.task;
        } else {
          return t;
        }
      });
    }
    case 'deleted': {
      return tasks.filter(t => t.id !== action.id);
    }
    default: {
      throw Error('Unknown action: ' + action.type);
    }
  }
}

let nextId = 3;
const initialTasks = [
  { id: 0, text: 'Philosopher’s Path', done: true },
  { id: 1, text: 'Visit the temple', done: false },
  { id: 2, text: 'Drink matcha', done: false }
];
```

In the next step, you will remove prop passing.

### Step 3: Use context anywhere in the tree[](#step-3-use-context-anywhere-in-the-tree "Link for Step 3: Use context anywhere in the tree ")

Now you don’t need to pass the list of tasks or the event handlers down the tree:

```
<TasksContext value={tasks}>

  <TasksDispatchContext value={dispatch}>

    <h1>Day off in Kyoto</h1>

    <AddTask />

    <TaskList />

  </TasksDispatchContext>

</TasksContext>
```

Instead, any component that needs the task list can read it from the `TasksContext`:

```
export default function TaskList() {

  const tasks = useContext(TasksContext);

  // ...
```

To update the task list, any component can read the `dispatch` function from context and call it:

```
export default function AddTask() {

  const [text, setText] = useState('');

  const dispatch = useContext(TasksDispatchContext);

  // ...

  return (

    // ...

    <button onClick={() => {

      setText('');

      dispatch({

        type: 'added',

        id: nextId++,

        text: text,

      });

    }}>Add</button>

    // ...
```

**The `TaskApp` component does not pass any event handlers down, and the `TaskList` does not pass any event handlers to the `Task` component either.** Each component reads the context that it needs:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useContext } from 'react';
import { TasksContext, TasksDispatchContext } from './TasksContext.js';

export default function TaskList() {
  const tasks = useContext(TasksContext);
  return (
    <ul>
      {tasks.map(task => (
        <li key={task.id}>
          <Task task={task} />
        </li>
      ))}
    </ul>
  );
}

function Task({ task }) {
  const [isEditing, setIsEditing] = useState(false);
  const dispatch = useContext(TasksDispatchContext);
  let taskContent;
  if (isEditing) {
    taskContent = (
      <>
        <input
          value={task.text}
          onChange={e => {
            dispatch({
              type: 'changed',
              task: {
                ...task,
                text: e.target.value
              }
            });
          }} />
        <button onClick={() => setIsEditing(false)}>
          Save
        </button>
      </>
    );
  } else {
    taskContent = (
      <>
        {task.text}
        <button onClick={() => setIsEditing(true)}>
          Edit
        </button>
      </>
    );
  }
  return (
    <label>
      <input
        type="checkbox"
        checked={task.done}
        onChange={e => {
          dispatch({
            type: 'changed',
            task: {
              ...task,
              done: e.target.checked
            }
          });
        }}
      />
      {taskContent}
      <button onClick={() => {
        dispatch({
          type: 'deleted',
          id: task.id
        });
      }}>
        Delete
      </button>
    </label>
  );
}
```

**The state still “lives” in the top-level `TaskApp` component, managed with `useReducer`.** But its `tasks` and `dispatch` are now available to every component below in the tree by importing and using these contexts.

## Moving all wiring into a single file[](#moving-all-wiring-into-a-single-file "Link for Moving all wiring into a single file ")

You don’t have to do this, but you could further declutter the components by moving both reducer and context into a single file. Currently, `TasksContext.js` contains only two context declarations:

```
import { createContext } from 'react';



export const TasksContext = createContext(null);

export const TasksDispatchContext = createContext(null);
```

This file is about to get crowded! You’ll move the reducer into that same file. Then you’ll declare a new `TasksProvider` component in the same file. This component will tie all the pieces together:

1. It will manage the state with a reducer.
2. It will provide both contexts to components below.
3. It will [take `children` as a prop](/learn/passing-props-to-a-component#passing-jsx-as-children) so you can pass JSX to it.

```
export function TasksProvider({ children }) {

  const [tasks, dispatch] = useReducer(tasksReducer, initialTasks);



  return (

    <TasksContext value={tasks}>

      <TasksDispatchContext value={dispatch}>

        {children}

      </TasksDispatchContext>

    </TasksContext>

  );

}
```

**This removes all the complexity and wiring from your `TaskApp` component:**

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import AddTask from './AddTask.js';
import TaskList from './TaskList.js';
import { TasksProvider } from './TasksContext.js';

export default function TaskApp() {
  return (
    <TasksProvider>
      <h1>Day off in Kyoto</h1>
      <AddTask />
      <TaskList />
    </TasksProvider>
  );
}
```

You can also export functions that *use* the context from `TasksContext.js`:

```
export function useTasks() {

  return useContext(TasksContext);

}



export function useTasksDispatch() {

  return useContext(TasksDispatchContext);

}
```

When a component needs to read context, it can do it through these functions:

```
const tasks = useTasks();

const dispatch = useTasksDispatch();
```

This doesn’t change the behavior in any way, but it lets you later split these contexts further or add some logic to these functions. **Now all of the context and reducer wiring is in `TasksContext.js`. This keeps the components clean and uncluttered, focused on what they display rather than where they get the data:**

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';
import { useTasks, useTasksDispatch } from './TasksContext.js';

export default function TaskList() {
  const tasks = useTasks();
  return (
    <ul>
      {tasks.map(task => (
        <li key={task.id}>
          <Task task={task} />
        </li>
      ))}
    </ul>
  );
}

function Task({ task }) {
  const [isEditing, setIsEditing] = useState(false);
  const dispatch = useTasksDispatch();
  let taskContent;
  if (isEditing) {
    taskContent = (
      <>
        <input
          value={task.text}
          onChange={e => {
            dispatch({
              type: 'changed',
              task: {
                ...task,
                text: e.target.value
              }
            });
          }} />
        <button onClick={() => setIsEditing(false)}>
          Save
        </button>
      </>
    );
  } else {
    taskContent = (
      <>
        {task.text}
        <button onClick={() => setIsEditing(true)}>
          Edit
        </button>
      </>
    );
  }
  return (
    <label>
      <input
        type="checkbox"
        checked={task.done}
        onChange={e => {
          dispatch({
            type: 'changed',
            task: {
              ...task,
              done: e.target.checked
            }
          });
        }}
      />
      {taskContent}
      <button onClick={() => {
        dispatch({
          type: 'deleted',
          id: task.id
        });
      }}>
        Delete
      </button>
    </label>
  );
}
```

***

----
url: https://legacy.reactjs.org/blog/2014/02/15/community-roundup-16.html
----

February 15, 2014 by [Jonas Gebhardt](https://twitter.com/jonasgebhardt)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

There have been many posts recently covering the *why* and *how* of React. This week’s community round-up includes a collection of recent articles to help you get started with React, along with a few posts that explain some of the inner workings.

## [](#react-in-a-nutshell)React in a nutshell

Got five minutes to pitch React to your coworkers? John Lynch ([@johnrlynch](https://twitter.com/johnrlynch)) put together [this excellent and refreshing slideshow](http://slid.es/johnlynch/reactjs):

## [](#reacts-diff-algorithm)React’s diff algorithm

React core team member Christopher Chedeau ([@vjeux](https://twitter.com/vjeux)) explores the innards of React’s tree diffing algorithm in this [extensive and well-illustrated post](http://calendar.perfplanet.com/2013/diff/).

[](http://calendar.perfplanet.com/2013/diff/)

While we’re talking about tree diffing: Matt Esch ([@MatthewEsch](https://twitter.com/MatthewEsch)) created [this project](https://github.com/Matt-Esch/virtual-dom), which aims to implement the virtual DOM and a corresponding diff algorithm as separate modules.

## [](#many-many-new-introductions-to-react)Many, many new introductions to React!

James Padosley wrote a short post on the basics (and merits) of React: [What is React?](http://james.padolsey.com/javascript/what-is-react/)

> What I like most about React is that it doesn’t impose heady design patterns and data-modelling abstractions on me. \[…] Its opinions are so minimal and its abstractions so focused on the problem of the DOM, that you can merrily slap your design choices atop.
>
> [Read the full post…](http://james.padolsey.com/javascript/what-is-react/)

Taylor Lapeyre ([@taylorlapeyre](https://twitter.com/taylorlapeyre)) wrote another nice [introduction to React](http://words.taylorlapeyre.me/an-introduction-to-react).

> React expects you to do the work of getting and pushing data from the server. This makes it very easy to implement React as a front end solution, since it simply expects you to hand it data. React does all the other work.
>
> [Read the full post…](http://words.taylorlapeyre.me/an-introduction-to-react)

[This “Deep explanation for newbies”](http://www.webdesignporto.com/react-js-in-pure-javascript-facebook-library/?utm_source=echojs\&utm_medium=post\&utm_campaign=echojs) by [@ProJavaScript](https://twitter.com/ProJavaScript) explains how to get started building a React game without using the optional JSX syntax.

### [](#react-around-the-world)React around the world

It’s great to see the React community expand internationally. [This site](http://habrahabr.ru/post/189230/) features a React introduction in Russian.

### [](#react-tutorial-series)React tutorial series

[Christopher Pitt](https://medium.com/@followchrisp) explains [React Components](https://medium.com/react-tutorials/828c397e3dc8) and [React Properties](https://medium.com/react-tutorials/ef11cd55caa0). The former includes a nice introduction to using JSX, while the latter focuses on adding interactivity and linking multiple components together. Also check out the [other posts in his React Tutorial series](https://medium.com/react-tutorials), e.g. on using [React + Backbone Model](https://medium.com/react-tutorials/8aaec65a546c) and [React + Backbone Router](https://medium.com/react-tutorials/c00be0cf1592).

### [](#beginner-tutorial-implementing-the-board-game-go)Beginner tutorial: Implementing the board game Go

[Chris LaRose](http://cjlarose.com/) walks through the steps of creating a Go app in React, showing how to separate application logic from the rendered components. Check out his [tutorial](http://cjlarose.com/2014/01/09/react-board-game-tutorial.html) or go straight to the [code](https://github.com/cjlarose/react-go).

### [](#eggheadio-video-tutorials)Egghead.io video tutorials

Joe Maddalone ([@joemaddalone](https://twitter.com/joemaddalone)) of [egghead.io](https://egghead.io/) created a series of React video tutorials, such as [this](http://www.youtube-nocookie.com/v/rFvZydtmsxM) introduction to React Components. \[[part 1](http://www.youtube-nocookie.com/v/rFvZydtmsxM)], \[[part 2](http://www.youtube-nocookie.com/v/5yvFLrt7N8M)]

### [](#react-finally-a-great-serverclient-web-stack)“React: Finally, a great server/client web stack”

Eric Florenzano ([@ericflo](https://twitter.com/ericflo)) sheds some light on what makes React perfect for server rendering:

> \[…] the ideal solution would fully render the markup on the server, deliver it to the client so that it can be shown to the user instantly. Then it would asynchronously load some JavaScript that would attach to the rendered markup, and invisibly promote the page into a full app that can render its own markup. \[…]

> What I’ve discovered is that enough of the pieces have come together, that this futuristic-sounding web environment is actually surprisingly easy to do now with React.js.

> [Read the full post…](http://eflorenzano.com/blog/2014/01/23/react-finally-server-client/)

## [](#building-a-complex-react-component)Building a complex React component

[Matt Harrison](http://matt-harrison.com/) walks through the process of [creating an SVG-based Resistance Calculator](http://matt-harrison.com/building-a-complex-web-component-with-facebooks-react-library/) using React.

[](http://matt-harrison.com/building-a-complex-web-component-with-facebooks-react-library/)

## [](#random-tweets)Random Tweets

> \[#reactjs]\(https\://twitter.com/search?q=%23reactjs\&src=hash) has very simple API, but it's amazing how much work has been done under the hood to make it blazing fast.
>
> — Anton Astashov (@anton\_astashov) [December 30, 2013](https://twitter.com/anton_astashov/status/417556491646693378)

> \[#reactjs]\((https\://twitter.com/search?q=%23reactjs\&src=hash) makes refactoring your HTML as easy & natural as refactoring your javascript \[@react\_js]\(https\://twitter.com/react\_js)
>
> — Jared Forsyth (@jaredforsyth) [January 6, 2014](https://twitter.com/jaredforsyth/status/420304083010854912)

> Played with react.js for an hour, so many things suddenly became stupidly simple.
>
> — andrewingram (@andrewingram) [January 13, 2014](https://twitter.com/andrewingram/status/422810480701620225)

> \[@okonetchnikov]\(https\://twitter.com/okonetchnikov) HOLY CRAP react is nice
>
> — julik (@julikt) [January 13, 2014](https://twitter.com/julikt/status/422843478792765440)

> brb rewriting everything with react
>
> — Ben Smithett (@bensmithett) [February 4, 2014](https://twitter.com/bensmithett/status/430671242186592256)

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2014-02-15-community-roundup-16.md)

----
url: https://legacy.reactjs.org/blog/2013/07/23/community-roundup-5.html
----

July 23, 2013 by [Vjeux](https://twitter.com/vjeux)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

We launched the [React Facebook Page](https://www.facebook.com/react) along with the React v0.4 launch. 700 people already liked it to get updated on the project :)

## [](#cross-browser-onchange)Cross-browser onChange

[Sophie Alpert](http://sophiebits.com/) from [Khan Academy](https://www.khanacademy.org/) worked on a cross-browser implementation of `onChange` event that landed in v0.4. She wrote a blog post explaining the various browser quirks she had to deal with.

> First off, what is the input event? If you have an `<input>` element and want to receive events whenever the value changes, the most obvious thing to do is to listen to the change event. Unfortunately, change fires only after the text field is defocused, rather than on each keystroke. The next obvious choice is the keyup event, which is triggered whenever a key is released. Unfortunately, keyup doesn’t catch input that doesn’t involve the keyboard (e.g., pasting from the clipboard using the mouse) and only fires once if a key is held down, rather than once per inserted character.
>
> Both keydown and keypress do fire repeatedly when a key is held down, but both fire immediately before the value changes, so to read the new value you have to defer the handler to the next event loop using `setTimeout(fn, 0)` or similar, which slows down your app. Of course, like keyup, neither keydown nor keypress fires for non-keyboard input events, and all three can fire in cases where the value doesn’t change at all (such as when pressing the arrow keys).
>
> [Read the full post…](http://sophiebits.com/2013/06/18/a-near-perfect-oninput-shim-for-ie-8-and-9.html)

## [](#react-samples)React Samples

Learning a new library is always easier when you have working examples you can play with. [jwh](https://github.com/jhw) put many of them on his [react-samples GitHub repo](https://github.com/jhw/react-samples).

> Some simple examples with Facebook’s React framework
>
> * Bootstrap action bar, modal and table [#1](https://rawgithub.com/jhw/react-samples/master/html/actionbar.html), [#2](https://rawgithub.com/jhw/react-samples/master/html/bootstrap_actionbar.html), [#3](https://rawgithub.com/jhw/react-samples/master/html/bootstrap_modal.html), [#4](https://rawgithub.com/jhw/react-samples/master/html/bootstrap_striped_table.html)
> * Comments [#1](https://rawgithub.com/jhw/react-samples/master/html/comments1.html), [#2](https://rawgithub.com/jhw/react-samples/master/html/comments2.html)
> * Data Table [#1](https://rawgithub.com/jhw/react-samples/master/html/datatable.html), [#2](https://rawgithub.com/jhw/react-samples/master/html/datatable2.html), [#3](https://rawgithub.com/jhw/react-samples/master/html/datatable3.html), [#4](https://rawgithub.com/jhw/react-samples/master/html/datatable4.html), [#5](https://rawgithub.com/jhw/react-samples/master/html/datatable5.html)
> * Filter Bar [#1](https://rawgithub.com/jhw/react-samples/master/html/filterbar.html), [#2](https://rawgithub.com/jhw/react-samples/master/html/filterbar2.html), [#3](https://rawgithub.com/jhw/react-samples/master/html/filterbar3.html), [#4](https://rawgithub.com/jhw/react-samples/master/html/filterbar4.html), [#5](https://rawgithub.com/jhw/react-samples/master/html/filterbar5.html)
> * Fundoo Rating [#1](https://rawgithub.com/jhw/react-samples/master/html/fundoo.html)
> * Line Char: [#1](https://rawgithub.com/jhw/react-samples/master/html/linechart.html), [#2](https://rawgithub.com/jhw/react-samples/master/html/linechart2.html)
> * Multi tabs [#1](https://rawgithub.com/jhw/react-samples/master/html/multitabs.html)
> * Select [#1](https://rawgithub.com/jhw/react-samples/master/html/select.html)
> * Simple Tabs [#1](https://rawgithub.com/jhw/react-samples/master/html/simpletabs.html), [#2](https://rawgithub.com/jhw/react-samples/master/html/simpletabs2.html), [#3](https://rawgithub.com/jhw/react-samples/master/html/simpletabs3.html), [#4](https://rawgithub.com/jhw/react-samples/master/html/simpletabs4.html)
> * Toggle [#1](https://rawgithub.com/jhw/react-samples/master/html/toggle.html)

## [](#react-chosen-wrapper)React Chosen Wrapper

[Cheng Lou](https://github.com/chenglou) wrote a wrapper for the [Chosen](https://harvesthq.github.io/chosen/) input library called [react-chosen](https://github.com/chenglou/react-chosen). It took just 25 lines to be able to use jQuery component as a React one.

```
React.renderComponent(
  <Chosen noResultsText="No result" value="Harvest" onChange={doSomething}>
    <option value="Facebook">Facebook</option>
    <option value="Harvest">Harvest</option>
  </Chosen>
, document.getElementById('example'));
```

## [](#jsx-and-es6-template-strings)JSX and ES6 Template Strings

[Domenic Denicola](http://domenicdenicola.com/) wrote a slide deck about the great applications of ES6 features and one slide shows how we could use Template Strings to compile JSX at run-time without the need for a pre-processing phase.

## [](#react-presentation)React Presentation

[Tom Occhino](http://tomocchino.com/) and [Jordan Walke](https://github.com/jordwalke), React developers, did a presentation of React at Facebook Seattle’s office. Check out the first 25 minutes for the presentation and the remaining 45 for a Q\&A. I highly recommend you watching this video.

## [](#docs)Docs

[Pete Hunt](http://www.petehunt.net/) rewrote the entirety of the docs for v0.4. The goal was to add more explanation about why we built React and what the best practices are.

> Guides
>
> * [Why React?](/docs/why-react.html)
>
> * [Displaying Data](/docs/displaying-data.html)
>
>   * [JSX in Depth](/docs/jsx-in-depth.html)
>   * [JSX Gotchas](/docs/jsx-gotchas.html)
>
> * [Interactivity and Dynamic UIs](/docs/interactivity-and-dynamic-uis.html)
>
> * [Multiple Components](/docs/multiple-components.html)
>
> * [Reusable Components](/docs/reusable-components.html)
>
> * [Forms](/docs/forms.html)
>
> * [Working With the Browser](/docs/working-with-the-browser.html)
>
>   * [More About Refs](/docs/more-about-refs.html)
>
> * [Tooling integration](/docs/tooling-integration.html)
>
> * [Reference](/docs/top-level-api.html)

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2013-07-23-community-roundup-5.md)

----
url: https://react.dev/reference/react-compiler/logger
----

[API Reference](/reference/react)

[Configuration](/reference/react-compiler/configuration)

# logger[](#undefined "Link for this heading")

The `logger` option provides custom logging for React Compiler events during compilation.

```
{

  logger: {

    logEvent(filename, event) {

      console.log(`[Compiler] ${event.kind}: ${filename}`);

    }

  }

}
```

* [Reference](#reference)
  * [`logger`](#logger)

* [Usage](#usage)

  * [Basic logging](#basic-logging)
  * [Detailed error logging](#detailed-error-logging)

***

## Reference[](#reference "Link for Reference ")

### `logger`[](#logger "Link for this heading")

Configures custom logging to track compiler behavior and debug issues.

#### Type[](#type "Link for Type ")

```
{

  logEvent: (filename: string | null, event: LoggerEvent) => void;

} | null
```

#### Default value[](#default-value "Link for Default value ")

`null`

#### Methods[](#methods "Link for Methods ")

* **`logEvent`**: Called for each compiler event with the filename and event details

#### Event types[](#event-types "Link for Event types ")

* **`CompileSuccess`**: Function successfully compiled
* **`CompileError`**: Function skipped due to errors
* **`CompileDiagnostic`**: Non-fatal diagnostic information
* **`CompileSkip`**: Function skipped for other reasons
* **`PipelineError`**: Unexpected compilation error
* **`Timing`**: Performance timing information

#### Caveats[](#caveats "Link for Caveats ")

* Event structure may change between versions
* Large codebases generate many log entries

***

## Usage[](#usage "Link for Usage ")

### Basic logging[](#basic-logging "Link for Basic logging ")

Track compilation success and failures:

```
{

  logger: {

    logEvent(filename, event) {

      switch (event.kind) {

        case 'CompileSuccess': {

          console.log(`✅ Compiled: ${filename}`);

          break;

        }

        case 'CompileError': {

          console.log(`❌ Skipped: ${filename}`);

          break;

        }

        default: {}

      }

    }

  }

}
```

### Detailed error logging[](#detailed-error-logging "Link for Detailed error logging ")

Get specific information about compilation failures:

```
{

  logger: {

    logEvent(filename, event) {

      if (event.kind === 'CompileError') {

        console.error(`\nCompilation failed: ${filename}`);

        console.error(`Reason: ${event.detail.reason}`);



        if (event.detail.description) {

          console.error(`Details: ${event.detail.description}`);

        }



        if (event.detail.loc) {

          const { line, column } = event.detail.loc.start;

          console.error(`Location: Line ${line}, Column ${column}`);

        }



        if (event.detail.suggestions) {

          console.error('Suggestions:', event.detail.suggestions);

        }

      }

    }

  }

}
```

[Previousgating](/reference/react-compiler/gating)

[NextpanicThreshold](/reference/react-compiler/panicThreshold)

***

----
url: https://react.dev/reference/eslint-plugin-react-hooks/lints/set-state-in-render
----

[API Reference](/reference/react)

[Lints](/reference/eslint-plugin-react-hooks)

# set-state-in-render[](#undefined "Link for this heading")

Validates against unconditionally setting state during render, which can trigger additional renders and potential infinite render loops.

## Rule Details[](#rule-details "Link for Rule Details ")

Calling `setState` during render unconditionally triggers another render before the current one finishes. This creates an infinite loop that crashes your app.

## Common Violations[](#common-violations "Link for Common Violations ")

### Invalid[](#invalid "Link for Invalid ")

```
// ❌ Unconditional setState directly in render

function Component({value}) {

  const [count, setCount] = useState(0);

  setCount(value); // Infinite loop!

  return <div>{count}</div>;

}
```

### Valid[](#valid "Link for Valid ")

```
// ✅ Derive during render

function Component({items}) {

  const sorted = [...items].sort(); // Just calculate it in render

  return <ul>{sorted.map(/*...*/)}</ul>;

}



// ✅ Set state in event handler

function Component() {

  const [count, setCount] = useState(0);

  return (

    <button onClick={() => setCount(count + 1)}>

      {count}

    </button>

  );

}



// ✅ Derive from props instead of setting state

function Component({user}) {

  const name = user?.name || '';

  const email = user?.email || '';

  return <div>{name}</div>;

}



// ✅ Conditionally derive state from props and state from previous renders

function Component({ items }) {

  const [isReverse, setIsReverse] = useState(false);

  const [selection, setSelection] = useState(null);



  const [prevItems, setPrevItems] = useState(items);

  if (items !== prevItems) { // This condition makes it valid

    setPrevItems(items);

    setSelection(null);

  }

  // ...

}
```

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### I want to sync state to a prop[](#clamp-state-to-prop "Link for I want to sync state to a prop ")

A common problem is trying to “fix” state after it renders. Suppose you want to keep a counter from exceeding a `max` prop:

```
// ❌ Wrong: clamps during render

function Counter({max}) {

  const [count, setCount] = useState(0);



  if (count > max) {

    setCount(max);

  }



  return (

    <button onClick={() => setCount(count + 1)}>

      {count}

    </button>

  );

}
```

As soon as `count` exceeds `max`, an infinite loop is triggered.

Instead, it’s often better to move this logic to the event (the place where the state is first set). For example, you can enforce the maximum at the moment you update state:

```
// ✅ Clamp when updating

function Counter({max}) {

  const [count, setCount] = useState(0);



  const increment = () => {

    setCount(current => Math.min(current + 1, max));

  };



  return <button onClick={increment}>{count}</button>;

}
```

Now the setter only runs in response to the click, React finishes the render normally, and `count` never crosses `max`.

In rare cases, you may need to adjust state based on information from previous renders. For those, follow [this pattern](https://react.dev/reference/react/useState#storing-information-from-previous-renders) of setting state conditionally.

[Previousset-state-in-effect](/reference/eslint-plugin-react-hooks/lints/set-state-in-effect)

[Nextstatic-components](/reference/eslint-plugin-react-hooks/lints/static-components)

***

----
url: https://18.react.dev/reference/react-dom/unmountComponentAtNode
----

```
unmountComponentAtNode(domNode)
```

* [Reference](#reference)
  * [`unmountComponentAtNode(domNode)`](#unmountcomponentatnode)
* [Usage](#usage)
  * [Removing a React app from a DOM element](#removing-a-react-app-from-a-dom-element)

***

## Reference[](#reference "Link for Reference ")

### `unmountComponentAtNode(domNode)`[](#unmountcomponentatnode "Link for this heading")

Call `unmountComponentAtNode` to remove a mounted React component from the DOM and clean up its event handlers and state.

```
import { unmountComponentAtNode } from 'react-dom';



const domNode = document.getElementById('root');

render(<App />, domNode);



unmountComponentAtNode(domNode);
```

[See more examples below.](#usage)

#### Parameters[](#parameters "Link for Parameters ")

* `domNode`: A [DOM element.](https://developer.mozilla.org/en-US/docs/Web/API/Element) React will remove a mounted React component from this element.

#### Returns[](#returns "Link for Returns ")

`unmountComponentAtNode` returns `true` if a component was unmounted and `false` otherwise.

***

## Usage[](#usage "Link for Usage ")

Call `unmountComponentAtNode` to remove a mounted React component from a browser DOM node and clean up its event handlers and state.

```
import { render, unmountComponentAtNode } from 'react-dom';

import App from './App.js';



const rootNode = document.getElementById('root');

render(<App />, rootNode);



// ...

unmountComponentAtNode(rootNode);
```

### Removing a React app from a DOM element[](#removing-a-react-app-from-a-dom-element "Link for Removing a React app from a DOM element ")

Occasionally, you may want to “sprinkle” React on an existing page, or a page that is not fully written in React. In those cases, you may need to “stop” the React app, by removing all of the UI, state, and listeners from the DOM node it was rendered to.

In this example, clicking “Render React App” will render a React app. Click “Unmount React App” to destroy it:

```
import './styles.css';
import { render, unmountComponentAtNode } from 'react-dom';
import App from './App.js';

const domNode = document.getElementById('root');

document.getElementById('render').addEventListener('click', () => {
  render(<App />, domNode);
});

document.getElementById('unmount').addEventListener('click', () => {
  unmountComponentAtNode(domNode);
});
```

[Previousrender](/reference/react-dom/render)

[NextClient APIs](/reference/react-dom/client)

***

----
url: https://18.react.dev/reference/react/createElement
----

[API Reference](/reference/react)

[Legacy React APIs](/reference/react/legacy)

# createElement[](#undefined "Link for this heading")

`createElement` lets you create a React element. It serves as an alternative to writing [JSX.](/learn/writing-markup-with-jsx)

```
const element = createElement(type, props, ...children)
```

* [Reference](#reference)
  * [`createElement(type, props, ...children)`](#createelement)
* [Usage](#usage)
  * [Creating an element without JSX](#creating-an-element-without-jsx)

***

## Reference[](#reference "Link for Reference ")

### `createElement(type, props, ...children)`[](#createelement "Link for this heading")

Call `createElement` to create a React element with the given `type`, `props`, and `children`.

```
import { createElement } from 'react';



function Greeting({ name }) {

  return createElement(

    'h1',

    { className: 'greeting' },

    'Hello'

  );

}
```

* `props`: The `props` you have passed except for `ref` and `key`. If the `type` is a component with legacy `type.defaultProps`, then any missing or undefined `props` will get the values from `type.defaultProps`.

***

## Usage[](#usage "Link for Usage ")

### Creating an element without JSX[](#creating-an-element-without-jsx "Link for Creating an element without JSX ")

If you don’t like [JSX](/learn/writing-markup-with-jsx) or can’t use it in your project, you can use `createElement` as an alternative.

To create an element without JSX, call `createElement` with some type, props, and children:

```
import { createElement } from 'react';



function Greeting({ name }) {

  return createElement(

    'h1',

    { className: 'greeting' },

    'Hello ',

    createElement('i', null, name),

    '. Welcome!'

  );

}
```

The children are optional, and you can pass as many as you need (the example above has three children). This code will display a `<h1>` header with a greeting. For comparison, here is the same example rewritten with JSX:

```
function Greeting({ name }) {

  return (

    <h1 className="greeting">

      Hello <i>{name}</i>. Welcome!

    </h1>

  );

}
```

To render your own React component, pass a function like `Greeting` as the type instead of a string like `'h1'`:

```
export default function App() {

  return createElement(Greeting, { name: 'Taylor' });

}
```

With JSX, it would look like this:

```
export default function App() {

  return <Greeting name="Taylor" />;

}
```

Here is a complete example written with `createElement`:

```
import { createElement } from 'react';

function Greeting({ name }) {
  return createElement(
    'h1',
    { className: 'greeting' },
    'Hello ',
    createElement('i', null, name),
    '. Welcome!'
  );
}

export default function App() {
  return createElement(
    Greeting,
    { name: 'Taylor' }
  );
}
```

And here is the same example written using JSX:

```
function Greeting({ name }) {
  return (
    <h1 className="greeting">
      Hello <i>{name}</i>. Welcome!
    </h1>
  );
}

export default function App() {
  return <Greeting name="Taylor" />;
}
```

Both coding styles are fine, so you can use whichever one you prefer for your project. The main benefit of using JSX compared to `createElement` is that it’s easy to see which closing tag corresponds to which opening tag.

##### Deep Dive#### What is a React element, exactly?[](#what-is-a-react-element-exactly "Link for What is a React element, exactly? ")

An element is a lightweight description of a piece of the user interface. For example, both `<Greeting name="Taylor" />` and `createElement(Greeting, { name: 'Taylor' })` produce an object like this:

```
// Slightly simplified

{

  type: Greeting,

  props: {

    name: 'Taylor'

  },

  key: null,

  ref: null,

}
```

**Note that creating this object does not render the `Greeting` component or create any DOM elements.**

A React element is more like a description—an instruction for React to later render the `Greeting` component. By returning this object from your `App` component, you tell React what to do next.

Creating elements is extremely cheap so you don’t need to try to optimize or avoid it.

[PreviousComponent](/reference/react/Component)

[NextcreateFactory](/reference/react/createFactory)

***

----
url: https://18.react.dev/learn
----

[Learn React](/learn)

# Quick Start[](#undefined "Link for this heading")

Welcome to the React documentation! This page will give you an introduction to the 80% of React concepts that you will use on a daily basis.

```
function MyButton() {

  return (

    <button>I'm a button</button>

  );

}
```

Now that you’ve declared `MyButton`, you can nest it into another component:

```
export default function MyApp() {

  return (

    <div>

      <h1>Welcome to my app</h1>

      <MyButton />

    </div>

  );

}
```

Notice that `<MyButton />` starts with a capital letter. That’s how you know it’s a React component. React component names must always start with a capital letter, while HTML tags must be lowercase.

Have a look at the result:

```
function MyButton() {
  return (
    <button>
      I'm a button
    </button>
  );
}

export default function MyApp() {
  return (
    <div>
      <h1>Welcome to my app</h1>
      <MyButton />
    </div>
  );
}
```

The `export default` keywords specify the main component in the file. If you’re not familiar with some piece of JavaScript syntax, [MDN](https://developer.mozilla.org/en-US/docs/web/javascript/reference/statements/export) and [javascript.info](https://javascript.info/import-export) have great references.

## Writing markup with JSX[](#writing-markup-with-jsx "Link for Writing markup with JSX ")

The markup syntax you’ve seen above is called *JSX*. It is optional, but most React projects use JSX for its convenience. All of the [tools we recommend for local development](/learn/installation) support JSX out of the box.

JSX is stricter than HTML. You have to close tags like `<br />`. Your component also can’t return multiple JSX tags. You have to wrap them into a shared parent, like a `<div>...</div>` or an empty `<>...</>` wrapper:

```
function AboutPage() {

  return (

    <>

      <h1>About</h1>

      <p>Hello there.<br />How do you do?</p>

    </>

  );

}
```

If you have a lot of HTML to port to JSX, you can use an [online converter.](https://transform.tools/html-to-jsx)

## Adding styles[](#adding-styles "Link for Adding styles ")

In React, you specify a CSS class with `className`. It works the same way as the HTML [`class`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/class) attribute:

```
<img className="avatar" />
```

Then you write the CSS rules for it in a separate CSS file:

```
/* In your CSS */

.avatar {

  border-radius: 50%;

}
```

React does not prescribe how you add CSS files. In the simplest case, you’ll add a [`<link>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link) tag to your HTML. If you use a build tool or a framework, consult its documentation to learn how to add a CSS file to your project.

## Displaying data[](#displaying-data "Link for Displaying data ")

JSX lets you put markup into JavaScript. Curly braces let you “escape back” into JavaScript so that you can embed some variable from your code and display it to the user. For example, this will display `user.name`:

```
return (

  <h1>

    {user.name}

  </h1>

);
```

You can also “escape into JavaScript” from JSX attributes, but you have to use curly braces *instead of* quotes. For example, `className="avatar"` passes the `"avatar"` string as the CSS class, but `src={user.imageUrl}` reads the JavaScript `user.imageUrl` variable value, and then passes that value as the `src` attribute:

```
return (

  <img

    className="avatar"

    src={user.imageUrl}

  />

);
```

You can put more complex expressions inside the JSX curly braces too, for example, [string concatenation](https://javascript.info/operators#string-concatenation-with-binary):

```
const user = {
  name: 'Hedy Lamarr',
  imageUrl: 'https://i.imgur.com/yXOvdOSs.jpg',
  imageSize: 90,
};

export default function Profile() {
  return (
    <>
      <h1>{user.name}</h1>
      <img
        className="avatar"
        src={user.imageUrl}
        alt={'Photo of ' + user.name}
        style={{
          width: user.imageSize,
          height: user.imageSize
        }}
      />
    </>
  );
}
```

In the above example, `style={{}}` is not a special syntax, but a regular `{}` object inside the `style={ }` JSX curly braces. You can use the `style` attribute when your styles depend on JavaScript variables.

## Conditional rendering[](#conditional-rendering "Link for Conditional rendering ")

In React, there is no special syntax for writing conditions. Instead, you’ll use the same techniques as you use when writing regular JavaScript code. For example, you can use an [`if`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/if...else) statement to conditionally include JSX:

```
let content;

if (isLoggedIn) {

  content = <AdminPanel />;

} else {

  content = <LoginForm />;

}

return (

  <div>

    {content}

  </div>

);
```

If you prefer more compact code, you can use the [conditional `?` operator.](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator) Unlike `if`, it works inside JSX:

```
<div>

  {isLoggedIn ? (

    <AdminPanel />

  ) : (

    <LoginForm />

  )}

</div>
```

When you don’t need the `else` branch, you can also use a shorter [logical `&&` syntax](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_AND#short-circuit_evaluation):

```
<div>

  {isLoggedIn && <AdminPanel />}

</div>
```

All of these approaches also work for conditionally specifying attributes. If you’re unfamiliar with some of this JavaScript syntax, you can start by always using `if...else`.

## Rendering lists[](#rendering-lists "Link for Rendering lists ")

You will rely on JavaScript features like [`for` loop](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for) and the [array `map()` function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) to render lists of components.

For example, let’s say you have an array of products:

```
const products = [

  { title: 'Cabbage', id: 1 },

  { title: 'Garlic', id: 2 },

  { title: 'Apple', id: 3 },

];
```

Inside your component, use the `map()` function to transform an array of products into an array of `<li>` items:

```
const listItems = products.map(product =>

  <li key={product.id}>

    {product.title}

  </li>

);



return (

  <ul>{listItems}</ul>

);
```

Notice how `<li>` has a `key` attribute. For each item in a list, you should pass a string or a number that uniquely identifies that item among its siblings. Usually, a key should be coming from your data, such as a database ID. React uses your keys to know what happened if you later insert, delete, or reorder the items.

```
const products = [
  { title: 'Cabbage', isFruit: false, id: 1 },
  { title: 'Garlic', isFruit: false, id: 2 },
  { title: 'Apple', isFruit: true, id: 3 },
];

export default function ShoppingList() {
  const listItems = products.map(product =>
    <li
      key={product.id}
      style={{
        color: product.isFruit ? 'magenta' : 'darkgreen'
      }}
    >
      {product.title}
    </li>
  );

  return (
    <ul>{listItems}</ul>
  );
}
```

## Responding to events[](#responding-to-events "Link for Responding to events ")

You can respond to events by declaring *event handler* functions inside your components:

```
function MyButton() {

  function handleClick() {

    alert('You clicked me!');

  }



  return (

    <button onClick={handleClick}>

      Click me

    </button>

  );

}
```

Notice how `onClick={handleClick}` has no parentheses at the end! Do not *call* the event handler function: you only need to *pass it down*. React will call your event handler when the user clicks the button.

## Updating the screen[](#updating-the-screen "Link for Updating the screen ")

Often, you’ll want your component to “remember” some information and display it. For example, maybe you want to count the number of times a button is clicked. To do this, add *state* to your component.

First, import [`useState`](/reference/react/useState) from React:

```
import { useState } from 'react';
```

Now you can declare a *state variable* inside your component:

```
function MyButton() {

  const [count, setCount] = useState(0);

  // ...
```

You’ll get two things from `useState`: the current state (`count`), and the function that lets you update it (`setCount`). You can give them any names, but the convention is to write `[something, setSomething]`.

The first time the button is displayed, `count` will be `0` because you passed `0` to `useState()`. When you want to change state, call `setCount()` and pass the new value to it. Clicking this button will increment the counter:

```
function MyButton() {

  const [count, setCount] = useState(0);



  function handleClick() {

    setCount(count + 1);

  }



  return (

    <button onClick={handleClick}>

      Clicked {count} times

    </button>

  );

}
```

React will call your component function again. This time, `count` will be `1`. Then it will be `2`. And so on.

If you render the same component multiple times, each will get its own state. Click each button separately:

```
import { useState } from 'react';

export default function MyApp() {
  return (
    <div>
      <h1>Counters that update separately</h1>
      <MyButton />
      <MyButton />
    </div>
  );
}

function MyButton() {
  const [count, setCount] = useState(0);

  function handleClick() {
    setCount(count + 1);
  }

  return (
    <button onClick={handleClick}>
      Clicked {count} times
    </button>
  );
}
```

```
export default function MyApp() {

  const [count, setCount] = useState(0);



  function handleClick() {

    setCount(count + 1);

  }



  return (

    <div>

      <h1>Counters that update separately</h1>

      <MyButton />

      <MyButton />

    </div>

  );

}



function MyButton() {

  // ... we're moving code from here ...

}
```

Then, *pass the state down* from `MyApp` to each `MyButton`, together with the shared click handler. You can pass information to `MyButton` using the JSX curly braces, just like you previously did with built-in tags like `<img>`:

```
export default function MyApp() {

  const [count, setCount] = useState(0);



  function handleClick() {

    setCount(count + 1);

  }



  return (

    <div>

      <h1>Counters that update together</h1>

      <MyButton count={count} onClick={handleClick} />

      <MyButton count={count} onClick={handleClick} />

    </div>

  );

}
```

The information you pass down like this is called *props*. Now the `MyApp` component contains the `count` state and the `handleClick` event handler, and *passes both of them down as props* to each of the buttons.

Finally, change `MyButton` to *read* the props you have passed from its parent component:

```
function MyButton({ count, onClick }) {

  return (

    <button onClick={onClick}>

      Clicked {count} times

    </button>

  );

}
```

When you click the button, the `onClick` handler fires. Each button’s `onClick` prop was set to the `handleClick` function inside `MyApp`, so the code inside of it runs. That code calls `setCount(count + 1)`, incrementing the `count` state variable. The new `count` value is passed as a prop to each button, so they all show the new value. This is called “lifting state up”. By moving state up, you’ve shared it between components.

```
import { useState } from 'react';

export default function MyApp() {
  const [count, setCount] = useState(0);

  function handleClick() {
    setCount(count + 1);
  }

  return (
    <div>
      <h1>Counters that update together</h1>
      <MyButton count={count} onClick={handleClick} />
      <MyButton count={count} onClick={handleClick} />
    </div>
  );
}

function MyButton({ count, onClick }) {
  return (
    <button onClick={onClick}>
      Clicked {count} times
    </button>
  );
}
```

## Next Steps[](#next-steps "Link for Next Steps ")

By now, you know the basics of how to write React code!

Check out the [Tutorial](/learn/tutorial-tic-tac-toe) to put them into practice and build your first mini-app with React.

[NextTutorial: Tic-Tac-Toe](/learn/tutorial-tic-tac-toe)

***

----
url: https://18.react.dev/community/acknowledgements
----

* [Sean Keegan](https://github.com/seanryankeegan)
* [Sophia Shoemaker](https://github.com/mrscobbler)
* [Sunil Pai](https://github.com/threepointone)

***

----
url: https://legacy.reactjs.org/docs/error-decoder.html
----

In the minified production build of React, we avoid sending down full error messages in order to reduce the number of bytes sent over the wire.

We highly recommend using the development build locally when debugging your app since it tracks additional debug info and provides helpful warnings about potential problems in your apps, but if you encounter an exception while using the production build, this page will reassemble the original text of the error.

When you encounter an error, you'll receive a link to this page for that specific error and we'll show you the full error text.

----
url: https://react.dev/reference/react-dom
----

[API Reference](/reference/react)

# React DOM APIs[](#undefined "Link for this heading")

The `react-dom` package contains methods that are only supported for the web applications (which run in the browser DOM environment). They are not supported for React Native.

***

## APIs[](#apis "Link for APIs ")

These APIs can be imported from your components. They are rarely used:

* [`createPortal`](/reference/react-dom/createPortal) lets you render child components in a different part of the DOM tree.
* [`flushSync`](/reference/react-dom/flushSync) lets you force React to flush a state update and update the DOM synchronously.

## Resource Preloading APIs[](#resource-preloading-apis "Link for Resource Preloading APIs ")

These APIs can be used to make apps faster by pre-loading resources such as scripts, stylesheets, and fonts as soon as you know you need them, for example before navigating to another page where the resources will be used.

[React-based frameworks](/learn/creating-a-react-app) frequently handle resource loading for you, so you might not have to call these APIs yourself. Consult your framework’s documentation for details.

* [`prefetchDNS`](/reference/react-dom/prefetchDNS) lets you prefetch the IP address of a DNS domain name that you expect to connect to.
* [`preconnect`](/reference/react-dom/preconnect) lets you connect to a server you expect to request resources from, even if you don’t know what resources you’ll need yet.
* [`preload`](/reference/react-dom/preload) lets you fetch a stylesheet, font, image, or external script that you expect to use.
* [`preloadModule`](/reference/react-dom/preloadModule) lets you fetch an ESM module that you expect to use.
* [`preinit`](/reference/react-dom/preinit) lets you fetch and evaluate an external script or fetch and insert a stylesheet.
* [`preinitModule`](/reference/react-dom/preinitModule) lets you fetch and evaluate an ESM module.

***

## Entry points[](#entry-points "Link for Entry points ")

The `react-dom` package provides two additional entry points:

* [`react-dom/client`](/reference/react-dom/client) contains APIs to render React components on the client (in the browser).
* [`react-dom/server`](/reference/react-dom/server) contains APIs to render React components on the server.

***

## Removed APIs[](#removed-apis "Link for Removed APIs ")

These APIs were removed in React 19:

* [`findDOMNode`](https://18.react.dev/reference/react-dom/findDOMNode): see [alternatives](https://18.react.dev/reference/react-dom/findDOMNode#alternatives).
* [`hydrate`](https://18.react.dev/reference/react-dom/hydrate): use [`hydrateRoot`](/reference/react-dom/client/hydrateRoot) instead.
* [`render`](https://18.react.dev/reference/react-dom/render): use [`createRoot`](/reference/react-dom/client/createRoot) instead.
* [`unmountComponentAtNode`](/reference/react-dom/unmountComponentAtNode): use [`root.unmount()`](/reference/react-dom/client/createRoot#root-unmount) instead.
* [`renderToNodeStream`](https://18.react.dev/reference/react-dom/server/renderToNodeStream): use [`react-dom/server`](/reference/react-dom/server) APIs instead.
* [`renderToStaticNodeStream`](https://18.react.dev/reference/react-dom/server/renderToStaticNodeStream): use [`react-dom/server`](/reference/react-dom/server) APIs instead.

[Previous\<title>](/reference/react-dom/components/title)

[NextcreatePortal](/reference/react-dom/createPortal)

***

----
url: https://legacy.reactjs.org/blog/all.html
----

# All Posts

* ## [React Labs: What We've Been Working On – June 2022](/blog/2022/06/15/react-labs-what-we-have-been-working-on-june-2022.html)

  June 15, 2022

  by Andrew Clark, Dan Abramov, Jan Kassens, Joseph Savona, Josh Story, Lauren Tan, Luna Ruan, Mengdi Chen, Rick Hanlon, Robert Zhang, Sathya Gunasekaran, Sebastian Markbåge, and Xuan Huang

* ## [React v18.0](/blog/2022/03/29/react-v18.html)

  March 29, 2022

  by The React Team

* ## [How to Upgrade to React 18](/blog/2022/03/08/react-18-upgrade-guide.html)

  March 08, 2022

  by Rick Hanlon

* ## [React Conf 2021 Recap](/blog/2021/12/17/react-conf-2021-recap.html)

  December 17, 2021

  by Jesslyn Tannady and Rick Hanlon

* ## [The Plan for React 18](/blog/2021/06/08/the-plan-for-react-18.html)

  June 08, 2021

  by Andrew Clark, Brian Vaughn, Christine Abernathy, Dan Abramov, Rachel Nabors, Rick Hanlon, Sebastian Markbåge, and Seth Webster

* ## [Introducing Zero-Bundle-Size React Server Components](/blog/2020/12/21/data-fetching-with-react-server-components.html)

  December 21, 2020

  by Dan Abramov, Lauren Tan, Joseph Savona, and Sebastian Markbåge

* ## [React v17.0](/blog/2020/10/20/react-v17.html)

  October 20, 2020

  by Dan Abramov and Rachel Nabors

* ## [Introducing the New JSX Transform](/blog/2020/09/22/introducing-the-new-jsx-transform.html)

  September 22, 2020

  by Luna Ruan

* ## [React v17.0 Release Candidate: No New Features](/blog/2020/08/10/react-v17-rc.html)

  August 10, 2020

  by Dan Abramov and Rachel Nabors

* ## [React v16.13.0](/blog/2020/02/26/react-v16.13.0.html)

  February 26, 2020

  by Sunil Pai

* ## [Building Great User Experiences with Concurrent Mode and Suspense](/blog/2019/11/06/building-great-user-experiences-with-concurrent-mode-and-suspense.html)

  November 06, 2019

  by Joseph Savona

* ## [Preparing for the Future with React Prereleases](/blog/2019/10/22/react-release-channels.html)

  October 22, 2019

  by Andrew Clark

* ## [Introducing the New React DevTools](/blog/2019/08/15/new-react-devtools.html)

  August 15, 2019

  by Brian Vaughn

* ## [React v16.9.0 and the Roadmap Update](/blog/2019/08/08/react-v16.9.0.html)

  August 08, 2019

  by Dan Abramov and Brian Vaughn

* ## [Is React Translated Yet? ¡Sí! Sim! はい！](/blog/2019/02/23/is-react-translated-yet.html)

  February 23, 2019

  by Nat Alison

* ## [React v16.8: The One With Hooks](/blog/2019/02/06/react-v16.8.0.html)

  February 06, 2019

  by Dan Abramov

* ## [React v16.7: No, This Is Not the One With Hooks](/blog/2018/12/19/react-v-16-7.html)

  December 19, 2018

  by Andrew Clark

* ## [React 16.x Roadmap](/blog/2018/11/27/react-16-roadmap.html)

  November 27, 2018

  by Dan Abramov

* ## [React Conf recap: Hooks, Suspense, and Concurrent Rendering](/blog/2018/11/13/react-conf-recap.html)

  November 13, 2018

  by Tom Occhino

* ## [React v16.6.0: lazy, memo and contextType](/blog/2018/10/23/react-v-16-6.html)

  October 23, 2018

  by Sebastian Markbåge

* ## [Create React App 2.0: Babel 7, Sass, and More](/blog/2018/10/01/create-react-app-v2.html)

  October 01, 2018

  by Joe Haddad and Dan Abramov

* ## [Introducing the React Profiler](/blog/2018/09/10/introducing-the-react-profiler.html)

  September 10, 2018

  by Brian Vaughn

* ## [React v16.4.2: Server-side vulnerability fix](/blog/2018/08/01/react-v-16-4-2.html)

  August 01, 2018

  by Dan Abramov

* ## [You Probably Don't Need Derived State](/blog/2018/06/07/you-probably-dont-need-derived-state.html)

  June 07, 2018

  by Brian Vaughn

* ## [React v16.4.0: Pointer Events](/blog/2018/05/23/react-v-16-4.html)

  May 23, 2018

  by Andrew Clark

* ## [React v16.3.0: New lifecycles and context API](/blog/2018/03/29/react-v-16-3.html)

  March 29, 2018

  by Brian Vaughn

* ## [Update on Async Rendering](/blog/2018/03/27/update-on-async-rendering.html)

  March 27, 2018

  by Brian Vaughn

* ## [Sneak Peek: Beyond React 16](/blog/2018/03/01/sneak-peek-beyond-react-16.html)

  March 01, 2018

  by Sophie Alpert

* ## [Behind the Scenes: Improving the Repository Infrastructure](/blog/2017/12/15/improving-the-repository-infrastructure.html)

  December 15, 2017

  by Dan Abramov and Brian Vaughn

* ## [Introducing the React RFC Process](/blog/2017/12/07/introducing-the-react-rfc-process.html)

  December 07, 2017

  by Andrew Clark

* ## [React v16.2.0: Improved Support for Fragments](/blog/2017/11/28/react-v16.2.0-fragment-support.html)

  November 28, 2017

  by Clement Hoang

* ## [React v16.0](/blog/2017/09/26/react-v16.0.html)

  September 26, 2017

  by Andrew Clark

* ## [React v15.6.2](/blog/2017/09/25/react-v15.6.2.html)

  September 25, 2017

  by Nathan Hunzaker

* ## [DOM Attributes in React 16](/blog/2017/09/08/dom-attributes-in-react-16.html)

  September 08, 2017

  by Dan Abramov

* ## [Error Handling in React 16](/blog/2017/07/26/error-handling-in-react-16.html)

  July 26, 2017

  by Dan Abramov

* ## [React v15.6.0](/blog/2017/06/13/react-v15.6.0.html)

  June 13, 2017

  by Flarnie Marchan

* ## [What's New in Create React App](/blog/2017/05/18/whats-new-in-create-react-app.html)

  May 18, 2017

  by Dan Abramov

* ## [React v15.5.0](/blog/2017/04/07/react-v15.5.0.html)

  April 07, 2017

  by Andrew Clark

* ## [React v15.4.0](/blog/2016/11/16/react-v15.4.0.html)

  November 16, 2016

  by Dan Abramov

* ## [Our First 50,000 Stars](/blog/2016/09/28/our-first-50000-stars.html)

  September 28, 2016

  by Vjeux

* ## [Relay: State of the State](/blog/2016/08/05/relay-state-of-the-state.html)

  August 05, 2016

  by Joseph Savona

* ## [Create Apps with No Configuration](/blog/2016/07/22/create-apps-with-no-configuration.html)

  July 22, 2016

  by Dan Abramov

* ## [Mixins Considered Harmful](/blog/2016/07/13/mixins-considered-harmful.html)

  July 13, 2016

  by Dan Abramov

* ## [Introducing React's Error Code System](/blog/2016/07/11/introducing-reacts-error-code-system.html)

  July 11, 2016

  by Keyan Zhang

* ## [React v15.0.1](/blog/2016/04/08/react-v15.0.1.html)

  April 08, 2016

  by Paul O’Shannessy

* ## [React v15.0](/blog/2016/04/07/react-v15.html)

  April 07, 2016

  by Dan Abramov

* ## [React v0.14.8](/blog/2016/03/29/react-v0.14.8.html)

  March 29, 2016

  by Dan Abramov

* ## [React v15.0 Release Candidate 2](/blog/2016/03/16/react-v15-rc2.html)

  March 16, 2016

  by Paul O’Shannessy

* ## [React v15.0 Release Candidate](/blog/2016/03/07/react-v15-rc1.html)

  March 07, 2016

  by Paul O’Shannessy

* ## [New Versioning Scheme](/blog/2016/02/19/new-versioning-scheme.html)

  February 19, 2016

  by Sebastian Markbåge

* ## [Discontinuing IE 8 Support in React DOM](/blog/2016/01/12/discontinuing-ie8-support.html)

  January 12, 2016

  by Sophie Alpert

* ## [(A => B) !=> (B => A)](/blog/2016/01/08/A-implies-B-does-not-imply-B-implies-A.html)

  January 08, 2016

  by Jim Sproch

* ## [React v0.14.4](/blog/2015/12/29/react-v0.14.4.html)

  December 29, 2015

  by Sophie Alpert

* ## [React Components, Elements, and Instances](/blog/2015/12/18/react-components-elements-and-instances.html)

  December 18, 2015

  by Dan Abramov

* ## [isMounted is an Antipattern](/blog/2015/12/16/ismounted-antipattern.html)

  December 16, 2015

  by Jim Sproch

* ## [React.js Conf 2016 Diversity Scholarship](/blog/2015/12/04/react-js-conf-2016-diversity-scholarship.html)

  December 04, 2015

  by Paul O’Shannessy

* ## [React v0.14.3](/blog/2015/11/18/react-v0.14.3.html)

  November 18, 2015

  by Paul O’Shannessy

* ## [React v0.14.2](/blog/2015/11/02/react-v0.14.2.html)

  November 02, 2015

  by Paul O’Shannessy

* ## [React v0.14.1](/blog/2015/10/28/react-v0.14.1.html)

  October 28, 2015

  by Paul O’Shannessy

* ## [Reactiflux is moving to Discord](/blog/2015/10/19/reactiflux-is-moving-to-discord.html)

  October 19, 2015

  by Paul Benigeri

* ## [React v0.14](/blog/2015/10/07/react-v0.14.html)

  October 07, 2015

  by Sophie Alpert

* ## [ReactDOM.render and the Top Level React API](/blog/2015/10/01/react-render-and-top-level-api.html)

  October 01, 2015

  by Jim Sproch and Sebastian Markbåge

* ## [Community Round-up #27 – Relay Edition](/blog/2015/09/14/community-roundup-27.html)

  September 14, 2015

  by Steven Luscher

* ## [React v0.14 Release Candidate](/blog/2015/09/10/react-v0.14-rc1.html)

  September 10, 2015

  by Sophie Alpert

* ## [New React Developer Tools](/blog/2015/09/02/new-react-developer-tools.html)

  September 02, 2015

  by Sophie Alpert

* ## [ReactEurope Round-up](/blog/2015/08/13/reacteurope-roundup.html)

  August 13, 2015

  by Matthew Johnston

* ## [Relay Technical Preview](/blog/2015/08/11/relay-technical-preview.html)

  August 11, 2015

  by Joseph Savona

* ## [New React Devtools Beta](/blog/2015/08/03/new-react-devtools-beta.html)

  August 03, 2015

  by Jared Forsyth

* ## [React v0.14 Beta 1](/blog/2015/07/03/react-v0.14-beta-1.html)

  July 03, 2015

  by Sophie Alpert

* ## [Deprecating JSTransform and react-tools](/blog/2015/06/12/deprecating-jstransform-and-react-tools.html)

  June 12, 2015

  by Paul O’Shannessy

* ## [React Native Release Process](/blog/2015/05/22/react-native-release-process.html)

  May 22, 2015

  by Vjeux

* ## [React v0.13.3](/blog/2015/05/08/react-v0.13.3.html)

  May 08, 2015

  by Paul O’Shannessy

* ## [GraphQL Introduction](/blog/2015/05/01/graphql-introduction.html)

  May 01, 2015

  by Nick Schrock

* ## [React v0.13.2](/blog/2015/04/18/react-v0.13.2.html)

  April 18, 2015

  by Paul O’Shannessy

* ## [React Native v0.4](/blog/2015/04/17/react-native-v0.4.html)

  April 17, 2015

  by Vjeux

* ## [Community Round-up #26](/blog/2015/03/30/community-roundup-26.html)

  March 30, 2015

  by Vjeux

* ## [Introducing React Native](/blog/2015/03/26/introducing-react-native.html)

  March 26, 2015

  by Sophie Alpert

* ## [Building The Facebook News Feed With Relay](/blog/2015/03/19/building-the-facebook-news-feed-with-relay.html)

  March 19, 2015

  by Joseph Savona

* ## [React v0.13.1](/blog/2015/03/16/react-v0.13.1.html)

  March 16, 2015

  by Paul O’Shannessy

* ## [React v0.13](/blog/2015/03/10/react-v0.13.html)

  March 10, 2015

  by Sophie Alpert

* ## [Community Round-up #25](/blog/2015/03/04/community-roundup-25.html)

  March 04, 2015

  by Matthew Johnston

* ## [React v0.13 RC2](/blog/2015/03/03/react-v0.13-rc2.html)

  March 03, 2015

  by Sebastian Markbåge

* ## [React v0.13 RC](/blog/2015/02/24/react-v0.13-rc1.html)

  February 24, 2015

  by Paul O’Shannessy

* ## [Streamlining React Elements](/blog/2015/02/24/streamlining-react-elements.html)

  February 24, 2015

  by Sebastian Markbåge

* ## [Introducing Relay and GraphQL](/blog/2015/02/20/introducing-relay-and-graphql.html)

  February 20, 2015

  by Greg Hurrell

* ## [React.js Conf Round-up 2015](/blog/2015/02/18/react-conf-roundup-2015.html)

  February 18, 2015

  by Steven Luscher

* ## [React v0.13.0 Beta 1](/blog/2015/01/27/react-v0.13.0-beta-1.html)

  January 27, 2015

  by Sebastian Markbåge

* ## [React.js Conf Diversity Scholarship](/blog/2014/12/19/react-js-conf-diversity-scholarship.html)

  December 19, 2014

  by Paul O’Shannessy

* ## [React v0.12.2](/blog/2014/12/18/react-v0.12.2.html)

  December 18, 2014

  by Paul O’Shannessy

* ## [Community Round-up #24](/blog/2014/11/25/community-roundup-24.html)

  November 25, 2014

  by Steven Luscher

* ## [React.js Conf Updates](/blog/2014/11/24/react-js-conf-updates.html)

  November 24, 2014

  by Vjeux

* ## [React v0.12](/blog/2014/10/28/react-v0.12.html)

  October 28, 2014

  by Paul O’Shannessy

* ## [React.js Conf](/blog/2014/10/27/react-js-conf.html)

  October 27, 2014

  by Vjeux

* ## [Community Round-up #23](/blog/2014/10/17/community-roundup-23.html)

  October 17, 2014

  by Lou Husson

* ## [React v0.12 RC](/blog/2014/10/16/react-v0.12-rc1.html)

  October 16, 2014

  by Sebastian Markbåge

* ## [Introducing React Elements](/blog/2014/10/14/introducing-react-elements.html)

  October 14, 2014

  by Sebastian Markbåge

* ## [Testing Flux Applications](/blog/2014/09/24/testing-flux-applications.html)

  September 24, 2014

  by Bill Fisher

* ## [React v0.11.2](/blog/2014/09/16/react-v0.11.2.html)

  September 16, 2014

  by Paul O’Shannessy

* ## [Community Round-up #22](/blog/2014/09/12/community-round-up-22.html)

  September 12, 2014

  by Lou Husson

* ## [Introducing the JSX Specification](/blog/2014/09/03/introducing-the-jsx-specification.html)

  September 03, 2014

  by Sebastian Markbåge

* ## [Community Round-up #21](/blog/2014/08/03/community-roundup-21.html)

  August 03, 2014

  by Lou Husson

* ## [Flux: Actions and the Dispatcher](/blog/2014/07/30/flux-actions-and-the-dispatcher.html)

  July 30, 2014

  by Bill Fisher

* ## [Community Round-up #20](/blog/2014/07/28/community-roundup-20.html)

  July 28, 2014

  by Lou Husson

* ## [React v0.11.1](/blog/2014/07/25/react-v0.11.1.html)

  July 25, 2014

  by Paul O’Shannessy

* ## [React v0.11](/blog/2014/07/17/react-v0.11.html)

  July 17, 2014

  by Paul O’Shannessy

* ## [React v0.11 RC](/blog/2014/07/13/react-v0.11-rc1.html)

  July 13, 2014

  by Paul O’Shannessy

* ## [Community Round-up #19](/blog/2014/06/27/community-roundup-19.html)

  June 27, 2014

  by Cheng Lou

* ## [One Year of Open-Source React](/blog/2014/05/29/one-year-of-open-source-react.html)

  May 29, 2014

  by Cheng Lou

* ## [Flux: An Application Architecture for React](/blog/2014/05/06/flux.html)

  May 06, 2014

  by Bill Fisher and Jing Chen

* ## [Use React and JSX in ASP.NET MVC](/blog/2014/04/04/reactnet.html)

  April 04, 2014

  by Daniel Lo Nigro

* ## [The Road to 1.0](/blog/2014/03/28/the-road-to-1.0.html)

  March 28, 2014

  by Paul O’Shannessy

* ## [React v0.10](/blog/2014/03/21/react-v0.10.html)

  March 21, 2014

  by Paul O’Shannessy

* ## [React v0.10 RC](/blog/2014/03/19/react-v0.10-rc1.html)

  March 19, 2014

  by Paul O’Shannessy

* ## [Community Round-up #18](/blog/2014/03/14/community-roundup-18.html)

  March 14, 2014

  by Jonas Gebhardt

* ## [Community Round-up #17](/blog/2014/02/24/community-roundup-17.html)

  February 24, 2014

  by Jonas Gebhardt

* ## [React v0.9](/blog/2014/02/20/react-v0.9.html)

  February 20, 2014

  by Sophie Alpert

* ## [React v0.9 RC](/blog/2014/02/16/react-v0.9-rc1.html)

  February 16, 2014

  by Sophie Alpert

* ## [Community Round-up #16](/blog/2014/02/15/community-roundup-16.html)

  February 15, 2014

  by Jonas Gebhardt

* ## [Community Round-up #15](/blog/2014/02/05/community-roundup-15.html)

  February 05, 2014

  by Jonas Gebhardt

* ## [Community Round-up #14](/blog/2014/01/06/community-roundup-14.html)

  January 06, 2014

  by Vjeux

* ## [React Chrome Developer Tools](/blog/2014/01/02/react-chrome-developer-tools.html)

  January 02, 2014

  by Sebastian Markbåge

* ## [Community Round-up #13](/blog/2013/12/30/community-roundup-13.html)

  December 30, 2013

  by Vjeux

* ## [Community Round-up #12](/blog/2013/12/23/community-roundup-12.html)

  December 23, 2013

  by Vjeux

* ## [React v0.8](/blog/2013/12/19/react-v0.8.0.html)

  December 19, 2013

  by Paul O’Shannessy

* ## [React v0.5.2, v0.4.2](/blog/2013/12/18/react-v0.5.2-v0.4.2.html)

  December 18, 2013

  by Paul O’Shannessy

* ## [Community Round-up #11](/blog/2013/11/18/community-roundup-11.html)

  November 18, 2013

  by Vjeux

* ## [Community Round-up #10](/blog/2013/11/06/community-roundup-10.html)

  November 06, 2013

  by Vjeux

* ## [React v0.5.1](/blog/2013/10/29/react-v0-5-1.html)

  October 29, 2013

  by Paul O’Shannessy

* ## [React v0.5](/blog/2013/10/16/react-v0.5.0.html)

  October 16, 2013

  by Paul O’Shannessy

* ## [Community Round-up #9](/blog/2013/10/3/community-roundup-9.html)

  October 03, 2013

  by Vjeux

* ## [Community Round-up #8](/blog/2013/09/24/community-roundup-8.html)

  September 24, 2013

  by Vjeux

* ## [Community Round-up #7](/blog/2013/08/26/community-roundup-7.html)

  August 26, 2013

  by Vjeux

* ## [Use React and JSX in Python Applications](/blog/2013/08/19/use-react-and-jsx-in-python-applications.html)

  August 19, 2013

  by Kunal Mehta

* ## [Community Round-up #6](/blog/2013/08/05/community-roundup-6.html)

  August 05, 2013

  by Vjeux

* ## [Use React and JSX in Ruby on Rails](/blog/2013/07/30/use-react-and-jsx-in-ruby-on-rails.html)

  July 30, 2013

  by Paul O’Shannessy

* ## [React v0.4.1](/blog/2013/07/26/react-v0-4-1.html)

  July 26, 2013

  by Paul O’Shannessy

* ## [Community Round-up #5](/blog/2013/07/23/community-roundup-5.html)

  July 23, 2013

  by Vjeux

* ## [React v0.4.0](/blog/2013/07/17/react-v0-4-0.html)

  July 17, 2013

  by Paul O’Shannessy

* ## [New in React v0.4: Prop Validation and Default Values](/blog/2013/07/11/react-v0-4-prop-validation-and-default-values.html)

  July 11, 2013

  by Paul O’Shannessy

* ## [Community Round-up #4](/blog/2013/07/03/community-roundup-4.html)

  July 03, 2013

  by Vjeux

* ## [New in React v0.4: Autobind by Default](/blog/2013/07/02/react-v0-4-autobind-by-default.html)

  July 02, 2013

  by Paul O’Shannessy

* ## [Community Round-up #3](/blog/2013/06/27/community-roundup-3.html)

  June 27, 2013

  by Vjeux

* ## [React v0.3.3](/blog/2013/06/21/react-v0-3-3.html)

  June 21, 2013

  by Paul O’Shannessy

* ## [Community Round-up #2](/blog/2013/06/19/community-roundup-2.html)

  June 19, 2013

  by Vjeux

* ## [Community Round-up #1](/blog/2013/06/12/community-roundup.html)

  June 12, 2013

  by Vjeux

* ## [Why did we build React?](/blog/2013/06/05/why-react.html)

  June 05, 2013

  by Pete Hunt

* ## [JSFiddle Integration](/blog/2013/06/02/jsfiddle-integration.html)

  June 02, 2013

  by Vjeux

----
url: https://legacy.reactjs.org/blog/2018/09/10/introducing-the-react-profiler.html
----

September 10, 2018 by [Brian Vaughn](https://github.com/bvaughn)

React 16.5 adds support for a new DevTools profiler plugin. This plugin uses React’s [experimental Profiler API](https://github.com/reactjs/rfcs/pull/51) to collect timing information about each component that’s rendered in order to identify performance bottlenecks in React applications. It will be fully compatible with our upcoming [time slicing and suspense](/blog/2018/03/01/sneak-peek-beyond-react-16.html) features.

This blog post covers the following topics:

* [Profiling an application](#profiling-an-application)

* [Reading performance data](#reading-performance-data)

  * [Browsing commits](#browsing-commits)
  * [Filtering commits](#filtering-commits)
  * [Flame chart](#flame-chart)
  * [Ranked chart](#ranked-chart)
  * [Component chart](#component-chart)
  * [Interactions](#interactions)

* [Troubleshooting](#troubleshooting)

  * [No profiling data has been recorded for the selected root](#no-profiling-data-has-been-recorded-for-the-selected-root)
  * [No timing data to display for the selected commit](#no-timing-data-to-display-for-the-selected-commit)

* [Deep dive video](#deep-dive-video)

## [](#profiling-an-application)Profiling an application

DevTools will show a “Profiler” tab for applications that support the new profiling API:

[](/static/4da6b55fc3c98de04c261cd902c14dc3/ad997/devtools-profiler-tab.png)

> Note:
>
> `react-dom` 16.5+ supports profiling in DEV mode. A production profiling bundle is also available as `react-dom/profiling`. Read more about how to use this bundle at [fb.me/react-profiling](https://fb.me/react-profiling)

The “Profiler” panel will be empty initially. Click the record button to start profiling:

[](/static/bae8d10e17f06eeb8c512c91c0153cff/ad997/start-profiling.png)

Once you’ve started recording, DevTools will automatically collect performance information each time your application renders. Use your app as you normally would. When you are finished profiling, click the “Stop” button.

[](/static/45619de03bed468869f7a0878f220586/ad997/stop-profiling.png)

Assuming your application rendered at least once while profiling, DevTools will show several ways to view the performance data. We’ll [take a look at each of these below](#reading-performance-data).

## [](#reading-performance-data)Reading performance data

### [](#browsing-commits)Browsing commits

Conceptually, React does work in two phases:

* The **render** phase determines what changes need to be made to e.g. the DOM. During this phase, React calls `render` and then compares the result to the previous render.
* The **commit** phase is when React applies any changes. (In the case of React DOM, this is when React inserts, updates, and removes DOM nodes.) React also calls lifecycles like `componentDidMount` and `componentDidUpdate` during this phase.

The DevTools profiler groups performance info by commit. Commits are displayed in a bar chart near the top of the profiler:

[](/static/bd72dec045515d59be51c944e902d263/d8f62/commit-selector.png)

Each bar in the chart represents a single commit with the currently selected commit colored black. You can click on a bar (or the left/right arrow buttons) to select a different commit.

The color and height of each bar corresponds to how long that commit took to render. (Taller, yellow bars took longer than shorter, blue bars.)

### [](#filtering-commits)Filtering commits

The longer you profile, the more times your application will render. In some cases you may end up with *too many commits* to easily process. The profiler offers a filtering mechanism to help with this. Use it to specify a threshold and the profiler will hide all commits that were *faster* than that value.

### [](#flame-chart)Flame chart

The flame chart view represents the state of your application for a particular commit. Each bar in the chart represents a React component (e.g. `App`, `Nav`). The size and color of the bar represents how long it took to render the component and its children. (The width of a bar represents how much time was spent *when the component last rendered* and the color represents how much time was spent *as part of the current commit*.)

[](/static/3046f500b9bfc052bde8b7b3b3cfc243/ad997/flame-chart.png)

> Note:
>
> The width of a bar indicates how long it took to render the component (and its children) when they last rendered. If the component did not re-render as part of this commit, the time represents a previous render. The wider a component is, the longer it took to render.
>
> The color of a bar indicates how long the component (and its children) took to render in the selected commit. Yellow components took more time, blue components took less time, and gray components did not render at all during this commit.

For example, the commit shown above took a total of 18.4ms to render. The `Router` component was the “most expensive” to render (taking 18.4ms). Most of this time was due to two of its children, `Nav` (8.4ms) and `Route` (7.9ms). The rest of the time was divided between its remaining children or spent in the component’s own render method.

You can zoom in or out on a flame chart by clicking on components:

Clicking on a component will also select it and show information in the right side panel which includes its `props` and `state` at the time of this commit. You can drill into these to learn more about what the component actually rendered during the commit:

In some cases, selecting a component and stepping between commits may also provide a hint as to *why* the component rendered:

The above image shows that `state.scrollOffset` changed between commits. This is likely what caused the `List` component to re-render.

### [](#ranked-chart)Ranked chart

The ranked chart view represents a single commit. Each bar in the chart represents a React component (e.g. `App`, `Nav`). The chart is ordered so that the components which took the longest to render are at the top.

[](/static/0c81347535e28c9cdef0e94fab887b89/ad997/ranked-chart.png)

> Note:
>
> A component’s render time includes the time spent rendering its children, so the components which took the longest to render are generally near the top of the tree.

As with the flame chart, you can zoom in or out on a ranked chart by clicking on components.

### [](#component-chart)Component chart

Sometimes it’s useful to see how many times a particular component rendered while you were profiling. The component chart provides this information in the form of a bar chart. Each bar in the chart represents a time when the component rendered. The color and height of each bar corresponds to how long the component took to render *relative to other components* in a particular commit.

[](/static/d71275b42c6109e222fbb0932a0c8c09/ad997/component-chart.png)

The chart above shows that the `List` component rendered 11 times. It also shows that each time it rendered, it was the most “expensive” component in the commit (meaning that it took the longest).

To view this chart, either double-click on a component *or* select a component and click on the blue bar chart icon in the right detail pane. You can return to the previous chart by clicking the “x” button in the right detail pane. You can also double click on a particular bar to view more information about that commit.

If the selected component did not render at all during the profiling session, the following message will be shown:

[](/static/8eb0c37a13353ef5d9e61ae8fc040705/ad997/no-render-times-for-selected-component.png)

### [](#interactions)Interactions

React recently added another [experimental API](https://fb.me/react-interaction-tracing) for tracing the *cause* of an update. “Interactions” traced with this API will also be shown in the profiler:

[](/static/a91a39ac076b71aa7a202aaf46f8bd5a/ad997/interactions.png)

The image above shows a profiling session that traced four interactions. Each row represents an interaction that was traced. The colored dots along the row represent commits that were related to that interaction.

You can also see which interactions were traced for a particular commit from the flame chart and ranked chart views as well:

[](/static/9847e78f930cb7cf2b0f9682853a5dbc/ad997/interactions-for-commit.png)

You can navigate between interactions and commits by clicking on them:

The tracing API is still new and we will cover it in more detail in a future blog post.

## [](#troubleshooting)Troubleshooting

### [](#no-profiling-data-has-been-recorded-for-the-selected-root)No profiling data has been recorded for the selected root

If your application has multiple “roots”, you may see the following message after profiling:[](/static/0755492a211f5bbb775285c0ff2fdfda/ad997/no-profiler-data-multi-root.png)

This message indicates that no performance data was recorded for the root that’s selected in the “Elements” panel. In this case, try selecting a different root in that panel to view profiling information for that root:

### [](#no-timing-data-to-display-for-the-selected-commit)No timing data to display for the selected commit

Sometimes a commit may be so fast that `performance.now()` doesn’t give DevTools any meaningful timing information. In this case, the following message will be shown:

[](/static/63b2fb6298feecb179272c467020ed95/ad997/no-timing-data-for-commit.png)

## [](#deep-dive-video)Deep dive video

The following video demonstrates how the React profiler can be used to detect and improve performance bottlenecks in an actual React application.



Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2018-09-10-introducing-the-react-profiler.md)

----
url: https://legacy.reactjs.org/docs/lists-and-keys.html
----

> These docs are old and won’t be updated. Go to [react.dev](https://react.dev/) for the new React docs.
>
> These new documentation pages teach modern React and include live examples:
>
> * [Rendering Lists](https://react.dev/learn/rendering-lists)

First, let’s review how you transform lists in JavaScript.

Given the code below, we use the [`map()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) function to take an array of `numbers` and double their values. We assign the new array returned by `map()` to the variable `doubled` and log it:

```
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map((number) => number * 2);console.log(doubled);
```

This code logs `[2, 4, 6, 8, 10]` to the console.

In React, transforming arrays into lists of [elements](/docs/rendering-elements.html) is nearly identical.

### [](#rendering-multiple-components)Rendering Multiple Components

You can build collections of elements and [include them in JSX](/docs/introducing-jsx.html#embedding-expressions-in-jsx) using curly braces `{}`.

Below, we loop through the `numbers` array using the JavaScript [`map()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) function. We return a `<li>` element for each item. Finally, we assign the resulting array of elements to `listItems`:

```
const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) =>  <li>{number}</li>);
```

Then, we can include the entire `listItems` array inside a `<ul>` element:

```
<ul>{listItems}</ul>
```

[**Try it on CodePen**](https://codepen.io/gaearon/pen/GjPyQr?editors=0011)

This code displays a bullet list of numbers between 1 and 5.

### [](#basic-list-component)Basic List Component

Usually you would render lists inside a [component](/docs/components-and-props.html).

We can refactor the previous example into a component that accepts an array of `numbers` and outputs a list of elements.

```
function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>    <li>{number}</li>  );  return (
    <ul>{listItems}</ul>  );
}

const numbers = [1, 2, 3, 4, 5];
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<NumberList numbers={numbers} />);
```

When you run this code, you’ll be given a warning that a key should be provided for list items. A “key” is a special string attribute you need to include when creating lists of elements. We’ll discuss why it’s important in the next section.

Let’s assign a `key` to our list items inside `numbers.map()` and fix the missing key issue.

```
function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>
    <li key={number.toString()}>      {number}
    </li>
  );
  return (
    <ul>{listItems}</ul>
  );
}
```

[**Try it on CodePen**](https://codepen.io/gaearon/pen/jrXYRR?editors=0011)

## [](#keys)Keys

Keys help React identify which items have changed, are added, or are removed. Keys should be given to the elements inside the array to give the elements a stable identity:

```
const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) =>
  <li key={number.toString()}>    {number}
  </li>
);
```

The best way to pick a key is to use a string that uniquely identifies a list item among its siblings. Most often you would use IDs from your data as keys:

```
const todoItems = todos.map((todo) =>
  <li key={todo.id}>    {todo.text}
  </li>
);
```

When you don’t have stable IDs for rendered items, you may use the item index as a key as a last resort:

```
const todoItems = todos.map((todo, index) =>
  // Only do this if items have no stable IDs  <li key={index}>    {todo.text}
  </li>
);
```

We don’t recommend using indexes for keys if the order of items may change. This can negatively impact performance and may cause issues with component state. Check out Robin Pokorny’s article for an [in-depth explanation on the negative impacts of using an index as a key](https://robinpokorny.com/blog/index-as-a-key-is-an-anti-pattern/). If you choose not to assign an explicit key to list items then React will default to using indexes as keys.

Here is an [in-depth explanation about why keys are necessary](/docs/reconciliation.html#recursing-on-children) if you’re interested in learning more.

### [](#extracting-components-with-keys)Extracting Components with Keys

Keys only make sense in the context of the surrounding array.

For example, if you [extract](/docs/components-and-props.html#extracting-components) a `ListItem` component, you should keep the key on the `<ListItem />` elements in the array rather than on the `<li>` element in the `ListItem` itself.

**Example: Incorrect Key Usage**

```
function ListItem(props) {
  const value = props.value;
  return (
    // Wrong! There is no need to specify the key here:    <li key={value.toString()}>      {value}
    </li>
  );
}

function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>
    // Wrong! The key should have been specified here:    <ListItem value={number} />  );
  return (
    <ul>
      {listItems}
    </ul>
  );
}
```

**Example: Correct Key Usage**

```
function ListItem(props) {
  // Correct! There is no need to specify the key here:  return <li>{props.value}</li>;}

function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>
    // Correct! Key should be specified inside the array.    <ListItem key={number.toString()} value={number} />  );
  return (
    <ul>
      {listItems}
    </ul>
  );
}
```

[**Try it on CodePen**](https://codepen.io/gaearon/pen/ZXeOGM?editors=0010)

A good rule of thumb is that elements inside the `map()` call need keys.

### [](#keys-must-only-be-unique-among-siblings)Keys Must Only Be Unique Among Siblings

Keys used within arrays should be unique among their siblings. However, they don’t need to be globally unique. We can use the same keys when we produce two different arrays:

```
function Blog(props) {
  const sidebar = (    <ul>
      {props.posts.map((post) =>
        <li key={post.id}>          {post.title}
        </li>
      )}
    </ul>
  );
  const content = props.posts.map((post) =>    <div key={post.id}>      <h3>{post.title}</h3>
      <p>{post.content}</p>
    </div>
  );
  return (
    <div>
      {sidebar}      <hr />
      {content}    </div>
  );
}

const posts = [
  {id: 1, title: 'Hello World', content: 'Welcome to learning React!'},
  {id: 2, title: 'Installation', content: 'You can install React from npm.'}
];

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Blog posts={posts} />);
```

[**Try it on CodePen**](https://codepen.io/gaearon/pen/NRZYGN?editors=0010)

Keys serve as a hint to React but they don’t get passed to your components. If you need the same value in your component, pass it explicitly as a prop with a different name:

```
const content = posts.map((post) =>
  <Post
    key={post.id}    id={post.id}    title={post.title} />
);
```

With the example above, the `Post` component can read `props.id`, but not `props.key`.

### [](#embedding-map-in-jsx)Embedding map() in JSX

In the examples above we declared a separate `listItems` variable and included it in JSX:

```
function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>    <ListItem key={number.toString()}              value={number} />  );  return (
    <ul>
      {listItems}
    </ul>
  );
}
```

JSX allows [embedding any expression](/docs/introducing-jsx.html#embedding-expressions-in-jsx) in curly braces so we could inline the `map()` result:

```
function NumberList(props) {
  const numbers = props.numbers;
  return (
    <ul>
      {numbers.map((number) =>        <ListItem key={number.toString()}                  value={number} />      )}    </ul>
  );
}
```

[**Try it on CodePen**](https://codepen.io/gaearon/pen/BLvYrB?editors=0010)

Sometimes this results in clearer code, but this style can also be abused. Like in JavaScript, it is up to you to decide whether it is worth extracting a variable for readability. Keep in mind that if the `map()` body is too nested, it might be a good time to [extract a component](/docs/components-and-props.html#extracting-components).

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/lists-and-keys.md)

* Previous article

  [Conditional Rendering](/docs/conditional-rendering.html)

* Next article

  [Forms](/docs/forms.html)

----
url: https://18.react.dev/learn/react-developer-tools
----

[Learn React](/learn)

[Installation](/learn/installation)

```
# Yarn

yarn global add react-devtools



# Npm

npm install -g react-devtools
```

Next open the developer tools from the terminal:

```
react-devtools
```

Then connect your website by adding the following `<script>` tag to the beginning of your website’s `<head>`:

```
<html>

  <head>

    <script src="http://localhost:8097"></script>
```

Reload your website in the browser now to view it in developer tools.

## Mobile (React Native)[](#mobile-react-native "Link for Mobile (React Native) ")

React Developer Tools can be used to inspect apps built with [React Native](https://reactnative.dev/) as well.

The easiest way to use React Developer Tools is to install it globally:

```
# Yarn

yarn global add react-devtools



# Npm

npm install -g react-devtools
```

Next open the developer tools from the terminal.

```
react-devtools
```

It should connect to any local React Native app that’s running.

> Try reloading the app if developer tools doesn’t connect after a few seconds.

[Learn more about debugging React Native.](https://reactnative.dev/docs/debugging)

[PreviousUsing TypeScript](/learn/typescript)

[NextReact Compiler](/learn/react-compiler)

***

----
url: https://legacy.reactjs.org/blog/2019/10/22/react-release-channels.html
----

October 22, 2019 by [Andrew Clark](https://twitter.com/acdlite)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

To share upcoming changes with our partners in the React ecosystem, we’re establishing official prerelease channels. We hope this process will help us make changes to React with confidence, and give developers the opportunity to try out experimental features.

> This post will be most relevant to developers who work on frameworks, libraries, or developer tooling. Developers who use React primarily to build user-facing applications should not need to worry about our prerelease channels.

React relies on a thriving open source community to file bug reports, open pull requests, and [submit RFCs](https://github.com/reactjs/rfcs). To encourage feedback, we sometimes share special builds of React that include unreleased features.

Because the source of truth for React is our [public GitHub repository](https://github.com/facebook/react), it’s always been possible to build a copy of React that includes the latest changes. However it’s much easier for developers to install React from npm, so we occasionally publish prerelease builds to the npm registry. A recent example is the 16.7 alpha, which included an early version of the Hooks API.

We would like to make it even easier for developers to test prerelease builds of React, so we’re formalizing our process with three separate release channels.

## [](#release-channels)Release Channels

> The information in this post is also available on our [Release Channels](/docs/release-channels.html) page. We will update that document whenever there are changes to our release process.

Each of React’s release channels is designed for a distinct use case:

* [**Latest**](#latest-channel) is for stable, semver React releases. It’s what you get when you install React from npm. This is the channel you’re already using today. **Use this for all user-facing React applications.**
* [**Next**](#next-channel) tracks the main branch of the React source code repository. Think of these as release candidates for the next minor semver release. Use this for integration testing between React and third party projects.
* [**Experimental**](#experimental-channel) includes experimental APIs and features that aren’t available in the stable releases. These also track the main branch, but with additional feature flags turned on. Use this to try out upcoming features before they are released.

All releases are published to npm, but only Latest uses [semantic versioning](/docs/faq-versioning.html). Prereleases (those in the Next and Experimental channels) have versions generated from a hash of their contents, e.g. `0.0.0-1022ee0ec` for Next and `0.0.0-experimental-1022ee0ec` for Experimental.

**The only officially supported release channel for user-facing applications is Latest**. Next and Experimental releases are provided for testing purposes only, and we provide no guarantees that behavior won’t change between releases. They do not follow the semver protocol that we use for releases from Latest.

By publishing prereleases to the same registry that we use for stable releases, we are able to take advantage of the many tools that support the npm workflow, like [unpkg](https://unpkg.com) and [CodeSandbox](https://codesandbox.io).

### [](#latest-channel)Latest Channel

Latest is the channel used for stable React releases. It corresponds to the `latest` tag on npm. It is the recommended channel for all React apps that are shipped to real users.

**If you’re not sure which channel you should use, it’s Latest.** If you’re a React developer, this is what you’re already using.

You can expect updates to Latest to be extremely stable. Versions follow the semantic versioning scheme. Learn more about our commitment to stability and incremental migration in our [versioning policy](/docs/faq-versioning.html).

### [](#next-channel)Next Channel

The Next channel is a prerelease channel that tracks the main branch of the React repository. We use prereleases in the Next channel as release candidates for the Latest channel. You can think of Next as a superset of Latest that is updated more frequently.

The degree of change between the most recent Next release and the most recent Latest release is approximately the same as you would find between two minor semver releases. However, **the Next channel does not conform to semantic versioning.** You should expect occasional breaking changes between successive releases in the Next channel.

**Do not use prereleases in user-facing applications.**

Releases in Next are published with the `next` tag on npm. Versions are generated from a hash of the build’s contents, e.g. `0.0.0-1022ee0ec`.

#### [](#using-the-next-channel-for-integration-testing)Using the Next Channel for Integration Testing

The Next channel is designed to support integration testing between React and other projects.

All changes to React go through extensive internal testing before they are released to the public. However, there are myriad environments and configurations used throughout the React ecosystem, and it’s not possible for us to test against every single one.

If you’re the author of a third party React framework, library, developer tool, or similar infrastructure-type project, you can help us keep React stable for your users and the entire React community by periodically running your test suite against the most recent changes. If you’re interested, follow these steps:

* Set up a cron job using your preferred continuous integration platform. Cron jobs are supported by both [CircleCI](https://circleci.com/docs/2.0/triggers/#scheduled-builds) and [Travis CI](https://docs.travis-ci.com/user/cron-jobs/).

* In the cron job, update your React packages to the most recent React release in the Next channel, using `next` tag on npm. Using the npm cli:

  ```
  npm update react@next react-dom@next
  ```

  Or yarn:

  ```
  yarn upgrade react@next react-dom@next
  ```

* Run your test suite against the updated packages.

* If everything passes, great! You can expect that your project will work with the next minor React release.

* If something breaks unexpectedly, please let us know by [filing an issue](https://github.com/facebook/react/issues).

A project that uses this workflow is Next.js. (No pun intended! Seriously!) You can refer to their [CircleCI configuration](https://github.com/zeit/next.js/blob/c0a1c0f93966fe33edd93fb53e5fafb0dcd80a9e/.circleci/config.yml) as an example.

### [](#experimental-channel)Experimental Channel

Like Next, the Experimental channel is a prerelease channel that tracks the main branch of the React repository. Unlike Next, Experimental releases include additional features and APIs that are not ready for wider release.

Usually, an update to Next is accompanied by a corresponding update to Experimental. They are based on the same source revision, but are built using a different set of feature flags.

Experimental releases may be significantly different than releases to Next and Latest. **Do not use Experimental releases in user-facing applications.** You should expect frequent breaking changes between releases in the Experimental channel.

Releases in Experimental are published with the `experimental` tag on npm. Versions are generated from a hash of the build’s contents, e.g. `0.0.0-experimental-1022ee0ec`.

#### [](#what-goes-into-an-experimental-release)What Goes Into an Experimental Release?

Experimental features are ones that are not ready to be released to the wider public, and may change drastically before they are finalized. Some experiments may never be finalized — the reason we have experiments is to test the viability of proposed changes.

For example, if the Experimental channel had existed when we announced Hooks, we would have released Hooks to the Experimental channel weeks before they were available in Latest.

You may find it valuable to run integration tests against Experimental. This is up to you. However, be advised that Experimental is even less stable than Next. **We do not guarantee any stability between Experimental releases.**

#### [](#how-can-i-learn-more-about-experimental-features)How Can I Learn More About Experimental Features?

Experimental features may or may not be documented. Usually, experiments aren’t documented until they are close to shipping in Next or Stable.

If a feature is not documented, they may be accompanied by an [RFC](https://github.com/reactjs/rfcs).

We will post to the React blog when we’re ready to announce new experiments, but that doesn’t mean we will publicize every experiment.

You can always refer to our public GitHub repository’s [history](https://github.com/facebook/react/commits/main) for a comprehensive list of changes.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2019-10-22-react-release-channels.md)

----
url: https://legacy.reactjs.org/docs/composition-vs-inheritance.html
----

> These docs are old and won’t be updated. Go to [react.dev](https://react.dev/) for the new React docs.

React has a powerful composition model, and we recommend using composition instead of inheritance to reuse code between components.

In this section, we will consider a few problems where developers new to React often reach for inheritance, and show how we can solve them with composition.

## [](#containment)Containment

Some components don’t know their children ahead of time. This is especially common for components like `Sidebar` or `Dialog` that represent generic “boxes”.

We recommend that such components use the special `children` prop to pass children elements directly into their output:

```
function FancyBorder(props) {
  return (
    <div className={'FancyBorder FancyBorder-' + props.color}>
      {props.children}    </div>
  );
}
```

This lets other components pass arbitrary children to them by nesting the JSX:

```
function WelcomeDialog() {
  return (
    <FancyBorder color="blue">
      <h1 className="Dialog-title">        Welcome      </h1>      <p className="Dialog-message">        Thank you for visiting our spacecraft!      </p>    </FancyBorder>
  );
}
```

**[Try it on CodePen](https://codepen.io/gaearon/pen/ozqNOV?editors=0010)**

Anything inside the `<FancyBorder>` JSX tag gets passed into the `FancyBorder` component as a `children` prop. Since `FancyBorder` renders `{props.children}` inside a `<div>`, the passed elements appear in the final output.

While this is less common, sometimes you might need multiple “holes” in a component. In such cases you may come up with your own convention instead of using `children`:

```
function SplitPane(props) {
  return (
    <div className="SplitPane">
      <div className="SplitPane-left">
        {props.left}      </div>
      <div className="SplitPane-right">
        {props.right}      </div>
    </div>
  );
}

function App() {
  return (
    <SplitPane
      left={
        <Contacts />      }
      right={
        <Chat />      } />
  );
}
```

[**Try it on CodePen**](https://codepen.io/gaearon/pen/gwZOJp?editors=0010)

React elements like `<Contacts />` and `<Chat />` are just objects, so you can pass them as props like any other data. This approach may remind you of “slots” in other libraries but there are no limitations on what you can pass as props in React.

## [](#specialization)Specialization

Sometimes we think about components as being “special cases” of other components. For example, we might say that a `WelcomeDialog` is a special case of `Dialog`.

In React, this is also achieved by composition, where a more “specific” component renders a more “generic” one and configures it with props:

```
function Dialog(props) {
  return (
    <FancyBorder color="blue">
      <h1 className="Dialog-title">
        {props.title}      </h1>
      <p className="Dialog-message">
        {props.message}      </p>
    </FancyBorder>
  );
}

function WelcomeDialog() {
  return (
    <Dialog      title="Welcome"      message="Thank you for visiting our spacecraft!" />  );
}
```

[**Try it on CodePen**](https://codepen.io/gaearon/pen/kkEaOZ?editors=0010)

Composition works equally well for components defined as classes:

```
function Dialog(props) {
  return (
    <FancyBorder color="blue">
      <h1 className="Dialog-title">
        {props.title}
      </h1>
      <p className="Dialog-message">
        {props.message}
      </p>
      {props.children}    </FancyBorder>
  );
}

class SignUpDialog extends React.Component {
  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
    this.handleSignUp = this.handleSignUp.bind(this);
    this.state = {login: ''};
  }

  render() {
    return (
      <Dialog title="Mars Exploration Program"
              message="How should we refer to you?">
        <input value={this.state.login}               onChange={this.handleChange} />        <button onClick={this.handleSignUp}>          Sign Me Up!        </button>      </Dialog>
    );
  }

  handleChange(e) {
    this.setState({login: e.target.value});
  }

  handleSignUp() {
    alert(`Welcome aboard, ${this.state.login}!`);
  }
}
```

[**Try it on CodePen**](https://codepen.io/gaearon/pen/gwZbYa?editors=0010)

## [](#so-what-about-inheritance)So What About Inheritance?

At Facebook, we use React in thousands of components, and we haven’t found any use cases where we would recommend creating component inheritance hierarchies.

Props and composition give you all the flexibility you need to customize a component’s look and behavior in an explicit and safe way. Remember that components may accept arbitrary props, including primitive values, React elements, or functions.

If you want to reuse non-UI functionality between components, we suggest extracting it into a separate JavaScript module. The components may import it and use that function, object, or class, without extending it.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/composition-vs-inheritance.md)

* Previous article

  [Lifting State Up](/docs/lifting-state-up.html)

* Next article

  [Thinking In React](/docs/thinking-in-react.html)

----
url: https://18.react.dev/reference/react-dom/client
----

[API Reference](/reference/react)

# Client React DOM APIs[](#undefined "Link for this heading")

The `react-dom/client` APIs let you render React components on the client (in the browser). These APIs are typically used at the top level of your app to initialize your React tree. A [framework](/learn/start-a-new-react-project#production-grade-react-frameworks) may call them for you. Most of your components don’t need to import or use them.

***

## Client APIs[](#client-apis "Link for Client APIs ")

* [`createRoot`](/reference/react-dom/client/createRoot) lets you create a root to display React components inside a browser DOM node.
* [`hydrateRoot`](/reference/react-dom/client/hydrateRoot) lets you display React components inside a browser DOM node whose HTML content was previously generated by [`react-dom/server`.](/reference/react-dom/server)

***

## Browser support[](#browser-support "Link for Browser support ")

React supports all popular browsers, including Internet Explorer 9 and above. Some polyfills are required for older browsers such as IE 9 and IE 10.

[PreviousunmountComponentAtNode](/reference/react-dom/unmountComponentAtNode)

[NextcreateRoot](/reference/react-dom/client/createRoot)

***

----
url: https://legacy.reactjs.org/docs/codebase-overview.html
----

This section will give you an overview of the React codebase organization, its conventions, and the implementation.

If you want to [contribute to React](/docs/how-to-contribute.html) we hope that this guide will help you feel more comfortable making changes.

We don’t necessarily recommend any of these conventions in React apps. Many of them exist for historical reasons and might change with time.

### [](#top-level-folders)Top-Level Folders

After cloning the [React repository](https://github.com/facebook/react), you will see a few top-level folders in it:

* [`packages`](https://github.com/facebook/react/tree/main/packages) contains metadata (such as `package.json`) and the source code (`src` subdirectory) for all packages in the React repository. **If your change is related to the code, the `src` subdirectory of each package is where you’ll spend most of your time.**
* [`fixtures`](https://github.com/facebook/react/tree/main/fixtures) contains a few small React test applications for contributors.
* `build` is the build output of React. It is not in the repository but it will appear in your React clone after you [build it](/docs/how-to-contribute.html#development-workflow) for the first time.

The documentation is hosted [in a separate repository from React](https://github.com/reactjs/reactjs.org).

There are a few other top-level folders but they are mostly used for the tooling and you likely won’t ever encounter them when contributing.

### [](#colocated-tests)Colocated Tests

We don’t have a top-level directory for unit tests. Instead, we put them into a directory called `__tests__` relative to the files that they test.

For example, a test for [`setInnerHTML.js`](https://github.com/facebook/react/blob/87724bd87506325fcaf2648c70fc1f43411a87be/src/renderers/dom/client/utils/setInnerHTML.js) is located in [`__tests__/setInnerHTML-test.js`](https://github.com/facebook/react/blob/87724bd87506325fcaf2648c70fc1f43411a87be/src/renderers/dom/client/utils/__tests__/setInnerHTML-test.js) right next to it.

### [](#warnings-and-invariants)Warnings and Invariants

The React codebase uses `console.error` to display warnings:

```
if (__DEV__) {
  console.error('Something is wrong.');
}
```

Warnings are only enabled in development. In production, they are completely stripped out. If you need to forbid some code path from executing, use `invariant` module instead:

```
var invariant = require('invariant');

invariant(
  2 + 2 === 4,
  'You shall not pass!'
);
```

**The invariant is thrown when the `invariant` condition is `false`.**

“Invariant” is just a way of saying “this condition always holds true”. You can think about it as making an assertion.

It is important to keep development and production behavior similar, so `invariant` throws both in development and in production. The error messages are automatically replaced with error codes in production to avoid negatively affecting the byte size.

### [](#development-and-production)Development and Production

You can use `__DEV__` pseudo-global variable in the codebase to guard development-only blocks of code.

It is inlined during the compile step, and turns into `process.env.NODE_ENV !== 'production'` checks in the CommonJS builds.

For standalone builds, it becomes `true` in the unminified build, and gets completely stripped out with the `if` blocks it guards in the minified build.

```
if (__DEV__) {
  // This code will only run in development.
}
```

### [](#flow)Flow

We recently started introducing [Flow](https://flow.org/) checks to the codebase. Files marked with the `@flow` annotation in the license header comment are being typechecked.

We accept pull requests [adding Flow annotations to existing code](https://github.com/facebook/react/pull/7600/files). Flow annotations look like this:

```
ReactRef.detachRefs = function(
  instance: ReactInstance,
  element: ReactElement | string | number | null | false,
): void {
  // ...
}
```

When possible, new code should use Flow annotations. You can run `yarn flow` locally to check your code with Flow.

### [](#multiple-packages)Multiple Packages

React is a [monorepo](https://danluu.com/monorepo/). Its repository contains multiple separate packages so that their changes can be coordinated together, and issues live in one place.

### [](#react-core)React Core

The “core” of React includes all the [top-level `React` APIs](/docs/react-api.html#react), for example:

* `React.createElement()`
* `React.Component`
* `React.Children`

**React core only includes the APIs necessary to define components.** It does not include the [reconciliation](/docs/reconciliation.html) algorithm or any platform-specific code. It is used both by React DOM and React Native components.

The code for React core is located in [`packages/react`](https://github.com/facebook/react/tree/main/packages/react) in the source tree. It is available on npm as the [`react`](https://www.npmjs.com/package/react) package. The corresponding standalone browser build is called `react.js`, and it exports a global called `React`.

### [](#renderers)Renderers

React was originally created for the DOM but it was later adapted to also support native platforms with [React Native](https://reactnative.dev/). This introduced the concept of “renderers” to React internals.

**Renderers manage how a React tree turns into the underlying platform calls.**

Renderers are also located in [`packages/`](https://github.com/facebook/react/tree/main/packages/):

* [React DOM Renderer](https://github.com/facebook/react/tree/main/packages/react-dom) renders React components to the DOM. It implements [top-level `ReactDOM` APIs](/docs/react-dom.html) and is available as [`react-dom`](https://www.npmjs.com/package/react-dom) npm package. It can also be used as standalone browser bundle called `react-dom.js` that exports a `ReactDOM` global.
* [React Native Renderer](https://github.com/facebook/react/tree/main/packages/react-native-renderer) renders React components to native views. It is used internally by React Native.
* [React Test Renderer](https://github.com/facebook/react/tree/main/packages/react-test-renderer) renders React components to JSON trees. It is used by the [Snapshot Testing](https://facebook.github.io/jest/blog/2016/07/27/jest-14.html) feature of [Jest](https://facebook.github.io/jest) and is available as [react-test-renderer](https://www.npmjs.com/package/react-test-renderer) npm package.

The only other officially supported renderer is [`react-art`](https://github.com/facebook/react/tree/main/packages/react-art). It used to be in a separate [GitHub repository](https://github.com/reactjs/react-art) but we moved it into the main source tree for now.

> **Note:**
>
> Technically the [`react-native-renderer`](https://github.com/facebook/react/tree/main/packages/react-native-renderer) is a very thin layer that teaches React to interact with React Native implementation. The real platform-specific code managing the native views lives in the [React Native repository](https://github.com/facebook/react-native) together with its components.

### [](#reconcilers)Reconcilers

Even vastly different renderers like React DOM and React Native need to share a lot of logic. In particular, the [reconciliation](/docs/reconciliation.html) algorithm should be as similar as possible so that declarative rendering, custom components, state, lifecycle methods, and refs work consistently across platforms.

To solve this, different renderers share some code between them. We call this part of React a “reconciler”. When an update such as `setState()` is scheduled, the reconciler calls `render()` on components in the tree and mounts, updates, or unmounts them.

Reconcilers are not packaged separately because they currently have no public API. Instead, they are exclusively used by renderers such as React DOM and React Native.

### [](#stack-reconciler)Stack Reconciler

The “stack” reconciler is the implementation powering React 15 and earlier. We have since stopped using it, but it is documented in detail in the [next section](/docs/implementation-notes.html).

### [](#fiber-reconciler)Fiber Reconciler

The “fiber” reconciler is a new effort aiming to resolve the problems inherent in the stack reconciler and fix a few long-standing issues. It has been the default reconciler since React 16.

Its main goals are:

* Ability to split interruptible work in chunks.
* Ability to prioritize, rebase and reuse work in progress.
* Ability to yield back and forth between parents and children to support layout in React.
* Ability to return multiple elements from `render()`.
* Better support for error boundaries.

You can read more about React Fiber Architecture [here](https://github.com/acdlite/react-fiber-architecture) and [here](https://blog.ag-grid.com/inside-fiber-an-in-depth-overview-of-the-new-reconciliation-algorithm-in-react). While it has shipped with React 16, the async features are not enabled by default yet.

Its source code is located in [`packages/react-reconciler`](https://github.com/facebook/react/tree/main/packages/react-reconciler).

### [](#event-system)Event System

React implements a layer over native events to smooth out cross-browser differences. Its source code is located in [`packages/react-dom/src/events`](https://github.com/facebook/react/tree/main/packages/react-dom/src/events).

### [](#what-next)What Next?

Read the [next section](/docs/implementation-notes.html) to learn about the pre-React 16 implementation of reconciler in more detail. We haven’t documented the internals of the new reconciler yet.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/codebase-overview.md)

* Previous article

  [How to Contribute](/docs/how-to-contribute.html)

* Next article

  [Implementation Notes](/docs/implementation-notes.html)

----
url: https://legacy.reactjs.org/blog/2013/06/12/community-roundup.html
----

June 12, 2013 by [Vjeux](https://twitter.com/vjeux)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

React was open sourced two weeks ago and it’s time for a little round-up of what has been going on.

## [](#khan-academy-question-editor)Khan Academy Question Editor

It looks like [Sophie Alpert](http://sophiebits.com/) is the first person outside of Facebook and Instagram to push React code to production. We are very grateful for her contributions in form of pull requests, bug reports and presence on IRC ([#reactjs on Freenode](irc://chat.freenode.net/reactjs)). Sophie wrote about her experience using React:

> I just rewrote a 2000-line project in React and have now made a handful of pull requests to React. Everything about React I’ve seen so far seems really well thought-out and I’m proud to be the first non-FB/IG production user of React.
>
> The project that I rewrote in React (and am continuing to improve) is the Khan Academy question editor which content creators can use to enter questions and hints that will be presented to students:
>
> [](http://sophiebits.com/2013/06/09/using-react-to-speed-up-khan-academy.html)
>
> [Read the full post…](http://sophiebits.com/2013/06/09/using-react-to-speed-up-khan-academy.html)

## [](#pimp-my-backboneview-by-replacing-it-with-react)Pimp my Backbone.View (by replacing it with React)

[Paul Seiffert](https://blog.mayflower.de/) wrote a blog post that explains how to integrate React into Backbone applications.

> React has some interesting concepts for JavaScript view objects that can be used to eliminate this one big problem I have with Backbone.js.
>
> As in most MVC implementations (although React is probably just a VC implementation), a view is one portion of the screen that is managed by a controlling object. This object is responsible for deciding when to re-render the view and how to react to user input. With React, these view-controllers objects are called components. A component knows how to render its view and how to handle to the user’s interaction with it.
>
> The interesting thing is that React is figuring out by itself when to re-render a view and how to do this in the most efficient way.
>
> [Read the full post…](https://blog.mayflower.de/3937-Backbone-React.html)

## [](#using-facebooks-react-with-requirejs)Using facebook’s React with require.js

[Mario Mueller](http://blog.xenji.com/) wrote a menu component in React and was able to easily integrate it with require.js, EventEmitter2 and bower.

> I recently stumbled upon facebook’s React library, which is a JavaScript library for building reusable frontend components. Even if this lib is only at version 0.3.x it behaves very stable, it is fast and is fun to code. I’m a big fan of require.js, so I tried to use React within the require.js eco system. It was not as hard as expected and here are some examples and some thoughts about it.
>
> [Read the full post…](http://blog.xenji.com/2013/06/facebooks-react-require-js.html)

## [](#origins-of-react)Origins of React

[Pete Hunt](http://www.petehunt.net/blog/) explained what differentiates React from other JavaScript libraries in [a previous blog post](/blog/2013/06/05/why-react.html). [Lee Byron](http://leebyron.com/) gives another perspective on Quora:

> React isn’t quite like any other popular JavaScript libraries, and it solves a very specific problem: complex UI rendering. It’s also intended to be used along side many other popular libraries. For example, React works well with Backbone.js, amongst many others.
>
> React was born out of frustrations with the common pattern of writing two-way data bindings in complex MVC apps. React is an implementation of one-way data bindings.
>
> [Read the full post…](https://www.quora.com/React-JS-Library/How-is-Facebooks-React-JavaScript-library/answer/Lee-Byron?srid=3DcX)

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2013-06-12-community-roundup.md)

----
url: https://legacy.reactjs.org/blog/2018/03/29/react-v-16-3.html
----

March 29, 2018 by [Brian Vaughn](https://github.com/bvaughn)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

A few days ago, we [wrote a post about upcoming changes to our legacy lifecycle methods](/blog/2018/03/27/update-on-async-rendering.html), including gradual migration strategies. In React 16.3.0, we are adding a few new lifecycle methods to assist with that migration. We are also introducing new APIs for long requested features: an official context API, a ref forwarding API, and an ergonomic ref API.

Read on to learn more about the release.

## [](#official-context-api)Official Context API

For many years, React has offered an experimental API for context. Although it was a powerful tool, its use was discouraged because of inherent problems in the API, and because we always intended to replace the experimental API with a better one.

Version 16.3 introduces a new context API that is more efficient and supports both static type checking and deep updates.

> **Note**
>
> The old context API will keep working for all React 16.x releases, so you will have time to migrate.

Here is an example illustrating how you might inject a “theme” using the new context API:

```
const ThemeContext = React.createContext('light');
class ThemeProvider extends React.Component {
  state = {theme: 'light'};

  render() {
    return (
      <ThemeContext.Provider value={this.state.theme}>        {this.props.children}      </ThemeContext.Provider>    );
  }
}

class ThemedButton extends React.Component {
  render() {
    return (
      <ThemeContext.Consumer>        {theme => <Button theme={theme} />}      </ThemeContext.Consumer>    );
  }
}
```

[Learn more about the new context API here.](/docs/context.html)

## [](#createref-api)`createRef` API

Previously, React provided two ways of managing refs: the legacy string ref API and the callback API. Although the string ref API was the more convenient of the two, it had [several downsides](https://github.com/facebook/react/issues/1373) and so our official recommendation was to use the callback form instead.

Version 16.3 adds a new option for managing refs that offers the convenience of a string ref without any of the downsides:

```
class MyComponent extends React.Component {
  constructor(props) {
    super(props);

    this.inputRef = React.createRef();  }

  render() {
    return <input type="text" ref={this.inputRef} />;  }

  componentDidMount() {
    this.inputRef.current.focus();  }
}
```

> **Note:**
>
> Callback refs will continue to be supported in addition to the new `createRef` API.
>
> You don’t need to replace callback refs in your components. They are slightly more flexible, so they will remain as an advanced feature.

[Learn more about the new `createRef` API here.](/docs/refs-and-the-dom.html)

## [](#forwardref-api)`forwardRef` API

Generally, React components are declarative, but sometimes imperative access to the component instances and the underlying DOM nodes is necessary. This is common for use cases like managing focus, selection, or animations. React provides [refs](/docs/refs-and-the-dom.html) as a way to solve this problem. However, component encapsulation poses some challenges with refs.

For example, if you replace a `<button>` with a custom `<FancyButton>` component, the `ref` attribute on it will start pointing at the wrapper component instead of the DOM node (and would be `null` for function components). While this is desirable for “application-level” components like `FeedStory` or `Comment` that need to be encapsulated, it can be annoying for “leaf” components such as `FancyButton` or `MyTextInput` that are typically used like their DOM counterparts, and might need to expose their DOM nodes.

Ref forwarding is a new opt-in feature that lets some components take a `ref` they receive, and pass it further down (in other words, “forward” it) to a child. In the example below, `FancyButton` forwards its ref to a DOM `button` that it renders:

```
const FancyButton = React.forwardRef((props, ref) => (  <button ref={ref} className="FancyButton">    {props.children}
  </button>
));

// You can now get a ref directly to the DOM button:
const ref = React.createRef();
<FancyButton ref={ref}>Click me!</FancyButton>;
```

This way, components using `FancyButton` can get a ref to the underlying `button` DOM node and access it if necessary—just like if they used a DOM `button` directly.

Ref forwarding is not limited to “leaf” components that render DOM nodes. If you write [higher order components](/docs/higher-order-components.html), we recommend using ref forwarding to automatically pass the ref down to the wrapped class component instances.

[Learn more about the forwardRef API here.](/docs/forwarding-refs.html)

## [](#component-lifecycle-changes)Component Lifecycle Changes

React’s class component API has been around for years with little change. However, as we add support for more advanced features (such as [error boundaries](/docs/react-component.html#componentdidcatch) and the upcoming [async rendering mode](/blog/2018/03/01/sneak-peek-beyond-react-16.html)) we stretch this model in ways that it was not originally intended.

For example, with the current API, it is too easy to block the initial render with non-essential logic. In part this is because there are too many ways to accomplish a given task, and it can be unclear which is best. We’ve observed that the interrupting behavior of error handling is often not taken into consideration and can result in memory leaks (something that will also impact the upcoming async rendering mode). The current class component API also complicates other efforts, like our work on [prototyping a React compiler](https://twitter.com/trueadm/status/944908776896978946).

Many of these issues are exacerbated by a subset of the component lifecycles (`componentWillMount`, `componentWillReceiveProps`, and `componentWillUpdate`). These also happen to be the lifecycles that cause the most confusion within the React community. For these reasons, we are going to deprecate those methods in favor of better alternatives.

We recognize that this change will impact many existing components. Because of this, the migration path will be as gradual as possible, and will provide escape hatches. (At Facebook, we maintain more than 50,000 React components. We depend on a gradual release cycle too!)

> **Note:**
>
> Deprecation warnings will be enabled with a future 16.x release, **but the legacy lifecycles will continue to work until version 17**.
>
> Even in version 17, it will still be possible to use them, but they will be aliased with an “UNSAFE\_” prefix to indicate that they might cause issues. We have also prepared an [automated script to rename them](https://github.com/reactjs/react-codemod#rename-unsafe-lifecycles) in existing code.

In addition to deprecating unsafe lifecycles, we are also adding a couple of new lifecyles:

* [`getDerivedStateFromProps`](/docs/react-component.html#static-getderivedstatefromprops) is being added as a safer alternative to the legacy `componentWillReceiveProps`. (Note that [in most cases you don’t need either of them](/blog/2018/06/07/you-probably-dont-need-derived-state.html).)
* [`getSnapshotBeforeUpdate`](/docs/react-component.html#getsnapshotbeforeupdate) is being added to support safely reading properties from e.g. the DOM before updates are made.

[Learn more about these lifecycle changes here.](/blog/2018/03/27/update-on-async-rendering.html)

## [](#strictmode-component)`StrictMode` Component

`StrictMode` is a tool for highlighting potential problems in an application. Like `Fragment`, `StrictMode` does not render any visible UI. It activates additional checks and warnings for its descendants.

> **Note:**
>
> `StrictMode` checks are run in development mode only; *they do not impact the production build*.

Although it is not possible for strict mode to catch all problems (e.g. certain types of mutation), it can help with many. If you see warnings in strict mode, those things will likely cause bugs for async rendering.

In version 16.3, `StrictMode` helps with:

* Identifying components with unsafe lifecycles
* Warning about legacy string ref API usage
* Detecting unexpected side effects

Additional functionality will be added with future releases of React.

[Learn more about the `StrictMode` component here.](/docs/strict-mode.html)

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2018-03-29-react-v-16-3.md)

----
url: https://legacy.reactjs.org/blog/2014/02/16/react-v0.9-rc1.html
----

February 16, 2014 by [Sophie Alpert](https://sophiebits.com/)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

We’re almost ready to release React v0.9! We’re posting a release candidate so that you can test your apps on it; we’d much prefer to find show-stopping bugs now rather than after we release.

The release candidate is available for download from the CDN:

* **React**\
  Dev build with warnings: <https://fb.me/react-0.9.0-rc1.js>\
  Minified build for production: <https://fb.me/react-0.9.0-rc1.min.js>
* **React with Add-Ons**\
  Dev build with warnings: <https://fb.me/react-with-addons-0.9.0-rc1.js>\
  Minified build for production: <https://fb.me/react-with-addons-0.9.0-rc1.min.js>
* **In-Browser JSX transformer**\
  <https://fb.me/JSXTransformer-0.9.0-rc1.js>

We’ve also published version `0.9.0-rc1` of the `react` and `react-tools` packages on npm and the `react` package on bower.

Please try these builds out and [file an issue on GitHub](https://github.com/facebook/react/issues/new) if you see anything awry.

## [](#upgrade-notes)Upgrade Notes

In addition to the changes to React core listed below, we’ve made a small change to the way JSX interprets whitespace to make things more consistent. With this release, space between two components on the same line will be preserved, while a newline separating a text node from a tag will be eliminated in the output. Consider the code:

```
<div>
  Monkeys:
  {listOfMonkeys} {submitButton}
</div>
```

In v0.8 and below, it was transformed to the following:

```
React.DOM.div(null,
  " Monkeys: ",
  listOfMonkeys, submitButton
)
```

In v0.9, it will be transformed to this JS instead:

```
React.DOM.div(null,
  "Monkeys:",  listOfMonkeys, " ", submitButton)
```

We believe this new behavior is more helpful and eliminates cases where unwanted whitespace was previously added.

In cases where you want to preserve the space adjacent to a newline, you can write a JS string like `{"Monkeys: "}` in your JSX source. We’ve included a script to do an automated codemod of your JSX source tree that preserves the old whitespace behavior by adding and removing spaces appropriately. You can [install jsx\_whitespace\_transformer from npm](https://github.com/facebook/react/blob/main/npm-jsx_whitespace_transformer/README.md) and run it over your source tree to modify files in place. The transformed JSX files will preserve your code’s existing whitespace behavior.

* When prop types validation fails, a warning is logged instead of an error thrown (with the production build of React, the type checks are now skipped for performance)
* On `input`, `select`, and `textarea` elements, `.getValue()` is no longer supported; use `.getDOMNode().value` instead
* `this.context` on components is now reserved for internal use by React

#### [](#new-features)New Features

* React now never rethrows errors, so stack traces are more accurate and Chrome’s purple break-on-error stop sign now works properly

* Added a new tool for profiling React components and identifying places where defining `shouldComponentUpdate` can give performance improvements

* Added support for SVG tags `defs`, `linearGradient`, `polygon`, `radialGradient`, `stop`

* Added support for more attributes:


Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2014-02-16-react-v0.9-rc1.md)

----
url: https://legacy.reactjs.org/redirect-to-codepen/reconciliation/no-index-used-as-key
----

```
```

[Powered by](https://www.algolia.com/?utm_source=react-instantsearch\&utm_medium=website\&utm_content=codepen.io\&utm_campaign=poweredby)

##### About External Resources

You can apply CSS to your Pen from any stylesheet on the web. Just put a URL to it here and we'll apply it, in the order you have them, before the CSS in the Pen itself.

You can also link to another Pen here (use the `.css` [URL Extension](https://blog.codepen.io/documentation/url-extensions/)) and we'll pull the CSS from that Pen and include it. If it's using a *matching* preprocessor, use the appropriate URL Extension and we'll combine the code before preprocessing, so you can use the linked Pen as a true dependency.

[Learn more](https://blog.codepen.io/documentation/editor/adding-external-resources/)

?

##### Insecure Resource

You are linking to a resource using the non-secure http\:// protocol, which may not work when the browser is using https\:// like CodePen enforces.

?

##### URL Extension Required

When linking another Pen as a resource, make sure you use a [URL Extension](https://blog.codepen.io/documentation/url-extensions/) of the type of code you want to link to. Either `.css`, `.js`, or the extension of a matching code processor.

[]()

?

##### Insecure Resource

You are linking to a resource using the non-secure http\:// protocol, which may not work when the browser is using https\:// like CodePen enforces.

?

##### URL Extension Required

When linking another Pen as a resource, make sure you use a [URL Extension](https://blog.codepen.io/documentation/url-extensions/) of the type of code you want to link to. Either `.css`, `.js`, or the extension of a matching code processor.

[]()

```
```

[Powered by](https://www.algolia.com/?utm_source=react-instantsearch\&utm_medium=website\&utm_content=codepen.io\&utm_campaign=poweredby)

##### About External Resources

You can apply a script from anywhere on the web to your Pen. Just put a URL to it here and we'll add it, in the order you have them, before the JavaScript in the Pen itself.

If the script you link to has the file extension of a preprocessor, we'll attempt to process it before applying.

You can also link to another Pen here, and we'll pull the JavaScript from that Pen and include it. If it's using a matching preprocessor, we'll combine the code before preprocessing, so you can use the linked Pen as a true dependency.

[Learn more](https://blog.codepen.io/documentation/adding-external-resources/)

?

##### Insecure Resource

You are linking to a resource using the non-secure http\:// protocol, which may not work when the browser is using https\:// like CodePen enforces.

?

##### URL Extension Required

When linking another Pen as a resource, make sure you use a [URL Extension](https://blog.codepen.io/documentation/url-extensions/) of the type of code you want to link to. Either `.css`, `.js`, or the extension of a matching code processor.

[](//unpkg.com/react/umd/react.development.js)

?

##### Insecure Resource

You are linking to a resource using the non-secure http\:// protocol, which may not work when the browser is using https\:// like CodePen enforces.

?

##### URL Extension Required

When linking another Pen as a resource, make sure you use a [URL Extension](https://blog.codepen.io/documentation/url-extensions/) of the type of code you want to link to. Either `.css`, `.js`, or the extension of a matching code processor.

[](//unpkg.com/react-dom/umd/react-dom.development.js)

\+ add another resource

### Packages

#### Add Packages

Search for and use JavaScript packages from [npm](https://www.npmjs.com/) here. By selecting a package, an `import` statement will be added to the top of the JavaScript editor for this package.

```
```

## HTML

 

1

```
<div id="root"></div>
```

!

## CSS

​x

 

1

```
​
```

!

## JS (Babel)

## JS (Babel)

```
xxxxxxxxxx
```

111

 

1

```
const ToDo = props => (
```

2

```
  <tr>
```

3

```
    <td>
```

4

```
      <label>{props.id}</label>
```

5

```
    </td>
```

6

```
    <td>
```

7

```
      <input />
```

8

```
    </td>
```

9

```
    <td>
```

10

```
      <label>{props.createdAt.toTimeString()}</label>
```

11

```
    </td>
```

12

```
  </tr>
```

13

```
);
```

14

```
​
```

15

```
class ToDoList extends React.Component {
```

16

```
  constructor() {
```

17

```
    super();
```

18

```
    const date = new Date();
```

19

```
    const toDoCounter = 1;
```

20

```
    this.state = {
```

21

```
      list: [
```

22

```
        {
```

23

```
          id: toDoCounter,
```

24

```
          createdAt: date,
```

25

```
        },
```

26

```
      ],
```

27

```
      toDoCounter: toDoCounter,
```

28

```
    };
```

29

```
  }
```

30

```
​
```

31

```
  sortByEarliest() {
```

32

```
    const sortedList = this.state.list.sort((a, b) => {
```

33

```
      return a.createdAt - b.createdAt;
```

34

```
    });
```

35

```
    this.setState({
```

36

```
      list: [...sortedList],
```

37

```
    });
```

38

```
  }
```

39

```
​
```

40

```
  sortByLatest() {
```

41

```
    const sortedList = this.state.list.sort((a, b) => {
```

42

```
      return b.createdAt - a.createdAt;
```

43

```
    });
```

44

```
    this.setState({
```

45

```
      list: [...sortedList],
```

46

```
    });
```

47

```
  }
```

48

```
​
```

49

```
  addToEnd() {
```

50

```
    const date = new Date();
```

51

```
    const nextId = this.state.toDoCounter + 1;
```

52

```
    const newList = [
```

53

```
      ...this.state.list,
```

54

```
      {id: nextId, createdAt: date},
```

55

```
    ];
```

56

```
    this.setState({
```

57

```
      list: newList,
```

58

```
      toDoCounter: nextId,
```

59

```
    });
```

60

```
  }
```

61

```
​
```

62

```
  addToStart() {
```

63

```
    const date = new Date();
```

64

```
    const nextId = this.state.toDoCounter + 1;
```

65

```
    const newList = [
```

66

```
      {id: nextId, createdAt: date},
```

67

```
      ...this.state.list,
```

68

```
    ];
```

69

```
    this.setState({
```

70

```
      list: newList,
```

71

```
      toDoCounter: nextId,
```

72

```
    });
```

73

```
  }
```

74

```
​
```

75

```
  render() {
```

76

```
    return (
```

77

```
      <div>
```

78

```
        <code>key=id</code>
```

79

```
        <br />
```

80

```
        <button onClick={this.addToStart.bind(this)}>
```

81

```
          Add New to Start
```

82

```
        </button>
```

83

```
        <button onClick={this.addToEnd.bind(this)}>
```

84

```
          Add New to End
```

85

```
        </button>
```

86

```
        <button onClick={this.sortByEarliest.bind(this)}>
```

87

```
          Sort by Earliest
```

88

```
        </button>
```

89

```
        <button onClick={this.sortByLatest.bind(this)}>
```

90

```
          Sort by Latest
```

91

```
        </button>
```

92

```
        <table>
```

93

```
          <tr>
```

94

```
            <th>ID</th>
```

95

```
            <th />
```

96

```
            <th>created at</th>
```

97

```
          </tr>
```

98

```
          {this.state.list.map((todo, index) => (
```

99

```
            <ToDo key={todo.id} {...todo} />
```

100

```
          ))}
```

101

```
        </table>
```

102

```
      </div>
```

103

```
    );
```

104

```
  }
```

105

```
}
```

106

```
​
```

107

```
ReactDOM.render(
```

108

```
  <ToDoList />,
```

109

```
  document.getElementById('root')
```

110

```
);
```

111

```
​
```

!

999px

If a groundhog inspects their Web Component, do they see their Shadow DOM?

----
url: https://react.dev/reference/react-dom/server/resumeToPipeableStream
----

[API Reference](/reference/react)

[Server APIs](/reference/react-dom/server)

# resumeToPipeableStream[](#undefined "Link for this heading")

`resumeToPipeableStream` streams a pre-rendered React tree to a pipeable [Node.js Stream.](https://nodejs.org/api/stream.html)

```
const {pipe, abort} = await resumeToPipeableStream(reactNode, postponedState, options?)
```

* [Reference](#reference)
  * [`resumeToPipeableStream(node, postponed, options?)`](#resume-to-pipeable-stream)
* [Usage](#usage)
  * [Further reading](#further-reading)

### Note

This API is specific to Node.js. Environments with [Web Streams,](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API) like Deno and modern edge runtimes, should use [`resume`](/reference/react-dom/server/renderToReadableStream) instead.

***

## Reference[](#reference "Link for Reference ")

### `resumeToPipeableStream(node, postponed, options?)`[](#resume-to-pipeable-stream "Link for this heading")

Call `resume` to resume rendering a pre-rendered React tree as HTML into a [Node.js Stream.](https://nodejs.org/api/stream.html#writable-streams)

```
import { resume } from 'react-dom/server';

import {getPostponedState} from './storage';



async function handler(request, response) {

  const postponed = await getPostponedState(request);

  const {pipe} = resumeToPipeableStream(<App />, postponed, {

    onShellReady: () => {

      pipe(response);

    }

  });

}
```

  * **optional** `onShellReady`: A callback that fires right after the [shell](#specifying-what-goes-into-the-shell) has finished. You can call `pipe` here to start streaming. React will [stream the additional content](#streaming-more-content-as-it-loads) after the shell along with the inline `<script>` tags that replace the HTML loading fallbacks with the content.
  * **optional** `onShellError`: A callback that fires if there was an error rendering the shell. It receives the error as an argument. No bytes were emitted from the stream yet, and neither `onShellReady` nor `onAllReady` will get called, so you can [output a fallback HTML shell](#recovering-from-errors-inside-the-shell) or use the prelude.

#### Returns[](#returns "Link for Returns ")

`resume` returns an object with two methods:

* `pipe` outputs the HTML into the provided [Writable Node.js Stream.](https://nodejs.org/api/stream.html#writable-streams) Call `pipe` in `onShellReady` if you want to enable streaming, or in `onAllReady` for crawlers and static generation.
* `abort` lets you [abort server rendering](#aborting-server-rendering) and render the rest on the client.

#### Caveats[](#caveats "Link for Caveats ")

* `resumeToPipeableStream` does not accept options for `bootstrapScripts`, `bootstrapScriptContent`, or `bootstrapModules`. Instead, you need to pass these options to the `prerender` call that generates the `postponedState`. You can also inject bootstrap content into the writable stream manually.
* `resumeToPipeableStream` does not accept `identifierPrefix` since the prefix needs to be the same in both `prerender` and `resumeToPipeableStream`.
* Since `nonce` cannot be provided to prerender, you should only provide `nonce` to `resumeToPipeableStream` if you’re not providing scripts to prerender.
* `resumeToPipeableStream` re-renders from the root until it finds a component that was not fully pre-rendered. Only fully prerendered Components (the Component and its children finished prerendering) are skipped entirely.

## Usage[](#usage "Link for Usage ")

### Further reading[](#further-reading "Link for Further reading ")

Resuming behaves like `renderToReadableStream`. For more examples, check out the [usage section of `renderToReadableStream`](/reference/react-dom/server/renderToReadableStream#usage). The [usage section of `prerender`](/reference/react-dom/static/prerender#usage) includes examples of how to use `prerenderToNodeStream` specifically.

[Previousresume](/reference/react-dom/server/resume)

[NextStatic APIs](/reference/react-dom/static)

***

----
url: https://react.dev/reference/eslint-plugin-react-hooks/lints/unsupported-syntax
----

[API Reference](/reference/react)

[Lints](/reference/eslint-plugin-react-hooks)

# unsupported-syntax[](#undefined "Link for this heading")

Validates against syntax that React Compiler does not support. If you need to, you can still use this syntax outside of React, such as in a standalone utility function.

## Rule Details[](#rule-details "Link for Rule Details ")

React Compiler needs to statically analyze your code to apply optimizations. Features like `eval` and `with` make it impossible to statically understand what the code does at compile time, so the compiler can’t optimize components that use them.

### Invalid[](#invalid "Link for Invalid ")

Examples of incorrect code for this rule:

```
// ❌ Using eval in component

function Component({ code }) {

  const result = eval(code); // Can't be analyzed

  return <div>{result}</div>;

}



// ❌ Using with statement

function Component() {

  with (Math) { // Changes scope dynamically

    return <div>{sin(PI / 2)}</div>;

  }

}



// ❌ Dynamic property access with eval

function Component({propName}) {

  const value = eval(`props.${propName}`);

  return <div>{value}</div>;

}
```

### Valid[](#valid "Link for Valid ")

Examples of correct code for this rule:

```
// ✅ Use normal property access

function Component({propName, props}) {

  const value = props[propName]; // Analyzable

  return <div>{value}</div>;

}



// ✅ Use standard Math methods

function Component() {

  return <div>{Math.sin(Math.PI / 2)}</div>;

}
```

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### I need to evaluate dynamic code[](#evaluate-dynamic-code "Link for I need to evaluate dynamic code ")

You might need to evaluate user-provided code:

```
// ❌ Wrong: eval in component

function Calculator({expression}) {

  const result = eval(expression); // Unsafe and unoptimizable

  return <div>Result: {result}</div>;

}
```

Use a safe expression parser instead:

```
// ✅ Better: Use a safe parser

import {evaluate} from 'mathjs'; // or similar library



function Calculator({expression}) {

  const [result, setResult] = useState(null);



  const calculate = () => {

    try {

      // Safe mathematical expression evaluation

      setResult(evaluate(expression));

    } catch (error) {

      setResult('Invalid expression');

    }

  };



  return (

    <div>

      <button onClick={calculate}>Calculate</button>

      {result && <div>Result: {result}</div>}

    </div>

  );

}
```

### Note

Never use `eval` with user input - it’s a security risk. Use dedicated parsing libraries for specific use cases like mathematical expressions, JSON parsing, or template evaluation.

[Previousstatic-components](/reference/eslint-plugin-react-hooks/lints/static-components)

[Nextuse-memo](/reference/eslint-plugin-react-hooks/lints/use-memo)

***

----
url: https://legacy.reactjs.org/docs/react-api.html
----

> These docs are old and won’t be updated. Go to [react.dev](https://react.dev/) for the new React docs.
>
> These new documentation pages teach modern React:
>
> * [`react`: Components](https://react.dev/reference/react/components)
> * [`react`: Hooks](https://react.dev/reference/react/)
> * [`react`: APIs](https://react.dev/reference/react/apis)
> * [`react`: Legacy APIs](https://react.dev/reference/react/legacy)

`React` is the entry point to the React library. If you load React from a `<script>` tag, these top-level APIs are available on the `React` global. If you use ES6 with npm, you can write `import React from 'react'`. If you use ES5 with npm, you can write `var React = require('react')`.

## [](#overview)Overview

### [](#components)Components

React components let you split the UI into independent, reusable pieces, and think about each piece in isolation. React components can be defined by subclassing `React.Component` or `React.PureComponent`.

* [`React.Component`](#reactcomponent)
* [`React.PureComponent`](#reactpurecomponent)

If you don’t use ES6 classes, you may use the `create-react-class` module instead. See [Using React without ES6](/docs/react-without-es6.html) for more information.

React components can also be defined as functions which can be wrapped:

* [`React.memo`](#reactmemo)

### [](#creating-react-elements)Creating React Elements

We recommend [using JSX](/docs/introducing-jsx.html) to describe what your UI should look like. Each JSX element is just syntactic sugar for calling [`React.createElement()`](#createelement). You will not typically invoke the following methods directly if you are using JSX.

* [`createElement()`](#createelement)
* [`createFactory()`](#createfactory)

See [Using React without JSX](/docs/react-without-jsx.html) for more information.

### [](#transforming-elements)Transforming Elements

`React` provides several APIs for manipulating elements:

* [`cloneElement()`](#cloneelement)
* [`isValidElement()`](#isvalidelement)
* [`React.Children`](#reactchildren)

### [](#fragments)Fragments

`React` also provides a component for rendering multiple elements without a wrapper.

* [`React.Fragment`](#reactfragment)

### [](#refs)Refs

* [`React.createRef`](#reactcreateref)
* [`React.forwardRef`](#reactforwardref)

### [](#suspense)Suspense

Suspense lets components “wait” for something before rendering. Today, Suspense only supports one use case: [loading components dynamically with `React.lazy`](/docs/code-splitting.html#reactlazy). In the future, it will support other use cases like data fetching.

* [`React.lazy`](#reactlazy)
* [`React.Suspense`](#reactsuspense)

### [](#transitions)Transitions

*Transitions* are a new concurrent feature introduced in React 18. They allow you to mark updates as transitions, which tells React that they can be interrupted and avoid going back to Suspense fallbacks for already visible content.

* [`React.startTransition`](#starttransition)
* [`React.useTransition`](/docs/hooks-reference.html#usetransition)

### [](#hooks)Hooks

*Hooks* are a new addition in React 16.8. They let you use state and other React features without writing a class. Hooks have a [dedicated docs section](/docs/hooks-intro.html) and a separate API reference:

* [Basic Hooks](/docs/hooks-reference.html#basic-hooks)

  * [`useState`](/docs/hooks-reference.html#usestate)
  * [`useEffect`](/docs/hooks-reference.html#useeffect)
  * [`useContext`](/docs/hooks-reference.html#usecontext)

* [Additional Hooks](/docs/hooks-reference.html#additional-hooks)

  * [`useReducer`](/docs/hooks-reference.html#usereducer)
  * [`useCallback`](/docs/hooks-reference.html#usecallback)
  * [`useMemo`](/docs/hooks-reference.html#usememo)
  * [`useRef`](/docs/hooks-reference.html#useref)
  * [`useImperativeHandle`](/docs/hooks-reference.html#useimperativehandle)
  * [`useLayoutEffect`](/docs/hooks-reference.html#uselayouteffect)
  * [`useDebugValue`](/docs/hooks-reference.html#usedebugvalue)
  * [`useDeferredValue`](/docs/hooks-reference.html#usedeferredvalue)
  * [`useTransition`](/docs/hooks-reference.html#usetransition)
  * [`useId`](/docs/hooks-reference.html#useid)

* [Library Hooks](/docs/hooks-reference.html#library-hooks)

  * [`useSyncExternalStore`](/docs/hooks-reference.html#usesyncexternalstore)
  * [`useInsertionEffect`](/docs/hooks-reference.html#useinsertioneffect)

***

## [](#reference)Reference

### [](#reactcomponent)`React.Component`

> This content is out of date.
>
> Read the new React documentation for [`Component`](https://react.dev/reference/react/Component).

`React.Component` is the base class for React components when they are defined using [ES6 classes](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Classes):

```
class Greeting extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}
```

See the [React.Component API Reference](/docs/react-component.html) for a list of methods and properties related to the base `React.Component` class.

***

### [](#reactpurecomponent)`React.PureComponent`

> This content is out of date.
>
> Read the new React documentation for [`PureComponent`](https://react.dev/reference/react/PureComponent).

`React.PureComponent` is similar to [`React.Component`](#reactcomponent). The difference between them is that [`React.Component`](#reactcomponent) doesn’t implement [`shouldComponentUpdate()`](/docs/react-component.html#shouldcomponentupdate), but `React.PureComponent` implements it with a shallow prop and state comparison.

If your React component’s `render()` function renders the same result given the same props and state, you can use `React.PureComponent` for a performance boost in some cases.

> Note
>
> `React.PureComponent`’s `shouldComponentUpdate()` only shallowly compares the objects. If these contain complex data structures, it may produce false-negatives for deeper differences. Only extend `PureComponent` when you expect to have simple props and state, or use [`forceUpdate()`](/docs/react-component.html#forceupdate) when you know deep data structures have changed. Or, consider using [immutable objects](https://immutable-js.com/) to facilitate fast comparisons of nested data.
>
> Furthermore, `React.PureComponent`’s `shouldComponentUpdate()` skips prop updates for the whole component subtree. Make sure all the children components are also “pure”.

***

### [](#reactmemo)`React.memo`

> This content is out of date.
>
> Read the new React documentation for [`memo`](https://react.dev/reference/react/memo).

```
const MyComponent = React.memo(function MyComponent(props) {
  /* render using props */
});
```

`React.memo` is a [higher order component](/docs/higher-order-components.html).

If your component renders the same result given the same props, you can wrap it in a call to `React.memo` for a performance boost in some cases by memoizing the result. This means that React will skip rendering the component, and reuse the last rendered result.

`React.memo` only checks for prop changes. If your function component wrapped in `React.memo` has a [`useState`](/docs/hooks-state.html), [`useReducer`](/docs/hooks-reference.html#usereducer) or [`useContext`](/docs/hooks-reference.html#usecontext) Hook in its implementation, it will still rerender when state or context change.

By default it will only shallowly compare complex objects in the props object. If you want control over the comparison, you can also provide a custom comparison function as the second argument.

```
function MyComponent(props) {
  /* render using props */
}
function areEqual(prevProps, nextProps) {
  /*
  return true if passing nextProps to render would return
  the same result as passing prevProps to render,
  otherwise return false
  */
}
export default React.memo(MyComponent, areEqual);
```

This method only exists as a **[performance optimization](/docs/optimizing-performance.html).** Do not rely on it to “prevent” a render, as this can lead to bugs.

> Note
>
> Unlike the [`shouldComponentUpdate()`](/docs/react-component.html#shouldcomponentupdate) method on class components, the `areEqual` function returns `true` if the props are equal and `false` if the props are not equal. This is the inverse from `shouldComponentUpdate`.

***

### [](#createelement)`createElement()`

> This content is out of date.
>
> Read the new React documentation for [`createElement`](https://react.dev/reference/react/createElement).

```
React.createElement(
  type,
  [props],
  [...children]
)
```

Create and return a new [React element](/docs/rendering-elements.html) of the given type. The type argument can be either a tag name string (such as `'div'` or `'span'`), a [React component](/docs/components-and-props.html) type (a class or a function), or a [React fragment](#reactfragment) type.

Code written with [JSX](/docs/introducing-jsx.html) will be converted to use `React.createElement()`. You will not typically invoke `React.createElement()` directly if you are using JSX. See [React Without JSX](/docs/react-without-jsx.html) to learn more.

***

### [](#cloneelement)`cloneElement()`

> This content is out of date.
>
> Read the new React documentation for [`cloneElement`](https://react.dev/reference/react/cloneElement).

```
React.cloneElement(
  element,
  [config],
  [...children]
)
```

Clone and return a new React element using `element` as the starting point. `config` should contain all new props, `key`, or `ref`. The resulting element will have the original element’s props with the new props merged in shallowly. New children will replace existing children. `key` and `ref` from the original element will be preserved if no `key` and `ref` present in the `config`.

`React.cloneElement()` is almost equivalent to:

```
<element.type {...element.props} {...props}>{children}</element.type>
```

However, it also preserves `ref`s. This means that if you get a child with a `ref` on it, you won’t accidentally steal it from your ancestor. You will get the same `ref` attached to your new element. The new `ref` or `key` will replace old ones if present.

This API was introduced as a replacement of the deprecated `React.addons.cloneWithProps()`.

***

### [](#createfactory)`createFactory()`

> This content is out of date.
>
> Read the new React documentation for [`createFactory`](https://react.dev/reference/react/createFactory).

```
React.createFactory(type)
```

Return a function that produces React elements of a given type. Like [`React.createElement()`](#createelement), the type argument can be either a tag name string (such as `'div'` or `'span'`), a [React component](/docs/components-and-props.html) type (a class or a function), or a [React fragment](#reactfragment) type.

This helper is considered legacy, and we encourage you to either use JSX or use `React.createElement()` directly instead.

You will not typically invoke `React.createFactory()` directly if you are using JSX. See [React Without JSX](/docs/react-without-jsx.html) to learn more.

***

### [](#isvalidelement)`isValidElement()`

> This content is out of date.
>
> Read the new React documentation for [`isValidElement`](https://react.dev/reference/react/isValidElement).

```
React.isValidElement(object)
```

Verifies the object is a React element. Returns `true` or `false`.

***

### [](#reactchildren)`React.Children`

> This content is out of date.
>
> Read the new React documentation for [`Children`](https://react.dev/reference/react/Children).

`React.Children` provides utilities for dealing with the `this.props.children` opaque data structure.

#### [](#reactchildrenmap)`React.Children.map`

```
React.Children.map(children, function[(thisArg)])
```

Invokes a function on every immediate child contained within `children` with `this` set to `thisArg`. If `children` is an array it will be traversed and the function will be called for each child in the array. If children is `null` or `undefined`, this method will return `null` or `undefined` rather than an array.

> Note
>
> If `children` is a `Fragment` it will be treated as a single child and not traversed.

#### [](#reactchildrenforeach)`React.Children.forEach`

```
React.Children.forEach(children, function[(thisArg)])
```

Like [`React.Children.map()`](#reactchildrenmap) but does not return an array.

#### [](#reactchildrencount)`React.Children.count`

```
React.Children.count(children)
```

Returns the total number of components in `children`, equal to the number of times that a callback passed to `map` or `forEach` would be invoked.

#### [](#reactchildrenonly)`React.Children.only`

```
React.Children.only(children)
```

Verifies that `children` has only one child (a React element) and returns it. Otherwise this method throws an error.

> Note:
>
> `React.Children.only()` does not accept the return value of [`React.Children.map()`](#reactchildrenmap) because it is an array rather than a React element.

#### [](#reactchildrentoarray)`React.Children.toArray`

```
React.Children.toArray(children)
```

Returns the `children` opaque data structure as a flat array with keys assigned to each child. Useful if you want to manipulate collections of children in your render methods, especially if you want to reorder or slice `this.props.children` before passing it down.

> Note:
>
> `React.Children.toArray()` changes keys to preserve the semantics of nested arrays when flattening lists of children. That is, `toArray` prefixes each key in the returned array so that each element’s key is scoped to the input array containing it.

***

### [](#reactfragment)`React.Fragment`

> This content is out of date.
>
> Read the new React documentation for [`Fragment`](https://react.dev/reference/react/Fragment).

The `React.Fragment` component lets you return multiple elements in a `render()` method without creating an additional DOM element:

```
render() {
  return (
    <React.Fragment>
      Some text.
      <h2>A heading</h2>
    </React.Fragment>
  );
}
```

You can also use it with the shorthand `<></>` syntax. For more information, see [React v16.2.0: Improved Support for Fragments](/blog/2017/11/28/react-v16.2.0-fragment-support.html).

### [](#reactcreateref)`React.createRef`

> This content is out of date.
>
> Read the new React documentation for [`createRef`](https://react.dev/reference/react/createRef).

`React.createRef` creates a [ref](/docs/refs-and-the-dom.html) that can be attached to React elements via the ref attribute.

```
class MyComponent extends React.Component {
  constructor(props) {
    super(props);

    this.inputRef = React.createRef();  }

  render() {
    return <input type="text" ref={this.inputRef} />;  }

  componentDidMount() {
    this.inputRef.current.focus();  }
}
```

### [](#reactforwardref)`React.forwardRef`

> This content is out of date.
>
> Read the new React documentation for [`forwardRef`](https://react.dev/reference/react/forwardRef).

`React.forwardRef` creates a React component that forwards the [ref](/docs/refs-and-the-dom.html) attribute it receives to another component below in the tree. This technique is not very common but is particularly useful in two scenarios:

* [Forwarding refs to DOM components](/docs/forwarding-refs.html#forwarding-refs-to-dom-components)
* [Forwarding refs in higher-order-components](/docs/forwarding-refs.html#forwarding-refs-in-higher-order-components)

`React.forwardRef` accepts a rendering function as an argument. React will call this function with `props` and `ref` as two arguments. This function should return a React node.

```
const FancyButton = React.forwardRef((props, ref) => (  <button ref={ref} className="FancyButton">    {props.children}
  </button>
));

// You can now get a ref directly to the DOM button:
const ref = React.createRef();
<FancyButton ref={ref}>Click me!</FancyButton>;
```

In the above example, React passes a `ref` given to `<FancyButton ref={ref}>` element as a second argument to the rendering function inside the `React.forwardRef` call. This rendering function passes the `ref` to the `<button ref={ref}>` element.

As a result, after React attaches the ref, `ref.current` will point directly to the `<button>` DOM element instance.

For more information, see [forwarding refs](/docs/forwarding-refs.html).

### [](#reactlazy)`React.lazy`

> This content is out of date.
>
> Read the new React documentation for [`lazy`](https://react.dev/reference/react/lazy).

`React.lazy()` lets you define a component that is loaded dynamically. This helps reduce the bundle size to delay loading components that aren’t used during the initial render.

You can learn how to use it from our [code splitting documentation](/docs/code-splitting.html#reactlazy). You might also want to check out [this article](https://medium.com/@pomber/lazy-loading-and-preloading-components-in-react-16-6-804de091c82d) explaining how to use it in more detail.

```
// This component is loaded dynamically
const SomeComponent = React.lazy(() => import('./SomeComponent'));
```

Note that rendering `lazy` components requires that there’s a `<React.Suspense>` component higher in the rendering tree. This is how you specify a loading indicator.

### [](#reactsuspense)`React.Suspense`

> This content is out of date.
>
> Read the new React documentation for [`Suspense`](https://react.dev/reference/react/Suspense).

`React.Suspense` lets you specify the loading indicator in case some components in the tree below it are not yet ready to render. In the future we plan to let `Suspense` handle more scenarios such as data fetching. You can read about this in [our roadmap](/blog/2018/11/27/react-16-roadmap.html).

Today, lazy loading components is the **only** use case supported by `<React.Suspense>`:

```
// This component is loaded dynamically
const OtherComponent = React.lazy(() => import('./OtherComponent'));

function MyComponent() {
  return (
    // Displays <Spinner> until OtherComponent loads
    <React.Suspense fallback={<Spinner />}>
      <div>
        <OtherComponent />
      </div>
    </React.Suspense>
  );
}
```

It is documented in our [code splitting guide](/docs/code-splitting.html#reactlazy). Note that `lazy` components can be deep inside the `Suspense` tree — it doesn’t have to wrap every one of them. The best practice is to place `<Suspense>` where you want to see a loading indicator, but to use `lazy()` wherever you want to do code splitting.

> Note
>
> For content that is already shown to the user, switching back to a loading indicator can be disorienting. It is sometimes better to show the “old” UI while the new UI is being prepared. To do this, you can use the new transition APIs [`startTransition`](#starttransition) and [`useTransition`](/docs/hooks-reference.html#usetransition) to mark updates as transitions and avoid unexpected fallbacks.

#### [](#reactsuspense-in-server-side-rendering)`React.Suspense` in Server Side Rendering

During server side rendering Suspense Boundaries allow you to flush your application in smaller chunks by suspending. When a component suspends we schedule a low priority task to render the closest Suspense boundary’s fallback. If the component unsuspends before we flush the fallback then we send down the actual content and throw away the fallback.

#### [](#reactsuspense-during-hydration)`React.Suspense` during hydration

Suspense boundaries depend on their parent boundaries being hydrated before they can hydrate, but they can hydrate independently from sibling boundaries. Events on a boundary before it is hydrated will cause the boundary to hydrate at a higher priority than neighboring boundaries. [Read more](https://github.com/reactwg/react-18/discussions/130)

### [](#starttransition)`React.startTransition`

> This content is out of date.
>
> Read the new React documentation for [`startTransition`](https://react.dev/reference/react/startTransition).

```
React.startTransition(callback)
```

`React.startTransition` lets you mark updates inside the provided callback as transitions. This method is designed to be used when [`React.useTransition`](/docs/hooks-reference.html#usetransition) is not available.

> 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, allowing the user to continue interacting while rendering the update.
>
> `React.startTransition` does not provide an `isPending` flag. To track the pending status of a transition see [`React.useTransition`](/docs/hooks-reference.html#usetransition).

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/reference-react.md)

----
url: https://react.dev/warnings/react-dom-test-utils
----

[React Docs](/)

# react-dom/test-utils Deprecation Warnings[](#undefined "Link for this heading")

## ReactDOMTestUtils.act() warning[](#reactdomtestutilsact-warning "Link for ReactDOMTestUtils.act() warning ")

`act` from `react-dom/test-utils` has been deprecated in favor of `act` from `react`.

Before:

```
import {act} from 'react-dom/test-utils';
```

After:

```
import {act} from 'react';
```

## Rest of ReactDOMTestUtils APIS[](#rest-of-reactdomtestutils-apis "Link for Rest of ReactDOMTestUtils APIS ")

All APIs except `act` have been removed.

The React Team recommends migrating your tests to [@testing-library/react](https://testing-library.com/docs/react-testing-library/intro/) for a modern and well supported testing experience.

### ReactDOMTestUtils.renderIntoDocument[](#reactdomtestutilsrenderintodocument "Link for ReactDOMTestUtils.renderIntoDocument ")

`renderIntoDocument` can be replaced with `render` from `@testing-library/react`.

Before:

```
import {renderIntoDocument} from 'react-dom/test-utils';



renderIntoDocument(<Component />);
```

After:

```
import {render} from '@testing-library/react';



render(<Component />);
```

### ReactDOMTestUtils.Simulate[](#reactdomtestutilssimulate "Link for ReactDOMTestUtils.Simulate ")

`Simulate` can be replaced with `fireEvent` from `@testing-library/react`.

Before:

```
import {Simulate} from 'react-dom/test-utils';



const element = document.querySelector('button');

Simulate.click(element);
```

After:

```
import {fireEvent} from '@testing-library/react';



const element = document.querySelector('button');

fireEvent.click(element);
```

Be aware that `fireEvent` dispatches an actual event on the element and doesn’t just synthetically call the event handler.

### List of all removed APIs[](#list-of-all-removed-apis-list-of-all-removed-apis "Link for List of all removed APIs ")

* `mockComponent()`
* `isElement()`
* `isElementOfType()`
* `isDOMComponent()`
* `isCompositeComponent()`
* `isCompositeComponentWithType()`
* `findAllInRenderedTree()`
* `scryRenderedDOMComponentsWithClass()`
* `findRenderedDOMComponentWithClass()`
* `scryRenderedDOMComponentsWithTag()`
* `findRenderedDOMComponentWithTag()`
* `scryRenderedComponentsWithType()`
* `findRenderedComponentWithType()`
* `renderIntoDocument`
* `Simulate`

***

----
url: https://18.react.dev/community
----

For the latest news about React, [follow **@reactjs** on Twitter](https://twitter.com/reactjs) and the [official React blog](/blog) on this website.

[NextReact Conferences](/community/conferences)

***

----
url: https://legacy.reactjs.org/docs/react-without-jsx.html
----

> These docs are old and won’t be updated. Go to [react.dev](https://react.dev/) for the new React docs.

JSX is not a requirement for using React. Using React without JSX is especially convenient when you don’t want to set up compilation in your build environment.

Each JSX element is just syntactic sugar for calling `React.createElement(component, props, ...children)`. So, anything you can do with JSX can also be done with just plain JavaScript.

For example, this code written with JSX:

```
class Hello extends React.Component {
  render() {
    return <div>Hello {this.props.toWhat}</div>;
  }
}

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Hello toWhat="World" />);
```

can be compiled to this code that does not use JSX:

```
class Hello extends React.Component {
  render() {
    return React.createElement('div', null, `Hello ${this.props.toWhat}`);
  }
}

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(React.createElement(Hello, {toWhat: 'World'}, null));
```

If you’re curious to see more examples of how JSX is converted to JavaScript, you can try out [the online Babel compiler](https://babeljs.io/repl/#?presets=react\&code_lz=GYVwdgxgLglg9mABACwKYBt1wBQEpEDeAUIogE6pQhlIA8AJjAG4B8AEhlogO5xnr0AhLQD0jVgG4iAXyJA).

The component can either be provided as a string, as a subclass of `React.Component`, or a plain function.

If you get tired of typing `React.createElement` so much, one common pattern is to assign a shorthand:

```
const e = React.createElement;

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(e('div', null, 'Hello World'));
```

If you use this shorthand form for `React.createElement`, it can be almost as convenient to use React without JSX.

Alternatively, you can refer to community projects such as [`react-hyperscript`](https://github.com/mlmorg/react-hyperscript) and [`hyperscript-helpers`](https://github.com/ohanhi/hyperscript-helpers) which offer a terser syntax.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/react-without-jsx.md)

----
url: https://legacy.reactjs.org/blog/2013/12/19/react-v0.8.0.html
----

December 19, 2013 by [Paul O’Shannessy](https://twitter.com/zpao)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

I’ll start by answering the obvious question:

> What happened to 0.6 and 0.7?

It’s become increasingly obvious since our launch in May that people want to use React on the server. With the server-side rendering abilities, that’s a perfect fit. However using the same copy of React on the server and then packaging it up for the client is surprisingly a harder problem. People have been using our `react-tools` module which includes React, but when browserifying that ends up packaging all of `esprima` and some other dependencies that aren’t needed on the client. So we wanted to make this whole experience better.

We talked with [Jeff Barczewski](https://github.com/jeffbski) who was the owner of the `react` module on npm. He was kind enough to transition ownership to us and release his package under a different name: `autoflow`. I encourage you to [check it out](https://github.com/jeffbski/autoflow) if you’re writing a lot of asynchronous code. In order to not break all of `react`’s current users of 0.7.x, we decided to bump our version to 0.8 and skip the issue entirely. We’re also including a warning if you use our `react` module like you would use the previous package.

In order to make the transition to 0.8 for our current users as painless as possible, we decided to make 0.8 primarily a bug fix release on top of 0.5. No public APIs were changed (even if they were already marked as deprecated). We haven’t added any of the new features we have in master, though we did take the opportunity to pull in some improvements to internals.

We hope that by releasing `react` on npm, we will enable a new set of uses that have been otherwise difficult. All feedback is welcome!

## [](#changelog)Changelog

### [](#react)React

* Added support for more attributes:

  * `rows` & `cols` for `<textarea>`
  * `defer` & `async` for `<script>`
  * `loop` for `<audio>` & `<video>`
  * `autoCorrect` for form fields (a non-standard attribute only supported by mobile WebKit)

* Improved error messages

* Fixed Selection events in IE11

* Added `onContextMenu` events

### [](#react-with-addons)React with Addons

* Fixed bugs with TransitionGroup when children were undefined
* Added support for `onTransition`

### [](#react-tools)react-tools

* Upgraded `jstransform` and `esprima-fb`

### [](#jsxtransformer)JSXTransformer

* Added support for use in IE8
* Upgraded browserify, which reduced file size by \~65KB (16KB gzipped)

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2013-12-19-react-v0.8.0.md)

----
url: https://react.dev/reference/react/cache
----

[API Reference](/reference/react)

[APIs](/reference/react/apis)

# cache[](#undefined "Link for this heading")

### React Server Components

`cache` is only for use with [React Server Components](/reference/rsc/server-components).

`cache` lets you cache the result of a data fetch or computation.

```
const cachedFn = cache(fn);
```

***

## Reference[](#reference "Link for Reference ")

### `cache(fn)`[](#cache "Link for this heading")

Call `cache` outside of any components to create a version of the function with caching.

```
import {cache} from 'react';

import calculateMetrics from 'lib/metrics';



const getMetrics = cache(calculateMetrics);



function Chart({data}) {

  const report = getMetrics(data);

  // ...

}
```

* `cache` is for use in [Server Components](/reference/rsc/server-components) only.

***

## Usage[](#usage "Link for Usage ")

### Cache an expensive computation[](#cache-expensive-computation "Link for Cache an expensive computation ")

Use `cache` to skip duplicate work.

```
import {cache} from 'react';

import calculateUserMetrics from 'lib/user';



const getUserMetrics = cache(calculateUserMetrics);



function Profile({user}) {

  const metrics = getUserMetrics(user);

  // ...

}



function TeamReport({users}) {

  for (let user in users) {

    const metrics = getUserMetrics(user);

    // ...

  }

  // ...

}
```

If the same `user` object is rendered in both `Profile` and `TeamReport`, the two components can share work and only call `calculateUserMetrics` once for that `user`.

Assume `Profile` is rendered first. It will call `getUserMetrics`, and check if there is a cached result. Since it is the first time `getUserMetrics` is called with that `user`, there will be a cache miss. `getUserMetrics` will then call `calculateUserMetrics` with that `user` and write the result to cache.

When `TeamReport` renders its list of `users` and reaches the same `user` object, it will call `getUserMetrics` and read the result from cache.

If `calculateUserMetrics` can be aborted by passing an [`AbortSignal`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal), you can use [`cacheSignal()`](/reference/react/cacheSignal) to cancel the expensive computation if React has finished rendering. `calculateUserMetrics` may already handle cancellation internally by using `cacheSignal` directly.

### Pitfall

##### Calling different memoized functions will read from different caches.[](#pitfall-different-memoized-functions "Link for Calling different memoized functions will read from different caches. ")

To access the same cache, components must call the same memoized function.

```
// Temperature.js

import {cache} from 'react';

import {calculateWeekReport} from './report';



export function Temperature({cityData}) {

  // 🚩 Wrong: Calling `cache` in component creates new `getWeekReport` for each render

  const getWeekReport = cache(calculateWeekReport);

  const report = getWeekReport(cityData);

  // ...

}
```

```
// Precipitation.js

import {cache} from 'react';

import {calculateWeekReport} from './report';



// 🚩 Wrong: `getWeekReport` is only accessible for `Precipitation` component.

const getWeekReport = cache(calculateWeekReport);



export function Precipitation({cityData}) {

  const report = getWeekReport(cityData);

  // ...

}
```

In the above example, `Precipitation` and `Temperature` each call `cache` to create a new memoized function with their own cache look-up. If both components render for the same `cityData`, they will do duplicate work to call `calculateWeekReport`.

In addition, `Temperature` creates a new memoized function each time the component is rendered which doesn’t allow for any cache sharing.

To maximize cache hits and reduce work, the two components should call the same memoized function to access the same cache. Instead, define the memoized function in a dedicated module that can be [`import`-ed](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import) across components.

```
// getWeekReport.js

import {cache} from 'react';

import {calculateWeekReport} from './report';



export default cache(calculateWeekReport);
```

```
// Temperature.js

import getWeekReport from './getWeekReport';



export default function Temperature({cityData}) {

	const report = getWeekReport(cityData);

  // ...

}
```

```
// Precipitation.js

import getWeekReport from './getWeekReport';



export default function Precipitation({cityData}) {

  const report = getWeekReport(cityData);

  // ...

}
```

Here, both components call the same memoized function exported from `./getWeekReport.js` to read and write to the same cache.

### Share a snapshot of data[](#take-and-share-snapshot-of-data "Link for Share a snapshot of data ")

To share a snapshot of data between components, call `cache` with a data-fetching function like `fetch`. When multiple components make the same data fetch, only one request is made and the data returned is cached and shared across components. All components refer to the same snapshot of data across the server render.

```
import {cache} from 'react';

import {fetchTemperature} from './api.js';



const getTemperature = cache(async (city) => {

	return await fetchTemperature(city);

});



async function AnimatedWeatherCard({city}) {

	const temperature = await getTemperature(city);

	// ...

}



async function MinimalWeatherCard({city}) {

	const temperature = await getTemperature(city);

	// ...

}
```

If `AnimatedWeatherCard` and `MinimalWeatherCard` both render for the same city, they will receive the same snapshot of data from the memoized function.

If `AnimatedWeatherCard` and `MinimalWeatherCard` supply different city arguments to `getTemperature`, then `fetchTemperature` will be called twice and each call site will receive different data.

The city acts as a cache key.

### Note

Asynchronous rendering is only supported for Server Components.

```
async function AnimatedWeatherCard({city}) {

	const temperature = await getTemperature(city);

	// ...

}
```

To render components that use asynchronous data in Client Components, see [`use()` documentation](/reference/react/use).

### Preload data[](#preload-data "Link for Preload data ")

By caching a long-running data fetch, you can kick off asynchronous work prior to rendering the component.

```
const getUser = cache(async (id) => {

  return await db.user.query(id);

});



async function Profile({id}) {

  const user = await getUser(id);

  return (

    <section>

      <img src={user.profilePic} />

      <h2>{user.name}</h2>

    </section>

  );

}



function Page({id}) {

  // ✅ Good: start fetching the user data

  getUser(id);

  // ... some computational work

  return (

    <>

      <Profile id={id} />

    </>

  );

}
```

When rendering `Page`, the component calls `getUser` but note that it doesn’t use the returned data. This early `getUser` call kicks off the asynchronous database query that occurs while `Page` is doing other computational work and rendering children.

When rendering `Profile`, we call `getUser` again. If the initial `getUser` call has already returned and cached the user data, when `Profile` asks and waits for this data, it can simply read from the cache without requiring another remote procedure call. If the initial data request hasn’t been completed, preloading data in this pattern reduces delay in data-fetching.

##### Deep Dive#### Caching asynchronous work[](#caching-asynchronous-work "Link for Caching asynchronous work ")

When evaluating an [asynchronous function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function), you will receive a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) for that work. The promise holds the state of that work (*pending*, *fulfilled*, *failed*) and its eventual settled result.

In this example, the asynchronous function `fetchData` returns a promise that is awaiting the `fetch`.

```
async function fetchData() {

  return await fetch(`https://...`);

}



const getData = cache(fetchData);



async function MyComponent() {

  getData();

  // ... some computational work

  await getData();

  // ...

}
```

In calling `getData` the first time, the promise returned from `fetchData` is cached. Subsequent look-ups will then return the same promise.

Notice that the first `getData` call does not `await` whereas the second does. [`await`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await) is a JavaScript operator that will wait and return the settled result of the promise. The first `getData` call simply initiates the `fetch` to cache the promise for the second `getData` to look-up.

If by the second call the promise is still *pending*, then `await` will pause for the result. The optimization is that while we wait on the `fetch`, React can continue with computational work, thus reducing the wait time for the second call.

If the promise is already settled, either to an error or the *fulfilled* result, `await` will return that value immediately. In both outcomes, there is a performance benefit.

### Pitfall

##### Calling a memoized function outside of a component will not use the cache.[](#pitfall-memoized-call-outside-component "Link for Calling a memoized function outside of a component will not use the cache. ")

```
import {cache} from 'react';



const getUser = cache(async (userId) => {

  return await db.user.query(userId);

});



// 🚩 Wrong: Calling memoized function outside of component will not memoize.

getUser('demo-id');



async function DemoProfile() {

  // ✅ Good: `getUser` will memoize.

  const user = await getUser('demo-id');

  return <Profile user={user} />;

}
```

React only provides cache access to the memoized function in a component. When calling `getUser` outside of a component, it will still evaluate the function but not read or update the cache.

This is because cache access is provided through a [context](/learn/passing-data-deeply-with-context) which is only accessible from a component.

##### Deep Dive#### When should I use `cache`, [`memo`](/reference/react/memo), or [`useMemo`](/reference/react/useMemo)?[](#cache-memo-usememo "Link for this heading")

All mentioned APIs offer memoization but the difference is what they’re intended to memoize, who can access the cache, and when their cache is invalidated.

#### `useMemo`[](#deep-dive-use-memo "Link for this heading")

In general, you should use [`useMemo`](/reference/react/useMemo) for caching an expensive computation in a Client Component across renders. As an example, to memoize a transformation of data within a component.

```
'use client';



function WeatherReport({record}) {

  const avgTemp = useMemo(() => calculateAvg(record), record);

  // ...

}



function App() {

  const record = getRecord();

  return (

    <>

      <WeatherReport record={record} />

      <WeatherReport record={record} />

    </>

  );

}
```

In this example, `App` renders two `WeatherReport`s with the same record. Even though both components do the same work, they cannot share work. `useMemo`’s cache is only local to the component.

However, `useMemo` does ensure that if `App` re-renders and the `record` object doesn’t change, each component instance would skip work and use the memoized value of `avgTemp`. `useMemo` will only cache the last computation of `avgTemp` with the given dependencies.

#### `cache`[](#deep-dive-cache "Link for this heading")

In general, you should use `cache` in Server Components to memoize work that can be shared across components.

```
const cachedFetchReport = cache(fetchReport);



function WeatherReport({city}) {

  const report = cachedFetchReport(city);

  // ...

}



function App() {

  const city = "Los Angeles";

  return (

    <>

      <WeatherReport city={city} />

      <WeatherReport city={city} />

    </>

  );

}
```

Re-writing the previous example to use `cache`, in this case the second instance of `WeatherReport` will be able to skip duplicate work and read from the same cache as the first `WeatherReport`. Another difference from the previous example is that `cache` is also recommended for memoizing data fetches, unlike `useMemo` which should only be used for computations.

At this time, `cache` should only be used in Server Components and the cache will be invalidated across server requests.

#### `memo`[](#deep-dive-memo "Link for this heading")

You should use [`memo`](/reference/react/memo) to prevent a component re-rendering if its props are unchanged.

```
'use client';



function WeatherReport({record}) {

  const avgTemp = calculateAvg(record);

  // ...

}



const MemoWeatherReport = memo(WeatherReport);



function App() {

  const record = getRecord();

  return (

    <>

      <MemoWeatherReport record={record} />

      <MemoWeatherReport record={record} />

    </>

  );

}
```

In this example, both `MemoWeatherReport` components will call `calculateAvg` when first rendered. However, if `App` re-renders, with no changes to `record`, none of the props have changed and `MemoWeatherReport` will not re-render.

Compared to `useMemo`, `memo` memoizes the component render based on props vs. specific computations. Similar to `useMemo`, the memoized component only caches the last render with the last prop values. Once the props change, the cache invalidates and the component re-renders.

***

```
import {cache} from 'react';



const calculateNorm = cache((vector) => {

  // ...

});



function MapMarker(props) {

  // 🚩 Wrong: props is an object that changes every render.

  const length = calculateNorm(props);

  // ...

}



function App() {

  return (

    <>

      <MapMarker x={10} y={10} z={10} />

      <MapMarker x={10} y={10} z={10} />

    </>

  );

}
```

In this case the two `MapMarker`s look like they’re doing the same work and calling `calculateNorm` with the same value of `{x: 10, y: 10, z:10}`. Even though the objects contain the same values, they are not the same object reference as each component creates its own `props` object.

React will call [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) on the input to verify if there is a cache hit.

```
import {cache} from 'react';



const calculateNorm = cache((x, y, z) => {

  // ...

});



function MapMarker(props) {

  // ✅ Good: Pass primitives to memoized function

  const length = calculateNorm(props.x, props.y, props.z);

  // ...

}



function App() {

  return (

    <>

      <MapMarker x={10} y={10} z={10} />

      <MapMarker x={10} y={10} z={10} />

    </>

  );

}
```

One way to address this could be to pass the vector dimensions to `calculateNorm`. This works because the dimensions themselves are primitives.

Another solution may be to pass the vector object itself as a prop to the component. We’ll need to pass the same object to both component instances.

```
import {cache} from 'react';



const calculateNorm = cache((vector) => {

  // ...

});



function MapMarker(props) {

  // ✅ Good: Pass the same `vector` object

  const length = calculateNorm(props.vector);

  // ...

}



function App() {

  const vector = [10, 10, 10];

  return (

    <>

      <MapMarker vector={vector} />

      <MapMarker vector={vector} />

    </>

  );

}
```

[PreviousaddTransitionType](/reference/react/addTransitionType)

[NextcacheSignal](/reference/react/cacheSignal)

***

----
url: https://react.dev/reference/eslint-plugin-react-hooks
----

[API Reference](/reference/react)

# eslint-plugin-react-hooks[](#undefined "Link for this heading")

`eslint-plugin-react-hooks` provides ESLint rules to enforce the [Rules of React](/reference/rules).

This plugin helps you catch violations of React’s rules at build time, ensuring your components and hooks follow React’s rules for correctness and performance. The lints cover both fundamental React patterns (exhaustive-deps and rules-of-hooks) and issues flagged by React Compiler. React Compiler diagnostics are automatically surfaced by this ESLint plugin, and can be used even if your app hasn’t adopted the compiler yet.

### Note

When the compiler reports a diagnostic, it means that the compiler was able to statically detect a pattern that is not supported or breaks the Rules of React. When it detects this, it **automatically** skips over those components and hooks, while keeping the rest of your app compiled. This ensures optimal coverage of safe optimizations that won’t break your app.

What this means for linting, is that you don’t need to fix all violations immediately. Address them at your own pace to gradually increase the number of optimized components.

## Recommended Rules[](#recommended "Link for Recommended Rules ")

These rules are included in the `recommended` preset in `eslint-plugin-react-hooks`:

* [`exhaustive-deps`](/reference/eslint-plugin-react-hooks/lints/exhaustive-deps) - Validates that dependency arrays for React hooks contain all necessary dependencies
* [`rules-of-hooks`](/reference/eslint-plugin-react-hooks/lints/rules-of-hooks) - Validates that components and hooks follow the Rules of Hooks
* [`component-hook-factories`](/reference/eslint-plugin-react-hooks/lints/component-hook-factories) - Validates higher order functions defining nested components or hooks
* [`config`](/reference/eslint-plugin-react-hooks/lints/config) - Validates the compiler configuration options
* [`error-boundaries`](/reference/eslint-plugin-react-hooks/lints/error-boundaries) - Validates usage of Error Boundaries instead of try/catch for child errors
* [`gating`](/reference/eslint-plugin-react-hooks/lints/gating) - Validates configuration of gating mode
* [`globals`](/reference/eslint-plugin-react-hooks/lints/globals) - Validates against assignment/mutation of globals during render
* [`immutability`](/reference/eslint-plugin-react-hooks/lints/immutability) - Validates against mutating props, state, and other immutable values
* [`incompatible-library`](/reference/eslint-plugin-react-hooks/lints/incompatible-library) - Validates against usage of libraries which are incompatible with memoization
* [`preserve-manual-memoization`](/reference/eslint-plugin-react-hooks/lints/preserve-manual-memoization) - Validates that existing manual memoization is preserved by the compiler
* [`purity`](/reference/eslint-plugin-react-hooks/lints/purity) - Validates that components/hooks are pure by checking known-impure functions
* [`refs`](/reference/eslint-plugin-react-hooks/lints/refs) - Validates correct usage of refs, not reading/writing during render
* [`set-state-in-effect`](/reference/eslint-plugin-react-hooks/lints/set-state-in-effect) - Validates against calling setState synchronously in an effect
* [`set-state-in-render`](/reference/eslint-plugin-react-hooks/lints/set-state-in-render) - Validates against setting state during render
* [`static-components`](/reference/eslint-plugin-react-hooks/lints/static-components) - Validates that components are static, not recreated every render
* [`unsupported-syntax`](/reference/eslint-plugin-react-hooks/lints/unsupported-syntax) - Validates against syntax that React Compiler does not support
* [`use-memo`](/reference/eslint-plugin-react-hooks/lints/use-memo) - Validates usage of the `useMemo` hook without a return value

[Nextexhaustive-deps](/reference/eslint-plugin-react-hooks/lints/exhaustive-deps)

***

----
url: https://react.dev/reference/react/Component
----

[API Reference](/reference/react)

[Legacy React APIs](/reference/react/legacy)

# Component[](#undefined "Link for this heading")

### Pitfall

We recommend defining components as functions instead of classes. [See how to migrate.](#alternatives)

`Component` is the base class for the React components defined as [JavaScript classes.](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes) Class components are still supported by React, but we don’t recommend using them in new code.

```
class Greeting extends Component {

  render() {

    return <h1>Hello, {this.props.name}!</h1>;

  }

}
```

* [Reference](#reference)

  * [`Component`](#component)
  * [`context`](#context)
  * [`props`](#props)
  * [`static contextType`](#static-contexttype)
  * [`static defaultProps`](#static-defaultprops)
  * [`static getDerivedStateFromError(error)`](#static-getderivedstatefromerror)
  * [`static getDerivedStateFromProps(props, state)`](#static-getderivedstatefromprops)

* [Usage](#usage)

  * [Defining a class component](#defining-a-class-component)
  * [Adding state to a class component](#adding-state-to-a-class-component)
  * [Adding lifecycle methods to a class component](#adding-lifecycle-methods-to-a-class-component)
  * [Catching rendering errors with an Error Boundary](#catching-rendering-errors-with-an-error-boundary)

* [Alternatives](#alternatives)

  * [Migrating a simple component from a class to a function](#migrating-a-simple-component-from-a-class-to-a-function)
  * [Migrating a component with state from a class to a function](#migrating-a-component-with-state-from-a-class-to-a-function)
  * [Migrating a component with lifecycle methods from a class to a function](#migrating-a-component-with-lifecycle-methods-from-a-class-to-a-function)
  * [Migrating a component with context from a class to a function](#migrating-a-component-with-context-from-a-class-to-a-function)

***

## Reference[](#reference "Link for Reference ")

### `Component`[](#component "Link for this heading")

To define a React component as a class, extend the built-in `Component` class and define a [`render` method:](#render)

```
import { Component } from 'react';



class Greeting extends Component {

  render() {

    return <h1>Hello, {this.props.name}!</h1>;

  }

}
```

Only the `render` method is required, other methods are optional.

[See more examples below.](#usage)

***

### `context`[](#context "Link for this heading")

The [context](/learn/passing-data-deeply-with-context) of a class component is available as `this.context`. It is only available if you specify *which* context you want to receive using [`static contextType`](#static-contexttype).

A class component can only read one context at a time.

```
class Button extends Component {

  static contextType = ThemeContext;



  render() {

    const theme = this.context;

    const className = 'button-' + theme;

    return (

      <button className={className}>

        {this.props.children}

      </button>

    );

  }

}
```

### Note

Reading `this.context` in class components is equivalent to [`useContext`](/reference/react/useContext) in function components.

[See how to migrate.](#migrating-a-component-with-context-from-a-class-to-a-function)

***

### `props`[](#props "Link for this heading")

The props passed to a class component are available as `this.props`.

```
class Greeting extends Component {

  render() {

    return <h1>Hello, {this.props.name}!</h1>;

  }

}



<Greeting name="Taylor" />
```

### Note

Reading `this.props` in class components is equivalent to [declaring props](/learn/passing-props-to-a-component#step-2-read-props-inside-the-child-component) in function components.

[See how to migrate.](#migrating-a-simple-component-from-a-class-to-a-function)

***

### `state`[](#state "Link for this heading")

The state of a class component is available as `this.state`. The `state` field must be an object. Do not mutate the state directly. If you wish to change the state, call `setState` with the new state.

```
class Counter extends Component {

  state = {

    age: 42,

  };



  handleAgeChange = () => {

    this.setState({

      age: this.state.age + 1

    });

  };



  render() {

    return (

      <>

        <button onClick={this.handleAgeChange}>

        Increment age

        </button>

        <p>You are {this.state.age}.</p>

      </>

    );

  }

}
```

### Note

Defining `state` in class components is equivalent to calling [`useState`](/reference/react/useState) in function components.

[See how to migrate.](#migrating-a-component-with-state-from-a-class-to-a-function)

***

### `constructor(props)`[](#constructor "Link for this heading")

The [constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/constructor) runs before your class component *mounts* (gets added to the screen). Typically, a constructor is only used for two purposes in React. It lets you declare state and [bind](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Function/bind) your class methods to the class instance:

```
class Counter extends Component {

  constructor(props) {

    super(props);

    this.state = { counter: 0 };

    this.handleClick = this.handleClick.bind(this);

  }



  handleClick() {

    // ...

  }
```

If you use modern JavaScript syntax, constructors are rarely needed. Instead, you can rewrite this code above using the [public class field syntax](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Public_class_fields) which is supported both by modern browsers and tools like [Babel:](https://babeljs.io/)

```
class Counter extends Component {

  state = { counter: 0 };



  handleClick = () => {

    // ...

  }
```

***

### `componentDidCatch(error, info)`[](#componentdidcatch "Link for this heading")

If you define `componentDidCatch`, React will call it when some child component (including distant children) throws an error during rendering. This lets you log that error to an error reporting service in production.

Typically, it is used together with [`static getDerivedStateFromError`](#static-getderivedstatefromerror) which lets you update state in response to an error and display an error message to the user. A component with these methods is called an *Error Boundary*.

***

### `componentDidMount()`[](#componentdidmount "Link for this heading")

If you define the `componentDidMount` method, React will call it when your component is added *(mounted)* to the screen. This is a common place to start data fetching, set up subscriptions, or manipulate the DOM nodes.

If you implement `componentDidMount`, you usually need to implement other lifecycle methods to avoid bugs. For example, if `componentDidMount` reads some state or props, you also have to implement [`componentDidUpdate`](#componentdidupdate) to handle their changes, and [`componentWillUnmount`](#componentwillunmount) to clean up whatever `componentDidMount` was doing.

```
class ChatRoom extends Component {

  state = {

    serverUrl: 'https://localhost:1234'

  };



  componentDidMount() {

    this.setupConnection();

  }



  componentDidUpdate(prevProps, prevState) {

    if (

      this.props.roomId !== prevProps.roomId ||

      this.state.serverUrl !== prevState.serverUrl

    ) {

      this.destroyConnection();

      this.setupConnection();

    }

  }



  componentWillUnmount() {

    this.destroyConnection();

  }



  // ...

}
```

***

### `componentDidUpdate(prevProps, prevState, snapshot?)`[](#componentdidupdate "Link for this heading")

If you define the `componentDidUpdate` method, React will call it immediately after your component has been re-rendered with updated props or state. This method is not called for the initial render.

You can use it to manipulate the DOM after an update. This is also a common place to do network requests as long as you compare the current props to previous props (e.g. a network request may not be necessary if the props have not changed). Typically, you’d use it together with [`componentDidMount`](#componentdidmount) and [`componentWillUnmount`:](#componentwillunmount)

```
class ChatRoom extends Component {

  state = {

    serverUrl: 'https://localhost:1234'

  };



  componentDidMount() {

    this.setupConnection();

  }



  componentDidUpdate(prevProps, prevState) {

    if (

      this.props.roomId !== prevProps.roomId ||

      this.state.serverUrl !== prevState.serverUrl

    ) {

      this.destroyConnection();

      this.setupConnection();

    }

  }



  componentWillUnmount() {

    this.destroyConnection();

  }



  // ...

}
```

***

### `componentWillMount()`[](#componentwillmount "Link for this heading")

### Deprecated

This API has been renamed from `componentWillMount` to [`UNSAFE_componentWillMount`.](#unsafe_componentwillmount) The old name has been deprecated. In a future major version of React, only the new name will work.

Run the [`rename-unsafe-lifecycles` codemod](https://github.com/reactjs/react-codemod#rename-unsafe-lifecycles) to automatically update your components.

***

### `componentWillReceiveProps(nextProps)`[](#componentwillreceiveprops "Link for this heading")

### Deprecated

This API has been renamed from `componentWillReceiveProps` to [`UNSAFE_componentWillReceiveProps`.](#unsafe_componentwillreceiveprops) The old name has been deprecated. In a future major version of React, only the new name will work.

Run the [`rename-unsafe-lifecycles` codemod](https://github.com/reactjs/react-codemod#rename-unsafe-lifecycles) to automatically update your components.

***

### `componentWillUpdate(nextProps, nextState)`[](#componentwillupdate "Link for this heading")

### Deprecated

This API has been renamed from `componentWillUpdate` to [`UNSAFE_componentWillUpdate`.](#unsafe_componentwillupdate) The old name has been deprecated. In a future major version of React, only the new name will work.

Run the [`rename-unsafe-lifecycles` codemod](https://github.com/reactjs/react-codemod#rename-unsafe-lifecycles) to automatically update your components.

***

### `componentWillUnmount()`[](#componentwillunmount "Link for this heading")

If you define the `componentWillUnmount` method, React will call it before your component is removed *(unmounted)* from the screen. This is a common place to cancel data fetching or remove subscriptions.

The logic inside `componentWillUnmount` should “mirror” the logic inside [`componentDidMount`.](#componentdidmount) For example, if `componentDidMount` sets up a subscription, `componentWillUnmount` should clean up that subscription. If the cleanup logic in your `componentWillUnmount` reads some props or state, you will usually also need to implement [`componentDidUpdate`](#componentdidupdate) to clean up resources (such as subscriptions) corresponding to the old props and state.

```
class ChatRoom extends Component {

  state = {

    serverUrl: 'https://localhost:1234'

  };



  componentDidMount() {

    this.setupConnection();

  }



  componentDidUpdate(prevProps, prevState) {

    if (

      this.props.roomId !== prevProps.roomId ||

      this.state.serverUrl !== prevState.serverUrl

    ) {

      this.destroyConnection();

      this.setupConnection();

    }

  }



  componentWillUnmount() {

    this.destroyConnection();

  }



  // ...

}
```

***

***

### `getSnapshotBeforeUpdate(prevProps, prevState)`[](#getsnapshotbeforeupdate "Link for this heading")

If you implement `getSnapshotBeforeUpdate`, React will call it immediately before React updates the DOM. It enables your component to capture some information from the DOM (e.g. scroll position) before it is potentially changed. Any value returned by this lifecycle method will be passed as a parameter to [`componentDidUpdate`.](#componentdidupdate)

For example, you can use it in a UI like a chat thread that needs to preserve its scroll position during updates:

```
class ScrollingList extends React.Component {

  constructor(props) {

    super(props);

    this.listRef = React.createRef();

  }



  getSnapshotBeforeUpdate(prevProps, prevState) {

    // Are we adding new items to the list?

    // Capture the scroll position so we can adjust scroll later.

    if (prevProps.list.length < this.props.list.length) {

      const list = this.listRef.current;

      return list.scrollHeight - list.scrollTop;

    }

    return null;

  }



  componentDidUpdate(prevProps, prevState, snapshot) {

    // If we have a snapshot value, we've just added new items.

    // Adjust scroll so these new items don't push the old ones out of view.

    // (snapshot here is the value returned from getSnapshotBeforeUpdate)

    if (snapshot !== null) {

      const list = this.listRef.current;

      list.scrollTop = list.scrollHeight - snapshot;

    }

  }



  render() {

    return (

      <div ref={this.listRef}>{/* ...contents... */}</div>

    );

  }

}
```

***

### `render()`[](#render "Link for this heading")

The `render` method is the only required method in a class component.

The `render` method should specify what you want to appear on the screen, for example:

```
import { Component } from 'react';



class Greeting extends Component {

  render() {

    return <h1>Hello, {this.props.name}!</h1>;

  }

}
```

***

### `setState(nextState, callback?)`[](#setstate "Link for this heading")

Call `setState` to update the state of your React component.

```
class Form extends Component {

  state = {

    name: 'Taylor',

  };



  handleNameChange = (e) => {

    const newName = e.target.value;

    this.setState({

      name: newName

    });

  }



  render() {

    return (

      <>

        <input value={this.state.name} onChange={this.handleNameChange} />

        <p>Hello, {this.state.name}.</p>

      </>

    );

  }

}
```

`setState` enqueues changes to the component state. It tells React that this component and its children need to re-render with the new state. This is the main way you’ll update the user interface in response to interactions.

### Pitfall

Calling `setState` **does not** change the current state in the already executing code:

```
function handleClick() {

  console.log(this.state.name); // "Taylor"

  this.setState({

    name: 'Robin'

  });

  console.log(this.state.name); // Still "Taylor"!

}
```

It only affects what `this.state` will return starting from the *next* render.

You can also pass a function to `setState`. It lets you update state based on the previous state:

```
  handleIncreaseAge = () => {

    this.setState(prevState => {

      return {

        age: prevState.age + 1

      };

    });

  }
```

***

### `shouldComponentUpdate(nextProps, nextState, nextContext)`[](#shouldcomponentupdate "Link for this heading")

If you define `shouldComponentUpdate`, React will call it to determine whether a re-render can be skipped.

If you are confident you want to write it by hand, you may compare `this.props` with `nextProps` and `this.state` with `nextState` and return `false` to tell React the update can be skipped.

```
class Rectangle extends Component {

  state = {

    isHovered: false

  };



  shouldComponentUpdate(nextProps, nextState) {

    if (

      nextProps.position.x === this.props.position.x &&

      nextProps.position.y === this.props.position.y &&

      nextProps.size.width === this.props.size.width &&

      nextProps.size.height === this.props.size.height &&

      nextState.isHovered === this.state.isHovered

    ) {

      // Nothing has changed, so a re-render is unnecessary

      return false;

    }

    return true;

  }



  // ...

}
```

React calls `shouldComponentUpdate` before rendering when new props or state are being received. Defaults to `true`. This method is not called for the initial render or when [`forceUpdate`](#forceupdate) is used.

#### Parameters[](#shouldcomponentupdate-parameters "Link for Parameters ")

* `nextProps`: The next props that the component is about to render with. Compare `nextProps` to [`this.props`](#props) to determine what changed.
* `nextState`: The next state that the component is about to render with. Compare `nextState` to [`this.state`](#props) to determine what changed.
* `nextContext`: The next context that the component is about to render with. Compare `nextContext` to [`this.context`](#context) to determine what changed. Only available if you specify [`static contextType`](#static-contexttype).

***

***

* `nextContext`: The next context that the component is about to receive from the closest provider. Compare `nextContext` to [`this.context`](#context) to determine what changed. Only available if you specify [`static contextType`](#static-contexttype).

***

***

### `static contextType`[](#static-contexttype "Link for this heading")

If you want to read [`this.context`](#context-instance-field) from your class component, you must specify which context it needs to read. The context you specify as the `static contextType` must be a value previously created by [`createContext`.](/reference/react/createContext)

```
class Button extends Component {

  static contextType = ThemeContext;



  render() {

    const theme = this.context;

    const className = 'button-' + theme;

    return (

      <button className={className}>

        {this.props.children}

      </button>

    );

  }

}
```

### Note

Reading `this.context` in class components is equivalent to [`useContext`](/reference/react/useContext) in function components.

[See how to migrate.](#migrating-a-component-with-context-from-a-class-to-a-function)

***

### `static defaultProps`[](#static-defaultprops "Link for this heading")

You can define `static defaultProps` to set the default props for the class. They will be used for `undefined` and missing props, but not for `null` props.

For example, here is how you define that the `color` prop should default to `'blue'`:

```
class Button extends Component {

  static defaultProps = {

    color: 'blue'

  };



  render() {

    return <button className={this.props.color}>click me</button>;

  }

}
```

If the `color` prop is not provided or is `undefined`, it will be set by default to `'blue'`:

```
<>

  {/* this.props.color is "blue" */}

  <Button />



  {/* this.props.color is "blue" */}

  <Button color={undefined} />



  {/* this.props.color is null */}

  <Button color={null} />



  {/* this.props.color is "red" */}

  <Button color="red" />

</>
```

### Note

Defining `defaultProps` in class components is similar to using [default values](/learn/passing-props-to-a-component#specifying-a-default-value-for-a-prop) in function components.

***

### `static getDerivedStateFromError(error)`[](#static-getderivedstatefromerror "Link for this heading")

If you define `static getDerivedStateFromError`, React will call it when a child component (including distant children) throws an error during rendering. This lets you display an error message instead of clearing the UI.

Typically, it is used together with [`componentDidCatch`](#componentdidcatch) which lets you send the error report to some analytics service. A component with these methods is called an *Error Boundary*.

***

### `static getDerivedStateFromProps(props, state)`[](#static-getderivedstatefromprops "Link for this heading")

If you define `static getDerivedStateFromProps`, React will call it right before calling [`render`,](#render) both on the initial mount and on subsequent updates. It should return an object to update the state, or `null` to update nothing.

This method exists for [rare use cases](https://legacy.reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#when-to-use-derived-state) where the state depends on changes in props over time. For example, this `Form` component resets the `email` state when the `userID` prop changes:

```
class Form extends Component {

  state = {

    email: this.props.defaultEmail,

    prevUserID: this.props.userID

  };



  static getDerivedStateFromProps(props, state) {

    // Any time the current user changes,

    // Reset any parts of state that are tied to that user.

    // In this simple example, that's just the email.

    if (props.userID !== state.prevUserID) {

      return {

        prevUserID: props.userID,

        email: props.defaultEmail

      };

    }

    return null;

  }



  // ...

}
```

***

## Usage[](#usage "Link for Usage ")

### Defining a class component[](#defining-a-class-component "Link for Defining a class component ")

To define a React component as a class, extend the built-in `Component` class and define a [`render` method:](#render)

```
import { Component } from 'react';



class Greeting extends Component {

  render() {

    return <h1>Hello, {this.props.name}!</h1>;

  }

}
```

React will call your [`render`](#render) method whenever it needs to figure out what to display on the screen. Usually, you will return some [JSX](/learn/writing-markup-with-jsx) from it. Your `render` method should be a [pure function:](https://en.wikipedia.org/wiki/Pure_function) it should only calculate the JSX.

Similarly to [function components,](/learn/your-first-component#defining-a-component) a class component can [receive information by props](/learn/your-first-component#defining-a-component) from its parent component. However, the syntax for reading props is different. For example, if the parent component renders `<Greeting name="Taylor" />`, then you can read the `name` prop from [`this.props`](#props), like `this.props.name`:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { Component } from 'react';

class Greeting extends Component {
  render() {
    return <h1>Hello, {this.props.name}!</h1>;
  }
}

export default function App() {
  return (
    <>
      <Greeting name="Sara" />
      <Greeting name="Cahal" />
      <Greeting name="Edite" />
    </>
  );
}
```

Note that Hooks (functions starting with `use`, like [`useState`](/reference/react/useState)) are not supported inside class components.

### Pitfall

We recommend defining components as functions instead of classes. [See how to migrate.](#migrating-a-simple-component-from-a-class-to-a-function)

***

### Adding state to a class component[](#adding-state-to-a-class-component "Link for Adding state to a class component ")

To add [state](/learn/state-a-components-memory) to a class, assign an object to a property called [`state`](#state). To update state, call [`this.setState`](#setstate).

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { Component } from 'react';

export default class Counter extends Component {
  state = {
    name: 'Taylor',
    age: 42,
  };

  handleNameChange = (e) => {
    this.setState({
      name: e.target.value
    });
  }

  handleAgeChange = () => {
    this.setState({
      age: this.state.age + 1
    });
  };

  render() {
    return (
      <>
        <input
          value={this.state.name}
          onChange={this.handleNameChange}
        />
        <button onClick={this.handleAgeChange}>
          Increment age
        </button>
        <p>Hello, {this.state.name}. You are {this.state.age}.</p>
      </>
    );
  }
}
```

### Pitfall

We recommend defining components as functions instead of classes. [See how to migrate.](#migrating-a-component-with-state-from-a-class-to-a-function)

***

### Adding lifecycle methods to a class component[](#adding-lifecycle-methods-to-a-class-component "Link for Adding lifecycle methods to a class component ")

There are a few special methods you can define on your class.

If you define the [`componentDidMount`](#componentdidmount) method, React will call it when your component is added *(mounted)* to the screen. React will call [`componentDidUpdate`](#componentdidupdate) after your component re-renders due to changed props or state. React will call [`componentWillUnmount`](#componentwillunmount) after your component has been removed *(unmounted)* from the screen.

If you implement `componentDidMount`, you usually need to implement all three lifecycles to avoid bugs. For example, if `componentDidMount` reads some state or props, you also have to implement `componentDidUpdate` to handle their changes, and `componentWillUnmount` to clean up whatever `componentDidMount` was doing.

For example, this `ChatRoom` component keeps a chat connection synchronized with props and state:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { Component } from 'react';
import { createConnection } from './chat.js';

export default class ChatRoom extends Component {
  state = {
    serverUrl: 'https://localhost:1234'
  };

  componentDidMount() {
    this.setupConnection();
  }

  componentDidUpdate(prevProps, prevState) {
    if (
      this.props.roomId !== prevProps.roomId ||
      this.state.serverUrl !== prevState.serverUrl
    ) {
      this.destroyConnection();
      this.setupConnection();
    }
  }

  componentWillUnmount() {
    this.destroyConnection();
  }

  setupConnection() {
    this.connection = createConnection(
      this.state.serverUrl,
      this.props.roomId
    );
    this.connection.connect();
  }

  destroyConnection() {
    this.connection.disconnect();
    this.connection = null;
  }

  render() {
    return (
      <>
        <label>
          Server URL:{' '}
          <input
            value={this.state.serverUrl}
            onChange={e => {
              this.setState({
                serverUrl: e.target.value
              });
            }}
          />
        </label>
        <h1>Welcome to the {this.props.roomId} room!</h1>
      </>
    );
  }
}
```

Note that in development when [Strict Mode](/reference/react/StrictMode) is on, React will call `componentDidMount`, immediately call `componentWillUnmount`, and then call `componentDidMount` again. This helps you notice if you forgot to implement `componentWillUnmount` or if its logic doesn’t fully “mirror” what `componentDidMount` does.

### Pitfall

We recommend defining components as functions instead of classes. [See how to migrate.](#migrating-a-component-with-lifecycle-methods-from-a-class-to-a-function)

***

### Catching rendering errors with an Error Boundary[](#catching-rendering-errors-with-an-error-boundary "Link for Catching rendering errors with an Error Boundary ")

By default, if your application throws an error during rendering, React will remove its UI from the screen. To prevent this, you can wrap a part of your UI into an *Error Boundary*. An Error Boundary is a special component that lets you display some fallback UI instead of the part that crashed—for example, an error message.

### Note

Error boundaries do not catch errors for:

* Event handlers [(learn more)](/learn/responding-to-events)
* [Server side rendering](/reference/react-dom/server)
* Errors thrown in the error boundary itself (rather than its children)
* Asynchronous code (e.g. `setTimeout` or `requestAnimationFrame` callbacks); an exception is the usage of the [`startTransition`](/reference/react/useTransition#starttransition) function returned by the [`useTransition`](/reference/react/useTransition) Hook. Errors thrown inside the transition function are caught by error boundaries [(learn more)](/reference/react/useTransition#displaying-an-error-to-users-with-error-boundary)

To implement an Error Boundary component, you need to provide [`static getDerivedStateFromError`](#static-getderivedstatefromerror) which lets you update state in response to an error and display an error message to the user. You can also optionally implement [`componentDidCatch`](#componentdidcatch) to add some extra logic, for example, to log the error to an analytics service.

With [`captureOwnerStack`](/reference/react/captureOwnerStack) you can include the Owner Stack during development.

```
import * as React from 'react';



class ErrorBoundary extends React.Component {

  constructor(props) {

    super(props);

    this.state = { hasError: false };

  }



  static getDerivedStateFromError(error) {

    // Update state so the next render will show the fallback UI.

    return { hasError: true };

  }



  componentDidCatch(error, info) {

    logErrorToMyService(

      error,

      // Example "componentStack":

      //   in ComponentThatThrows (created by App)

      //   in ErrorBoundary (created by App)

      //   in div (created by App)

      //   in App

      info.componentStack,

      // Warning: `captureOwnerStack` is not available in production.

      React.captureOwnerStack(),

    );

  }



  render() {

    if (this.state.hasError) {

      // You can render any custom fallback UI

      return this.props.fallback;

    }



    return this.props.children;

  }

}
```

Then you can wrap a part of your component tree with it:

```
<ErrorBoundary fallback={<p>Something went wrong</p>}>

  <Profile />

</ErrorBoundary>
```

If `Profile` or its child component throws an error, `ErrorBoundary` will “catch” that error, display a fallback UI with the error message you’ve provided, and send a production error report to your error reporting service.

You don’t need to wrap every component into a separate Error Boundary. When you think about the [granularity of Error Boundaries,](https://www.brandondail.com/posts/fault-tolerance-react) consider where it makes sense to display an error message. For example, in a messaging app, it makes sense to place an Error Boundary around the list of conversations. It also makes sense to place one around every individual message. However, it wouldn’t make sense to place a boundary around every avatar.

### Note

There is currently no way to write an Error Boundary as a function component. However, you don’t have to write the Error Boundary class yourself. For example, you can use [`react-error-boundary`](https://github.com/bvaughn/react-error-boundary) instead.

***

## Alternatives[](#alternatives "Link for Alternatives ")

### Migrating a simple component from a class to a function[](#migrating-a-simple-component-from-a-class-to-a-function "Link for Migrating a simple component from a class to a function ")

Typically, you will [define components as functions](/learn/your-first-component#defining-a-component) instead.

For example, suppose you’re converting this `Greeting` class component to a function:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { Component } from 'react';

class Greeting extends Component {
  render() {
    return <h1>Hello, {this.props.name}!</h1>;
  }
}

export default function App() {
  return (
    <>
      <Greeting name="Sara" />
      <Greeting name="Cahal" />
      <Greeting name="Edite" />
    </>
  );
}
```

Define a function called `Greeting`. This is where you will move the body of your `render` function.

```
function Greeting() {

  // ... move the code from the render method here ...

}
```

Instead of `this.props.name`, define the `name` prop [using the destructuring syntax](/learn/passing-props-to-a-component) and read it directly:

```
function Greeting({ name }) {

  return <h1>Hello, {name}!</h1>;

}
```

Here is a complete example:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
function Greeting({ name }) {
  return <h1>Hello, {name}!</h1>;
}

export default function App() {
  return (
    <>
      <Greeting name="Sara" />
      <Greeting name="Cahal" />
      <Greeting name="Edite" />
    </>
  );
}
```

***

### Migrating a component with state from a class to a function[](#migrating-a-component-with-state-from-a-class-to-a-function "Link for Migrating a component with state from a class to a function ")

Suppose you’re converting this `Counter` class component to a function:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { Component } from 'react';

export default class Counter extends Component {
  state = {
    name: 'Taylor',
    age: 42,
  };

  handleNameChange = (e) => {
    this.setState({
      name: e.target.value
    });
  }

  handleAgeChange = (e) => {
    this.setState({
      age: this.state.age + 1
    });
  };

  render() {
    return (
      <>
        <input
          value={this.state.name}
          onChange={this.handleNameChange}
        />
        <button onClick={this.handleAgeChange}>
          Increment age
        </button>
        <p>Hello, {this.state.name}. You are {this.state.age}.</p>
      </>
    );
  }
}
```

Start by declaring a function with the necessary [state variables:](/reference/react/useState#adding-state-to-a-component)

```
import { useState } from 'react';



function Counter() {

  const [name, setName] = useState('Taylor');

  const [age, setAge] = useState(42);

  // ...
```

Next, convert the event handlers:

```
function Counter() {

  const [name, setName] = useState('Taylor');

  const [age, setAge] = useState(42);



  function handleNameChange(e) {

    setName(e.target.value);

  }



  function handleAgeChange() {

    setAge(age + 1);

  }

  // ...
```

Finally, replace all references starting with `this` with the variables and functions you defined in your component. For example, replace `this.state.age` with `age`, and replace `this.handleNameChange` with `handleNameChange`.

Here is a fully converted component:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function Counter() {
  const [name, setName] = useState('Taylor');
  const [age, setAge] = useState(42);

  function handleNameChange(e) {
    setName(e.target.value);
  }

  function handleAgeChange() {
    setAge(age + 1);
  }

  return (
    <>
      <input
        value={name}
        onChange={handleNameChange}
      />
      <button onClick={handleAgeChange}>
        Increment age
      </button>
      <p>Hello, {name}. You are {age}.</p>
    </>
  )
}
```

***

### Migrating a component with lifecycle methods from a class to a function[](#migrating-a-component-with-lifecycle-methods-from-a-class-to-a-function "Link for Migrating a component with lifecycle methods from a class to a function ")

Suppose you’re converting this `ChatRoom` class component with lifecycle methods to a function:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { Component } from 'react';
import { createConnection } from './chat.js';

export default class ChatRoom extends Component {
  state = {
    serverUrl: 'https://localhost:1234'
  };

  componentDidMount() {
    this.setupConnection();
  }

  componentDidUpdate(prevProps, prevState) {
    if (
      this.props.roomId !== prevProps.roomId ||
      this.state.serverUrl !== prevState.serverUrl
    ) {
      this.destroyConnection();
      this.setupConnection();
    }
  }

  componentWillUnmount() {
    this.destroyConnection();
  }

  setupConnection() {
    this.connection = createConnection(
      this.state.serverUrl,
      this.props.roomId
    );
    this.connection.connect();
  }

  destroyConnection() {
    this.connection.disconnect();
    this.connection = null;
  }

  render() {
    return (
      <>
        <label>
          Server URL:{' '}
          <input
            value={this.state.serverUrl}
            onChange={e => {
              this.setState({
                serverUrl: e.target.value
              });
            }}
          />
        </label>
        <h1>Welcome to the {this.props.roomId} room!</h1>
      </>
    );
  }
}
```

First, verify that your [`componentWillUnmount`](#componentwillunmount) does the opposite of [`componentDidMount`.](#componentdidmount) In the above example, that’s true: it disconnects the connection that `componentDidMount` sets up. If such logic is missing, add it first.

Next, verify that your [`componentDidUpdate`](#componentdidupdate) method handles changes to any props and state you’re using in `componentDidMount`. In the above example, `componentDidMount` calls `setupConnection` which reads `this.state.serverUrl` and `this.props.roomId`. This is why `componentDidUpdate` checks whether `this.state.serverUrl` and `this.props.roomId` have changed, and resets the connection if they did. If your `componentDidUpdate` logic is missing or doesn’t handle changes to all relevant props and state, fix that first.

In the above example, the logic inside the lifecycle methods connects the component to a system outside of React (a chat server). To connect a component to an external system, [describe this logic as a single Effect:](/reference/react/useEffect#connecting-to-an-external-system)

```
import { useState, useEffect } from 'react';



function ChatRoom({ roomId }) {

  const [serverUrl, setServerUrl] = useState('https://localhost:1234');



  useEffect(() => {

    const connection = createConnection(serverUrl, roomId);

    connection.connect();

    return () => {

      connection.disconnect();

    };

  }, [serverUrl, roomId]);



  // ...

}
```

This [`useEffect`](/reference/react/useEffect) call is equivalent to the logic in the lifecycle methods above. If your lifecycle methods do multiple unrelated things, [split them into multiple independent Effects.](/learn/removing-effect-dependencies#is-your-effect-doing-several-unrelated-things) Here is a complete example you can play with:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useEffect } from 'react';
import { createConnection } from './chat.js';

export default function ChatRoom({ roomId }) {
  const [serverUrl, setServerUrl] = useState('https://localhost:1234');

  useEffect(() => {
    const connection = createConnection(serverUrl, roomId);
    connection.connect();
    return () => {
      connection.disconnect();
    };
  }, [roomId, serverUrl]);

  return (
    <>
      <label>
        Server URL:{' '}
        <input
          value={serverUrl}
          onChange={e => setServerUrl(e.target.value)}
        />
      </label>
      <h1>Welcome to the {roomId} room!</h1>
    </>
  );
}
```

### Note

If your component does not synchronize with any external systems, [you might not need an Effect.](/learn/you-might-not-need-an-effect)

***

### Migrating a component with context from a class to a function[](#migrating-a-component-with-context-from-a-class-to-a-function "Link for Migrating a component with context from a class to a function ")

In this example, the `Panel` and `Button` class components read [context](/learn/passing-data-deeply-with-context) from [`this.context`:](#context)

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { createContext, Component } from 'react';

const ThemeContext = createContext(null);

class Panel extends Component {
  static contextType = ThemeContext;

  render() {
    const theme = this.context;
    const className = 'panel-' + theme;
    return (
      <section className={className}>
        <h1>{this.props.title}</h1>
        {this.props.children}
      </section>
    );
  }
}

class Button extends Component {
  static contextType = ThemeContext;

  render() {
    const theme = this.context;
    const className = 'button-' + theme;
    return (
      <button className={className}>
        {this.props.children}
      </button>
    );
  }
}

function Form() {
  return (
    <Panel title="Welcome">
      <Button>Sign up</Button>
      <Button>Log in</Button>
    </Panel>
  );
}

export default function MyApp() {
  return (
    <ThemeContext value="dark">
      <Form />
    </ThemeContext>
  )
}
```

When you convert them to function components, replace `this.context` with [`useContext`](/reference/react/useContext) calls:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { createContext, useContext } from 'react';

const ThemeContext = createContext(null);

function Panel({ title, children }) {
  const theme = useContext(ThemeContext);
  const className = 'panel-' + theme;
  return (
    <section className={className}>
      <h1>{title}</h1>
      {children}
    </section>
  )
}

function Button({ children }) {
  const theme = useContext(ThemeContext);
  const className = 'button-' + theme;
  return (
    <button className={className}>
      {children}
    </button>
  );
}

function Form() {
  return (
    <Panel title="Welcome">
      <Button>Sign up</Button>
      <Button>Log in</Button>
    </Panel>
  );
}

export default function MyApp() {
  return (
    <ThemeContext value="dark">
      <Form />
    </ThemeContext>
  )
}
```

[PreviouscloneElement](/reference/react/cloneElement)

[NextcreateElement](/reference/react/createElement)

***

----
url: https://react.dev/reference/react-compiler/target
----

[API Reference](/reference/react)

[Configuration](/reference/react-compiler/configuration)

# target[](#undefined "Link for this heading")

The `target` option specifies which React version the compiler should generate code for.

```
{

  target: '19' // or '18', '17'

}
```

* [Reference](#reference)
  * [`target`](#target)

* [Usage](#usage)

  * [Targeting React 19 (default)](#targeting-react-19)
  * [Targeting React 17 or 18](#targeting-react-17-or-18)

* [Troubleshooting](#troubleshooting)

  * [Runtime errors about missing compiler runtime](#missing-runtime)
  * [Runtime package not working](#runtime-not-working)
  * [Checking compiled output](#checking-output)

***

## Reference[](#reference "Link for Reference ")

### `target`[](#target "Link for this heading")

Configures the React version compatibility for the compiled output.

#### Type[](#type "Link for Type ")

```
'17' | '18' | '19'
```

#### Default value[](#default-value "Link for Default value ")

`'19'`

#### Valid values[](#valid-values "Link for Valid values ")

* **`'19'`**: Target React 19 (default). No additional runtime required.
* **`'18'`**: Target React 18. Requires `react-compiler-runtime` package.
* **`'17'`**: Target React 17. Requires `react-compiler-runtime` package.

#### Caveats[](#caveats "Link for Caveats ")

* Always use string values, not numbers (e.g., `'17'` not `17`)
* Don’t include patch versions (e.g., use `'18'` not `'18.2.0'`)
* React 19 includes built-in compiler runtime APIs
* React 17 and 18 require installing `react-compiler-runtime@latest`

***

## Usage[](#usage "Link for Usage ")

### Targeting React 19 (default)[](#targeting-react-19 "Link for Targeting React 19 (default) ")

For React 19, no special configuration is needed:

```
{

  // defaults to target: '19'

}
```

The compiler will use React 19’s built-in runtime APIs:

```
// Compiled output uses React 19's native APIs

import { c as _c } from 'react/compiler-runtime';
```

### Targeting React 17 or 18[](#targeting-react-17-or-18 "Link for Targeting React 17 or 18 ")

For React 17 and React 18 projects, you need two steps:

1. Install the runtime package:

```
npm install react-compiler-runtime@latest
```

2. Configure the target:

```
// For React 18

{

  target: '18'

}



// For React 17

{

  target: '17'

}
```

The compiler will use the polyfill runtime for both versions:

```
// Compiled output uses the polyfill

import { c as _c } from 'react-compiler-runtime';
```

***

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### Runtime errors about missing compiler runtime[](#missing-runtime "Link for Runtime errors about missing compiler runtime ")

If you see errors like “Cannot find module ‘react/compiler-runtime’“:

1. Check your React version:

   ```
   npm why react
   ```

2. If using React 17 or 18, install the runtime:

   ```
   npm install react-compiler-runtime@latest
   ```

3. Ensure your target matches your React version:

   ```
   {

     target: '18' // Must match your React major version

   }
   ```

### Runtime package not working[](#runtime-not-working "Link for Runtime package not working ")

Ensure the runtime package is:

1. Installed in your project (not globally)
2. Listed in your `package.json` dependencies
3. The correct version (`@latest` tag)
4. Not in `devDependencies` (it’s needed at runtime)

### Checking compiled output[](#checking-output "Link for Checking compiled output ")

To verify the correct runtime is being used, note the different import (`react/compiler-runtime` for builtin, `react-compiler-runtime` standalone package for 17/18):

```
// For React 19 (built-in runtime)

import { c } from 'react/compiler-runtime'

//                      ^



// For React 17/18 (polyfill runtime)

import { c } from 'react-compiler-runtime'

//                      ^
```

[PreviouspanicThreshold](/reference/react-compiler/panicThreshold)

[NextDirectives](/reference/react-compiler/directives)

***

----
url: https://18.react.dev/reference/react-dom/components/link
----

[API Reference](/reference/react)

[Components](/reference/react-dom/components)

# \<link>[](#undefined "Link for this heading")

### Canary

React’s extensions to `<link>` are currently only available in React’s canary and experimental channels. In stable releases of React `<link>` works only as a [built-in browser HTML component](https://react.dev/reference/react-dom/components#all-html-components). Learn more about [React’s release channels here](/community/versioning-policy#all-release-channels).

The [built-in browser `<link>` component](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link) lets you use external resources such as stylesheets or annotate the document with link metadata.

```
<link rel="icon" href="favicon.ico" />
```

***

## Reference[](#reference "Link for Reference ")

### `<link>`[](#link "Link for this heading")

To link to external resources such as stylesheets, fonts, and icons, or to annotate the document with link metadata, render the [built-in browser `<link>` component](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link). You can render `<link>` from any component and React will [in most cases](#special-rendering-behavior) place the corresponding DOM element in the document head.

```
<link rel="icon" href="favicon.ico" />
```

[See more examples below.](#usage)

#### Props[](#props "Link for Props ")

`<link>` supports all [common element props.](/reference/react-dom/components/common#props)

***

## Usage[](#usage "Link for Usage ")

### Linking to related resources[](#linking-to-related-resources "Link for Linking to related resources ")

You can annotate the document with links to related resources such as an icon, canonical URL, or pingback. React will place this metadata within the document `<head>` regardless of where in the React tree it is rendered.

```
import ShowRenderedHTML from './ShowRenderedHTML.js';

export default function BlogPage() {
  return (
    <ShowRenderedHTML>
      <link rel="icon" href="favicon.ico" />
      <link rel="pingback" href="http://www.example.com/xmlrpc.php" />
      <h1>My Blog</h1>
      <p>...</p>
    </ShowRenderedHTML>
  );
}
```

### Linking to a stylesheet[](#linking-to-a-stylesheet "Link for Linking to a stylesheet ")

If a component depends on a certain stylesheet in order to be displayed correctly, you can render a link to that stylesheet within the component. Your component will [suspend](/reference/react/Suspense) while the stylesheet is loading. You must supply the `precedence` prop, which tells React where to place this stylesheet relative to others — stylesheets with higher precedence can override those with lower precedence.

### Note

When you want to use a stylesheet, it can be beneficial to call the [preinit](/reference/react-dom/preinit) function. Calling this function may allow the browser to start fetching the stylesheet earlier than if you just render a `<link>` component, for example by sending an [HTTP Early Hints response](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/103).

```
import ShowRenderedHTML from './ShowRenderedHTML.js';

export default function SiteMapPage() {
  return (
    <ShowRenderedHTML>
      <link rel="stylesheet" href="sitemap.css" precedence="medium" />
      <p>...</p>
    </ShowRenderedHTML>
  );
}
```

### Controlling stylesheet precedence[](#controlling-stylesheet-precedence "Link for Controlling stylesheet precedence ")

Stylesheets can conflict with each other, and when they do, the browser goes with the one that comes later in the document. React lets you control the order of stylesheets with the `precedence` prop. In this example, two components render stylesheets, and the one with the higher precedence goes later in the document even though the component that renders it comes earlier.

```
import ShowRenderedHTML from './ShowRenderedHTML.js';

export default function HomePage() {
  return (
    <ShowRenderedHTML>
      <FirstComponent />
      <SecondComponent />
      ...
    </ShowRenderedHTML>
  );
}

function FirstComponent() {
  return <link rel="stylesheet" href="first.css" precedence="high" />;
}

function SecondComponent() {
  return <link rel="stylesheet" href="second.css" precedence="low" />;
}
```

### Deduplicated stylesheet rendering[](#deduplicated-stylesheet-rendering "Link for Deduplicated stylesheet rendering ")

If you render the same stylesheet from multiple components, React will place only a single `<link>` in the document head.

```
import ShowRenderedHTML from './ShowRenderedHTML.js';

export default function HomePage() {
  return (
    <ShowRenderedHTML>
      <Component />
      <Component />
      ...
    </ShowRenderedHTML>
  );
}

function Component() {
  return <link rel="stylesheet" href="styles.css" precedence="medium" />;
}
```

### Annotating specific items within the document with links[](#annotating-specific-items-within-the-document-with-links "Link for Annotating specific items within the document with links ")

You can use the `<link>` component with the `itemProp` prop to annotate specific items within the document with links to related resources. In this case, React will *not* place these annotations within the document `<head>` but will place them like any other React component.

```
<section itemScope>

  <h3>Annotating specific items</h3>

  <link itemProp="author" href="http://example.com/" />

  <p>...</p>

</section>
```

[Previous\<textarea>](/reference/react-dom/components/textarea)

[Next\<meta>](/reference/react-dom/components/meta)

***

----
url: https://18.react.dev/reference/react/useState
----

[API Reference](/reference/react)

[Hooks](/reference/react/hooks)

# useState[](#undefined "Link for this heading")

`useState` is a React Hook that lets you add a [state variable](/learn/state-a-components-memory) to your component.

```
const [state, setState] = useState(initialState)
```

***

## Reference[](#reference "Link for Reference ")

### `useState(initialState)`[](#usestate "Link for this heading")

Call `useState` at the top level of your component to declare a [state variable.](/learn/state-a-components-memory)

```
import { useState } from 'react';



function MyComponent() {

  const [age, setAge] = useState(28);

  const [name, setName] = useState('Taylor');

  const [todos, setTodos] = useState(() => createTodos());

  // ...
```

***

### `set` functions, like `setSomething(nextState)`[](#setstate "Link for this heading")

The `set` function returned by `useState` lets you update the state to a different value and trigger a re-render. You can pass the next state directly, or a function that calculates it from the previous state:

```
const [name, setName] = useState('Edward');



function handleClick() {

  setName('Taylor');

  setAge(a => a + 1);

  // ...
```

***

## Usage[](#usage "Link for Usage ")

### Adding state to a component[](#adding-state-to-a-component "Link for Adding state to a component ")

Call `useState` at the top level of your component to declare one or more [state variables.](/learn/state-a-components-memory)

```
import { useState } from 'react';



function MyComponent() {

  const [age, setAge] = useState(42);

  const [name, setName] = useState('Taylor');

  // ...
```

The convention is to name state variables like `[something, setSomething]` using [array destructuring.](https://javascript.info/destructuring-assignment)

`useState` returns an array with exactly two items:

1. The current state of this state variable, initially set to the initial state you provided.
2. The `set` function that lets you change it to any other value in response to interaction.

To update what’s on the screen, call the `set` function with some next state:

```
function handleClick() {

  setName('Robin');

}
```

React will store the next state, render your component again with the new values, and update the UI.

### Pitfall

Calling the `set` function [**does not** change the current state in the already executing code](#ive-updated-the-state-but-logging-gives-me-the-old-value):

```
function handleClick() {

  setName('Robin');

  console.log(name); // Still "Taylor"!

}
```

It only affects what `useState` will return starting from the *next* render.

#### Basic useState examples[](#examples-basic "Link for Basic useState examples")

#### Example 1 of 4:Counter (number)[](#counter-number "Link for this heading")

In this example, the `count` state variable holds a number. Clicking the button increments it.

```
import { useState } from 'react';

export default function Counter() {
  const [count, setCount] = useState(0);

  function handleClick() {
    setCount(count + 1);
  }

  return (
    <button onClick={handleClick}>
      You pressed me {count} times
    </button>
  );
}
```

***

### Updating state based on the previous state[](#updating-state-based-on-the-previous-state "Link for Updating state based on the previous state ")

Suppose the `age` is `42`. This handler calls `setAge(age + 1)` three times:

```
function handleClick() {

  setAge(age + 1); // setAge(42 + 1)

  setAge(age + 1); // setAge(42 + 1)

  setAge(age + 1); // setAge(42 + 1)

}
```

However, after one click, `age` will only be `43` rather than `45`! This is because calling the `set` function [does not update](/learn/state-as-a-snapshot) the `age` state variable in the already running code. So each `setAge(age + 1)` call becomes `setAge(43)`.

To solve this problem, **you may pass an *updater function*** to `setAge` instead of the next state:

```
function handleClick() {

  setAge(a => a + 1); // setAge(42 => 43)

  setAge(a => a + 1); // setAge(43 => 44)

  setAge(a => a + 1); // setAge(44 => 45)

}
```

```
import { useState } from 'react';

export default function Counter() {
  const [age, setAge] = useState(42);

  function increment() {
    setAge(a => a + 1);
  }

  return (
    <>
      <h1>Your age: {age}</h1>
      <button onClick={() => {
        increment();
        increment();
        increment();
      }}>+3</button>
      <button onClick={() => {
        increment();
      }}>+1</button>
    </>
  );
}
```

***

### Updating objects and arrays in state[](#updating-objects-and-arrays-in-state "Link for Updating objects and arrays in state ")

You can put objects and arrays into state. In React, state is considered read-only, so **you should *replace* it rather than *mutate* your existing objects**. For example, if you have a `form` object in state, don’t mutate it:

```
// 🚩 Don't mutate an object in state like this:

form.firstName = 'Taylor';
```

Instead, replace the whole object by creating a new one:

```
// ✅ Replace state with a new object

setForm({

  ...form,

  firstName: 'Taylor'

});
```

Read [updating objects in state](/learn/updating-objects-in-state) and [updating arrays in state](/learn/updating-arrays-in-state) to learn more.

#### Examples of objects and arrays in state[](#examples-objects "Link for Examples of objects and arrays in state")

#### Example 1 of 4:Form (object)[](#form-object "Link for this heading")

In this example, the `form` state variable holds an object. Each input has a change handler that calls `setForm` with the next state of the entire form. The `{ ...form }` spread syntax ensures that the state object is replaced rather than mutated.

```
import { useState } from 'react';

export default function Form() {
  const [form, setForm] = useState({
    firstName: 'Barbara',
    lastName: 'Hepworth',
    email: 'bhepworth@sculpture.com',
  });

  return (
    <>
      <label>
        First name:
        <input
          value={form.firstName}
          onChange={e => {
            setForm({
              ...form,
              firstName: e.target.value
            });
          }}
        />
      </label>
      <label>
        Last name:
        <input
          value={form.lastName}
          onChange={e => {
            setForm({
              ...form,
              lastName: e.target.value
            });
          }}
        />
      </label>
      <label>
        Email:
        <input
          value={form.email}
          onChange={e => {
            setForm({
              ...form,
              email: e.target.value
            });
          }}
        />
      </label>
      <p>
        {form.firstName}{' '}
        {form.lastName}{' '}
        ({form.email})
      </p>
    </>
  );
}
```

***

### Avoiding recreating the initial state[](#avoiding-recreating-the-initial-state "Link for Avoiding recreating the initial state ")

React saves the initial state once and ignores it on the next renders.

```
function TodoList() {

  const [todos, setTodos] = useState(createInitialTodos());

  // ...
```

Although the result of `createInitialTodos()` is only used for the initial render, you’re still calling this function on every render. This can be wasteful if it’s creating large arrays or performing expensive calculations.

To solve this, you may **pass it as an *initializer* function** to `useState` instead:

```
function TodoList() {

  const [todos, setTodos] = useState(createInitialTodos);

  // ...
```

Notice that you’re passing `createInitialTodos`, which is the *function itself*, and not `createInitialTodos()`, which is the result of calling it. If you pass a function to `useState`, React will only call it during initialization.

React may [call your initializers twice](#my-initializer-or-updater-function-runs-twice) in development to verify that they are [pure.](/learn/keeping-components-pure)

#### The difference between passing an initializer and passing the initial state directly[](#examples-initializer "Link for The difference between passing an initializer and passing the initial state directly")

#### Example 1 of 2:Passing the initializer function[](#passing-the-initializer-function "Link for this heading")

This example passes the initializer function, so the `createInitialTodos` function only runs during initialization. It does not run when component re-renders, such as when you type into the input.

```
import { useState } from 'react';

function createInitialTodos() {
  const initialTodos = [];
  for (let i = 0; i < 50; i++) {
    initialTodos.push({
      id: i,
      text: 'Item ' + (i + 1)
    });
  }
  return initialTodos;
}

export default function TodoList() {
  const [todos, setTodos] = useState(createInitialTodos);
  const [text, setText] = useState('');

  return (
    <>
      <input
        value={text}
        onChange={e => setText(e.target.value)}
      />
      <button onClick={() => {
        setText('');
        setTodos([{
          id: todos.length,
          text: text
        }, ...todos]);
      }}>Add</button>
      <ul>
        {todos.map(item => (
          <li key={item.id}>
            {item.text}
          </li>
        ))}
      </ul>
    </>
  );
}
```

***

### Resetting state with a key[](#resetting-state-with-a-key "Link for Resetting state with a key ")

You’ll often encounter the `key` attribute when [rendering lists.](/learn/rendering-lists) However, it also serves another purpose.

You can **reset a component’s state by passing a different `key` to a component.** In this example, the Reset button changes the `version` state variable, which we pass as a `key` to the `Form`. When the `key` changes, React re-creates the `Form` component (and all of its children) from scratch, so its state gets reset.

Read [preserving and resetting state](/learn/preserving-and-resetting-state) to learn more.

```
import { useState } from 'react';

export default function App() {
  const [version, setVersion] = useState(0);

  function handleReset() {
    setVersion(version + 1);
  }

  return (
    <>
      <button onClick={handleReset}>Reset</button>
      <Form key={version} />
    </>
  );
}

function Form() {
  const [name, setName] = useState('Taylor');

  return (
    <>
      <input
        value={name}
        onChange={e => setName(e.target.value)}
      />
      <p>Hello, {name}.</p>
    </>
  );
}
```

***

```
export default function CountLabel({ count }) {

  return <h1>{count}</h1>

}
```

Say you want to show whether the counter has *increased or decreased* since the last change. The `count` prop doesn’t tell you this — you need to keep track of its previous value. Add the `prevCount` state variable to track it. Add another state variable called `trend` to hold whether the count has increased or decreased. Compare `prevCount` with `count`, and if they’re not equal, update both `prevCount` and `trend`. Now you can show both the current count prop and *how it has changed since the last render*.

```
import { useState } from 'react';

export default function CountLabel({ count }) {
  const [prevCount, setPrevCount] = useState(count);
  const [trend, setTrend] = useState(null);
  if (prevCount !== count) {
    setPrevCount(count);
    setTrend(count > prevCount ? 'increasing' : 'decreasing');
  }
  return (
    <>
      <h1>{count}</h1>
      {trend && <p>The count is {trend}</p>}
    </>
  );
}
```

Note that if you call a `set` function while rendering, it must be inside a condition like `prevCount !== count`, and there must be a call like `setPrevCount(count)` inside of the condition. Otherwise, your component would re-render in a loop until it crashes. Also, you can only update the state of the *currently rendering* component like this. Calling the `set` function of *another* component during rendering is an error. Finally, your `set` call should still [update state without mutation](#updating-objects-and-arrays-in-state) — this doesn’t mean you can break other rules of [pure functions.](/learn/keeping-components-pure)

This pattern can be hard to understand and is usually best avoided. However, it’s better than updating state in an effect. When you call the `set` function during render, React will re-render that component immediately after your component exits with a `return` statement, and before rendering the children. This way, children don’t need to render twice. The rest of your component function will still execute (and the result will be thrown away). If your condition is below all the Hook calls, you may add an early `return;` to restart rendering earlier.

***

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### I’ve updated the state, but logging gives me the old value[](#ive-updated-the-state-but-logging-gives-me-the-old-value "Link for I’ve updated the state, but logging gives me the old value ")

Calling the `set` function **does not change state in the running code**:

```
function handleClick() {

  console.log(count);  // 0



  setCount(count + 1); // Request a re-render with 1

  console.log(count);  // Still 0!



  setTimeout(() => {

    console.log(count); // Also 0!

  }, 5000);

}
```

This is because [states behaves like a snapshot.](/learn/state-as-a-snapshot) Updating state requests another render with the new state value, but does not affect the `count` JavaScript variable in your already-running event handler.

If you need to use the next state, you can save it in a variable before passing it to the `set` function:

```
const nextCount = count + 1;

setCount(nextCount);



console.log(count);     // 0

console.log(nextCount); // 1
```

***

### I’ve updated the state, but the screen doesn’t update[](#ive-updated-the-state-but-the-screen-doesnt-update "Link for I’ve updated the state, but the screen doesn’t update ")

React will **ignore your update if the next state is equal to the previous state,** as determined by an [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) comparison. This usually happens when you change an object or an array in state directly:

```
obj.x = 10;  // 🚩 Wrong: mutating existing object

setObj(obj); // 🚩 Doesn't do anything
```

You mutated an existing `obj` object and passed it back to `setObj`, so React ignored the update. To fix this, you need to ensure that you’re always [*replacing* objects and arrays in state instead of *mutating* them](#updating-objects-and-arrays-in-state):

```
// ✅ Correct: creating a new object

setObj({

  ...obj,

  x: 10

});
```

***

### I’m getting an error: “Too many re-renders”[](#im-getting-an-error-too-many-re-renders "Link for I’m getting an error: “Too many re-renders” ")

You might get an error that says: `Too many re-renders. React limits the number of renders to prevent an infinite loop.` Typically, this means that you’re unconditionally setting state *during render*, so your component enters a loop: render, set state (which causes a render), render, set state (which causes a render), and so on. Very often, this is caused by a mistake in specifying an event handler:

```
// 🚩 Wrong: calls the handler during render

return <button onClick={handleClick()}>Click me</button>



// ✅ Correct: passes down the event handler

return <button onClick={handleClick}>Click me</button>



// ✅ Correct: passes down an inline function

return <button onClick={(e) => handleClick(e)}>Click me</button>
```

If you can’t find the cause of this error, click on the arrow next to the error in the console and look through the JavaScript stack to find the specific `set` function call responsible for the error.

***

### My initializer or updater function runs twice[](#my-initializer-or-updater-function-runs-twice "Link for My initializer or updater function runs twice ")

In [Strict Mode](/reference/react/StrictMode), React will call some of your functions twice instead of once:

```
function TodoList() {

  // This component function will run twice for every render.



  const [todos, setTodos] = useState(() => {

    // This initializer function will run twice during initialization.

    return createTodos();

  });



  function handleClick() {

    setTodos(prevTodos => {

      // This updater function will run twice for every click.

      return [...prevTodos, createTodo()];

    });

  }

  // ...
```

This is expected and shouldn’t break your code.

This **development-only** behavior helps you [keep components pure.](/learn/keeping-components-pure) React uses the result of one of the calls, and ignores the result of the other call. As long as your component, initializer, and updater functions are pure, this shouldn’t affect your logic. However, if they are accidentally impure, this helps you notice the mistakes.

For example, this impure updater function mutates an array in state:

```
setTodos(prevTodos => {

  // 🚩 Mistake: mutating state

  prevTodos.push(createTodo());

});
```

Because React calls your updater function twice, you’ll see the todo was added twice, so you’ll know that there is a mistake. In this example, you can fix the mistake by [replacing the array instead of mutating it](#updating-objects-and-arrays-in-state):

```
setTodos(prevTodos => {

  // ✅ Correct: replacing with new state

  return [...prevTodos, createTodo()];

});
```

Now that this updater function is pure, calling it an extra time doesn’t make a difference in behavior. This is why React calling it twice helps you find mistakes. **Only component, initializer, and updater functions need to be pure.** Event handlers don’t need to be pure, so React will never call your event handlers twice.

Read [keeping components pure](/learn/keeping-components-pure) to learn more.

***

### I’m trying to set state to a function, but it gets called instead[](#im-trying-to-set-state-to-a-function-but-it-gets-called-instead "Link for I’m trying to set state to a function, but it gets called instead ")

You can’t put a function into state like this:

```
const [fn, setFn] = useState(someFunction);



function handleClick() {

  setFn(someOtherFunction);

}
```

Because you’re passing a function, React assumes that `someFunction` is an [initializer function](#avoiding-recreating-the-initial-state), and that `someOtherFunction` is an [updater function](#updating-state-based-on-the-previous-state), so it tries to call them and store the result. To actually *store* a function, you have to put `() =>` before them in both cases. Then React will store the functions you pass.

```
const [fn, setFn] = useState(() => someFunction);



function handleClick() {

  setFn(() => someOtherFunction);

}
```

[PrevioususeRef](/reference/react/useRef)

[NextuseSyncExternalStore](/reference/react/useSyncExternalStore)

***

----
url: https://18.react.dev/reference/react/useReducer
----

[API Reference](/reference/react)

[Hooks](/reference/react/hooks)

# useReducer[](#undefined "Link for this heading")

`useReducer` is a React Hook that lets you add a [reducer](/learn/extracting-state-logic-into-a-reducer) to your component.

```
const [state, dispatch] = useReducer(reducer, initialArg, init?)
```

***

## Reference[](#reference "Link for Reference ")

### `useReducer(reducer, initialArg, init?)`[](#usereducer "Link for this heading")

Call `useReducer` at the top level of your component to manage its state with a [reducer.](/learn/extracting-state-logic-into-a-reducer)

```
import { useReducer } from 'react';



function reducer(state, action) {

  // ...

}



function MyComponent() {

  const [state, dispatch] = useReducer(reducer, { age: 42 });

  // ...
```

***

### `dispatch` function[](#dispatch "Link for this heading")

The `dispatch` function returned by `useReducer` lets you update the state to a different value and trigger a re-render. You need to pass the action as the only argument to the `dispatch` function:

```
const [state, dispatch] = useReducer(reducer, { age: 42 });



function handleClick() {

  dispatch({ type: 'incremented_age' });

  // ...
```

***

## Usage[](#usage "Link for Usage ")

### Adding a reducer to a component[](#adding-a-reducer-to-a-component "Link for Adding a reducer to a component ")

Call `useReducer` at the top level of your component to manage state with a [reducer.](/learn/extracting-state-logic-into-a-reducer)

```
import { useReducer } from 'react';



function reducer(state, action) {

  // ...

}



function MyComponent() {

  const [state, dispatch] = useReducer(reducer, { age: 42 });

  // ...
```

`useReducer` returns an array with exactly two items:

1. The current state of this state variable, initially set to the initial state you provided.
2. The `dispatch` function that lets you change it in response to interaction.

To update what’s on the screen, call `dispatch` with an object representing what the user did, called an *action*:

```
function handleClick() {

  dispatch({ type: 'incremented_age' });

}
```

React will pass the current state and the action to your reducer function. Your reducer will calculate and return the next state. React will store that next state, render your component with it, and update the UI.

```
import { useReducer } from 'react';

function reducer(state, action) {
  if (action.type === 'incremented_age') {
    return {
      age: state.age + 1
    };
  }
  throw Error('Unknown action.');
}

export default function Counter() {
  const [state, dispatch] = useReducer(reducer, { age: 42 });

  return (
    <>
      <button onClick={() => {
        dispatch({ type: 'incremented_age' })
      }}>
        Increment age
      </button>
      <p>Hello! You are {state.age}.</p>
    </>
  );
}
```

`useReducer` is very similar to [`useState`](/reference/react/useState), but it lets you move the state update logic from event handlers into a single function outside of your component. Read more about [choosing between `useState` and `useReducer`.](/learn/extracting-state-logic-into-a-reducer#comparing-usestate-and-usereducer)

***

### Writing the reducer function[](#writing-the-reducer-function "Link for Writing the reducer function ")

A reducer function is declared like this:

```
function reducer(state, action) {

  // ...

}
```

Then you need to fill in the code that will calculate and return the next state. By convention, it is common to write it as a [`switch` statement.](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/switch) For each `case` in the `switch`, calculate and return some next state.

```
function reducer(state, action) {

  switch (action.type) {

    case 'incremented_age': {

      return {

        name: state.name,

        age: state.age + 1

      };

    }

    case 'changed_name': {

      return {

        name: action.nextName,

        age: state.age

      };

    }

  }

  throw Error('Unknown action: ' + action.type);

}
```

Actions can have any shape. By convention, it’s common to pass objects with a `type` property identifying the action. It should include the minimal necessary information that the reducer needs to compute the next state.

```
function Form() {

  const [state, dispatch] = useReducer(reducer, { name: 'Taylor', age: 42 });

  

  function handleButtonClick() {

    dispatch({ type: 'incremented_age' });

  }



  function handleInputChange(e) {

    dispatch({

      type: 'changed_name',

      nextName: e.target.value

    });

  }

  // ...
```

The action type names are local to your component. [Each action describes a single interaction, even if that leads to multiple changes in data.](/learn/extracting-state-logic-into-a-reducer#writing-reducers-well) The shape of the state is arbitrary, but usually it’ll be an object or an array.

Read [extracting state logic into a reducer](/learn/extracting-state-logic-into-a-reducer) to learn more.

### Pitfall

State is read-only. Don’t modify any objects or arrays in state:

```
function reducer(state, action) {

  switch (action.type) {

    case 'incremented_age': {

      // 🚩 Don't mutate an object in state like this:

      state.age = state.age + 1;

      return state;

    }
```

Instead, always return new objects from your reducer:

```
function reducer(state, action) {

  switch (action.type) {

    case 'incremented_age': {

      // ✅ Instead, return a new object

      return {

        ...state,

        age: state.age + 1

      };

    }
```

Read [updating objects in state](/learn/updating-objects-in-state) and [updating arrays in state](/learn/updating-arrays-in-state) to learn more.

#### Basic useReducer examples[](#examples-basic "Link for Basic useReducer examples")

#### Example 1 of 3:Form (object)[](#form-object "Link for this heading")

In this example, the reducer manages a state object with two fields: `name` and `age`.

```
import { useReducer } from 'react';

function reducer(state, action) {
  switch (action.type) {
    case 'incremented_age': {
      return {
        name: state.name,
        age: state.age + 1
      };
    }
    case 'changed_name': {
      return {
        name: action.nextName,
        age: state.age
      };
    }
  }
  throw Error('Unknown action: ' + action.type);
}

const initialState = { name: 'Taylor', age: 42 };

export default function Form() {
  const [state, dispatch] = useReducer(reducer, initialState);

  function handleButtonClick() {
    dispatch({ type: 'incremented_age' });
  }

  function handleInputChange(e) {
    dispatch({
      type: 'changed_name',
      nextName: e.target.value
    }); 
  }

  return (
    <>
      <input
        value={state.name}
        onChange={handleInputChange}
      />
      <button onClick={handleButtonClick}>
        Increment age
      </button>
      <p>Hello, {state.name}. You are {state.age}.</p>
    </>
  );
}
```

***

### Avoiding recreating the initial state[](#avoiding-recreating-the-initial-state "Link for Avoiding recreating the initial state ")

React saves the initial state once and ignores it on the next renders.

```
function createInitialState(username) {

  // ...

}



function TodoList({ username }) {

  const [state, dispatch] = useReducer(reducer, createInitialState(username));

  // ...
```

Although the result of `createInitialState(username)` is only used for the initial render, you’re still calling this function on every render. This can be wasteful if it’s creating large arrays or performing expensive calculations.

To solve this, you may **pass it as an *initializer* function** to `useReducer` as the third argument instead:

```
function createInitialState(username) {

  // ...

}



function TodoList({ username }) {

  const [state, dispatch] = useReducer(reducer, username, createInitialState);

  // ...
```

Notice that you’re passing `createInitialState`, which is the *function itself*, and not `createInitialState()`, which is the result of calling it. This way, the initial state does not get re-created after initialization.

In the above example, `createInitialState` takes a `username` argument. If your initializer doesn’t need any information to compute the initial state, you may pass `null` as the second argument to `useReducer`.

#### The difference between passing an initializer and passing the initial state directly[](#examples-initializer "Link for The difference between passing an initializer and passing the initial state directly")

#### Example 1 of 2:Passing the initializer function[](#passing-the-initializer-function "Link for this heading")

This example passes the initializer function, so the `createInitialState` function only runs during initialization. It does not run when component re-renders, such as when you type into the input.

```
import { useReducer } from 'react';

function createInitialState(username) {
  const initialTodos = [];
  for (let i = 0; i < 50; i++) {
    initialTodos.push({
      id: i,
      text: username + "'s task #" + (i + 1)
    });
  }
  return {
    draft: '',
    todos: initialTodos,
  };
}

function reducer(state, action) {
  switch (action.type) {
    case 'changed_draft': {
      return {
        draft: action.nextDraft,
        todos: state.todos,
      };
    };
    case 'added_todo': {
      return {
        draft: '',
        todos: [{
          id: state.todos.length,
          text: state.draft
        }, ...state.todos]
      }
    }
  }
  throw Error('Unknown action: ' + action.type);
}

export default function TodoList({ username }) {
  const [state, dispatch] = useReducer(
    reducer,
    username,
    createInitialState
  );
  return (
    <>
      <input
        value={state.draft}
        onChange={e => {
          dispatch({
            type: 'changed_draft',
            nextDraft: e.target.value
          })
        }}
      />
      <button onClick={() => {
        dispatch({ type: 'added_todo' });
      }}>Add</button>
      <ul>
        {state.todos.map(item => (
          <li key={item.id}>
            {item.text}
          </li>
        ))}
      </ul>
    </>
  );
}
```

***

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### I’ve dispatched an action, but logging gives me the old state value[](#ive-dispatched-an-action-but-logging-gives-me-the-old-state-value "Link for I’ve dispatched an action, but logging gives me the old state value ")

Calling the `dispatch` function **does not change state in the running code**:

```
function handleClick() {

  console.log(state.age);  // 42



  dispatch({ type: 'incremented_age' }); // Request a re-render with 43

  console.log(state.age);  // Still 42!



  setTimeout(() => {

    console.log(state.age); // Also 42!

  }, 5000);

}
```

This is because [states behaves like a snapshot.](/learn/state-as-a-snapshot) Updating state requests another render with the new state value, but does not affect the `state` JavaScript variable in your already-running event handler.

If you need to guess the next state value, you can calculate it manually by calling the reducer yourself:

```
const action = { type: 'incremented_age' };

dispatch(action);



const nextState = reducer(state, action);

console.log(state);     // { age: 42 }

console.log(nextState); // { age: 43 }
```

***

### I’ve dispatched an action, but the screen doesn’t update[](#ive-dispatched-an-action-but-the-screen-doesnt-update "Link for I’ve dispatched an action, but the screen doesn’t update ")

React will **ignore your update if the next state is equal to the previous state,** as determined by an [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) comparison. This usually happens when you change an object or an array in state directly:

```
function reducer(state, action) {

  switch (action.type) {

    case 'incremented_age': {

      // 🚩 Wrong: mutating existing object

      state.age++;

      return state;

    }

    case 'changed_name': {

      // 🚩 Wrong: mutating existing object

      state.name = action.nextName;

      return state;

    }

    // ...

  }

}
```

You mutated an existing `state` object and returned it, so React ignored the update. To fix this, you need to ensure that you’re always [updating objects in state](/learn/updating-objects-in-state) and [updating arrays in state](/learn/updating-arrays-in-state) instead of mutating them:

```
function reducer(state, action) {

  switch (action.type) {

    case 'incremented_age': {

      // ✅ Correct: creating a new object

      return {

        ...state,

        age: state.age + 1

      };

    }

    case 'changed_name': {

      // ✅ Correct: creating a new object

      return {

        ...state,

        name: action.nextName

      };

    }

    // ...

  }

}
```

***

### A part of my reducer state becomes undefined after dispatching[](#a-part-of-my-reducer-state-becomes-undefined-after-dispatching "Link for A part of my reducer state becomes undefined after dispatching ")

Make sure that every `case` branch **copies all of the existing fields** when returning the new state:

```
function reducer(state, action) {

  switch (action.type) {

    case 'incremented_age': {

      return {

        ...state, // Don't forget this!

        age: state.age + 1

      };

    }

    // ...
```

Without `...state` above, the returned next state would only contain the `age` field and nothing else.

***

### My entire reducer state becomes undefined after dispatching[](#my-entire-reducer-state-becomes-undefined-after-dispatching "Link for My entire reducer state becomes undefined after dispatching ")

If your state unexpectedly becomes `undefined`, you’re likely forgetting to `return` state in one of the cases, or your action type doesn’t match any of the `case` statements. To find why, throw an error outside the `switch`:

```
function reducer(state, action) {

  switch (action.type) {

    case 'incremented_age': {

      // ...

    }

    case 'edited_name': {

      // ...

    }

  }

  throw Error('Unknown action: ' + action.type);

}
```

You can also use a static type checker like TypeScript to catch such mistakes.

***

### I’m getting an error: “Too many re-renders”[](#im-getting-an-error-too-many-re-renders "Link for I’m getting an error: “Too many re-renders” ")

You might get an error that says: `Too many re-renders. React limits the number of renders to prevent an infinite loop.` Typically, this means that you’re unconditionally dispatching an action *during render*, so your component enters a loop: render, dispatch (which causes a render), render, dispatch (which causes a render), and so on. Very often, this is caused by a mistake in specifying an event handler:

```
// 🚩 Wrong: calls the handler during render

return <button onClick={handleClick()}>Click me</button>



// ✅ Correct: passes down the event handler

return <button onClick={handleClick}>Click me</button>



// ✅ Correct: passes down an inline function

return <button onClick={(e) => handleClick(e)}>Click me</button>
```

If you can’t find the cause of this error, click on the arrow next to the error in the console and look through the JavaScript stack to find the specific `dispatch` function call responsible for the error.

***

### My reducer or initializer function runs twice[](#my-reducer-or-initializer-function-runs-twice "Link for My reducer or initializer function runs twice ")

In [Strict Mode](/reference/react/StrictMode), React will call your reducer and initializer functions twice. This shouldn’t break your code.

This **development-only** behavior helps you [keep components pure.](/learn/keeping-components-pure) React uses the result of one of the calls, and ignores the result of the other call. As long as your component, initializer, and reducer functions are pure, this shouldn’t affect your logic. However, if they are accidentally impure, this helps you notice the mistakes.

For example, this impure reducer function mutates an array in state:

```
function reducer(state, action) {

  switch (action.type) {

    case 'added_todo': {

      // 🚩 Mistake: mutating state

      state.todos.push({ id: nextId++, text: action.text });

      return state;

    }

    // ...

  }

}
```

Because React calls your reducer function twice, you’ll see the todo was added twice, so you’ll know that there is a mistake. In this example, you can fix the mistake by [replacing the array instead of mutating it](/learn/updating-arrays-in-state#adding-to-an-array):

```
function reducer(state, action) {

  switch (action.type) {

    case 'added_todo': {

      // ✅ Correct: replacing with new state

      return {

        ...state,

        todos: [

          ...state.todos,

          { id: nextId++, text: action.text }

        ]

      };

    }

    // ...

  }

}
```

Now that this reducer function is pure, calling it an extra time doesn’t make a difference in behavior. This is why React calling it twice helps you find mistakes. **Only component, initializer, and reducer functions need to be pure.** Event handlers don’t need to be pure, so React will never call your event handlers twice.

Read [keeping components pure](/learn/keeping-components-pure) to learn more.

[PrevioususeOptimistic](/reference/react/useOptimistic)

[NextuseRef](/reference/react/useRef)

***

----
url: https://react.dev/reference/react-compiler/directives
----

[API Reference](/reference/react)

# Directives[](#undefined "Link for this heading")

React Compiler directives are special string literals that control whether specific functions are compiled.

```
function MyComponent() {

  "use memo"; // Opt this component into compilation

  return <div>{/* ... */}</div>;

}
```

* [Overview](#overview)

  * [Available directives](#available-directives)
  * [Quick comparison](#quick-comparison)

* [Usage](#usage)

  * [Function-level directives](#function-level)
  * [Module-level directives](#module-level)
  * [Compilation modes interaction](#compilation-modes)

* [Best practices](#best-practices)

  * [Use directives sparingly](#use-sparingly)
  * [Document directive usage](#document-usage)
  * [Plan for removal](#plan-removal)

* [Common patterns](#common-patterns)
  * [Gradual adoption](#gradual-adoption)

* [Troubleshooting](#troubleshooting)
  * [Common issues](#common-issues)

* [See also](#see-also)

***

## Overview[](#overview "Link for Overview ")

React Compiler directives provide fine-grained control over which functions are optimized by the compiler. They are string literals placed at the beginning of a function body or at the top of a module.

### Available directives[](#available-directives "Link for Available directives ")

* **[`"use memo"`](/reference/react-compiler/directives/use-memo)** - Opts a function into compilation
* **[`"use no memo"`](/reference/react-compiler/directives/use-no-memo)** - Opts a function out of compilation

### Quick comparison[](#quick-comparison "Link for Quick comparison ")

| Directive                                                           | Purpose             | When to use                                                         |
| ------------------------------------------------------------------- | ------------------- | ------------------------------------------------------------------- |
| [`"use memo"`](/reference/react-compiler/directives/use-memo)       | Force compilation   | When using `annotation` mode or to override `infer` mode heuristics |
| [`"use no memo"`](/reference/react-compiler/directives/use-no-memo) | Prevent compilation | Debugging issues or working with incompatible code                  |

***

## Usage[](#usage "Link for Usage ")

### Function-level directives[](#function-level "Link for Function-level directives ")

Place directives at the beginning of a function to control its compilation:

```
// Opt into compilation

function OptimizedComponent() {

  "use memo";

  return <div>This will be optimized</div>;

}



// Opt out of compilation

function UnoptimizedComponent() {

  "use no memo";

  return <div>This won't be optimized</div>;

}
```

### Module-level directives[](#module-level "Link for Module-level directives ")

Place directives at the top of a file to affect all functions in that module:

```
// At the very top of the file

"use memo";



// All functions in this file will be compiled

function Component1() {

  return <div>Compiled</div>;

}



function Component2() {

  return <div>Also compiled</div>;

}



// Can be overridden at function level

function Component3() {

  "use no memo"; // This overrides the module directive

  return <div>Not compiled</div>;

}
```

### Compilation modes interaction[](#compilation-modes "Link for Compilation modes interaction ")

Directives behave differently depending on your [`compilationMode`](/reference/react-compiler/compilationMode):

* **`annotation` mode**: Only functions with `"use memo"` are compiled
* **`infer` mode**: Compiler decides what to compile, directives override decisions
* **`all` mode**: Everything is compiled, `"use no memo"` can exclude specific functions

***

## Best practices[](#best-practices "Link for Best practices ")

### Use directives sparingly[](#use-sparingly "Link for Use directives sparingly ")

Directives are escape hatches. Prefer configuring the compiler at the project level:

```
// ✅ Good - project-wide configuration

{

  plugins: [

    ['babel-plugin-react-compiler', {

      compilationMode: 'infer'

    }]

  ]

}



// ⚠️ Use directives only when needed

function SpecialCase() {

  "use no memo"; // Document why this is needed

  // ...

}
```

### Document directive usage[](#document-usage "Link for Document directive usage ")

Always explain why a directive is used:

```
// ✅ Good - clear explanation

function DataGrid() {

  "use no memo"; // TODO: Remove after fixing issue with dynamic row heights (JIRA-123)

  // Complex grid implementation

}



// ❌ Bad - no explanation

function Mystery() {

  "use no memo";

  // ...

}
```

### Plan for removal[](#plan-removal "Link for Plan for removal ")

Opt-out directives should be temporary:

1. Add the directive with a TODO comment
2. Create a tracking issue
3. Fix the underlying problem
4. Remove the directive

```
function TemporaryWorkaround() {

  "use no memo"; // TODO: Remove after upgrading ThirdPartyLib to v2.0

  return <ThirdPartyComponent />;

}
```

***

## Common patterns[](#common-patterns "Link for Common patterns ")

### Gradual adoption[](#gradual-adoption "Link for Gradual adoption ")

When adopting the React Compiler in a large codebase:

```
// Start with annotation mode

{

  compilationMode: 'annotation'

}



// Opt in stable components

function StableComponent() {

  "use memo";

  // Well-tested component

}



// Later, switch to infer mode and opt out problematic ones

function ProblematicComponent() {

  "use no memo"; // Fix issues before removing

  // ...

}
```

***

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

For specific issues with directives, see the troubleshooting sections in:

* [`"use memo"` troubleshooting](/reference/react-compiler/directives/use-memo#troubleshooting)
* [`"use no memo"` troubleshooting](/reference/react-compiler/directives/use-no-memo#troubleshooting)

### Common issues[](#common-issues "Link for Common issues ")

1. **Directive ignored**: Check placement (must be first) and spelling
2. **Compilation still happens**: Check `ignoreUseNoForget` setting
3. **Module directive not working**: Ensure it’s before all imports

***

## See also[](#see-also "Link for See also ")

* [`compilationMode`](/reference/react-compiler/compilationMode) - Configure how the compiler chooses what to optimize
* [`Configuration`](/reference/react-compiler/configuration) - Full compiler configuration options
* [React Compiler documentation](https://react.dev/learn/react-compiler) - Getting started guide

[Previoustarget](/reference/react-compiler/target)

[Next"use memo"](/reference/react-compiler/directives/use-memo)

***

----
url: https://18.react.dev/learn/adding-interactivity
----

```
export default function App() {
  return (
    <Toolbar
      onPlayMovie={() => alert('Playing!')}
      onUploadImage={() => alert('Uploading!')}
    />
  );
}

function Toolbar({ onPlayMovie, onUploadImage }) {
  return (
    <div>
      <Button onClick={onPlayMovie}>
        Play Movie
      </Button>
      <Button onClick={onUploadImage}>
        Upload Image
      </Button>
    </div>
  );
}

function Button({ onClick, children }) {
  return (
    <button onClick={onClick}>
      {children}
    </button>
  );
}
```

## Ready to learn this topic?

Read **[Responding to Events](/learn/responding-to-events)** to learn how to add event handlers.

[Read More](/learn/responding-to-events)

***

## State: a component’s memory[](#state-a-components-memory "Link for State: a component’s memory ")

Components often need to change what’s on the screen as a result of an interaction. Typing into the form should update the input field, clicking “next” on an image carousel should change which image is displayed, clicking “buy” puts a product in the shopping cart. Components need to “remember” things: the current input value, the current image, the shopping cart. In React, this kind of component-specific memory is called *state.*

You can add state to a component with a [`useState`](/reference/react/useState) Hook. *Hooks* are special functions that let your components use React features (state is one of those features). The `useState` Hook lets you declare a state variable. It takes the initial state and returns a pair of values: the current state, and a state setter function that lets you update it.

```
const [index, setIndex] = useState(0);

const [showMore, setShowMore] = useState(false);
```

Here is how an image gallery uses and updates state on click:

```
import { useState } from 'react';
import { sculptureList } from './data.js';

export default function Gallery() {
  const [index, setIndex] = useState(0);
  const [showMore, setShowMore] = useState(false);
  const hasNext = index < sculptureList.length - 1;

  function handleNextClick() {
    if (hasNext) {
      setIndex(index + 1);
    } else {
      setIndex(0);
    }
  }

  function handleMoreClick() {
    setShowMore(!showMore);
  }

  let sculpture = sculptureList[index];
  return (
    <>
      <button onClick={handleNextClick}>
        Next
      </button>
      <h2>
        <i>{sculpture.name} </i>
        by {sculpture.artist}
      </h2>
      <h3>
        ({index + 1} of {sculptureList.length})
      </h3>
      <button onClick={handleMoreClick}>
        {showMore ? 'Hide' : 'Show'} details
      </button>
      {showMore && <p>{sculpture.description}</p>}
      <img
        src={sculpture.url}
        alt={sculpture.alt}
      />
    </>
  );
}
```

## Ready to learn this topic?

Read **[State: A Component’s Memory](/learn/state-a-components-memory)** to learn how to remember a value and update it on interaction.

[Read More](/learn/state-a-components-memory)

***

***

## State as a snapshot[](#state-as-a-snapshot "Link for State as a snapshot ")

Unlike regular JavaScript variables, React state behaves more like a snapshot. Setting it does not change the state variable you already have, but instead triggers a re-render. This can be surprising at first!

```
console.log(count);  // 0

setCount(count + 1); // Request a re-render with 1

console.log(count);  // Still 0!
```

This behavior helps you avoid subtle bugs. Here is a little chat app. Try to guess what happens if you press “Send” first and *then* change the recipient to Bob. Whose name will appear in the `alert` five seconds later?

```
import { useState } from 'react';

export default function Form() {
  const [to, setTo] = useState('Alice');
  const [message, setMessage] = useState('Hello');

  function handleSubmit(e) {
    e.preventDefault();
    setTimeout(() => {
      alert(`You said ${message} to ${to}`);
    }, 5000);
  }

  return (
    <form onSubmit={handleSubmit}>
      <label>
        To:{' '}
        <select
          value={to}
          onChange={e => setTo(e.target.value)}>
          <option value="Alice">Alice</option>
          <option value="Bob">Bob</option>
        </select>
      </label>
      <textarea
        placeholder="Message"
        value={message}
        onChange={e => setMessage(e.target.value)}
      />
      <button type="submit">Send</button>
    </form>
  );
}
```

## Ready to learn this topic?

Read **[State as a Snapshot](/learn/state-as-a-snapshot)** to learn why state appears “fixed” and unchanging inside the event handlers.

[Read More](/learn/state-as-a-snapshot)

***

## Queueing a series of state updates[](#queueing-a-series-of-state-updates "Link for Queueing a series of state updates ")

This component is buggy: clicking “+3” increments the score only once.

```
import { useState } from 'react';

export default function Counter() {
  const [score, setScore] = useState(0);

  function increment() {
    setScore(score + 1);
  }

  return (
    <>
      <button onClick={() => increment()}>+1</button>
      <button onClick={() => {
        increment();
        increment();
        increment();
      }}>+3</button>
      <h1>Score: {score}</h1>
    </>
  )
}
```

[State as a Snapshot](/learn/state-as-a-snapshot) explains why this is happening. Setting state requests a new re-render, but does not change it in the already running code. So `score` continues to be `0` right after you call `setScore(score + 1)`.

```
console.log(score);  // 0

setScore(score + 1); // setScore(0 + 1);

console.log(score);  // 0

setScore(score + 1); // setScore(0 + 1);

console.log(score);  // 0

setScore(score + 1); // setScore(0 + 1);

console.log(score);  // 0
```

You can fix this by passing an *updater function* when setting state. Notice how replacing `setScore(score + 1)` with `setScore(s => s + 1)` fixes the “+3” button. This lets you queue multiple state updates.

```
import { useState } from 'react';

export default function Counter() {
  const [score, setScore] = useState(0);

  function increment() {
    setScore(s => s + 1);
  }

  return (
    <>
      <button onClick={() => increment()}>+1</button>
      <button onClick={() => {
        increment();
        increment();
        increment();
      }}>+3</button>
      <h1>Score: {score}</h1>
    </>
  )
}
```

## Ready to learn this topic?

Read **[Queueing a Series of State Updates](/learn/queueing-a-series-of-state-updates)** to learn how to queue a sequence of state updates.

[Read More](/learn/queueing-a-series-of-state-updates)

***

## Updating objects in state[](#updating-objects-in-state "Link for Updating objects in state ")

State can hold any kind of JavaScript value, including objects. But you shouldn’t change objects and arrays that you hold in the React state directly. Instead, when you want to update an object and array, you need to create a new one (or make a copy of an existing one), and then update the state to use that copy.

Usually, you will use the `...` spread syntax to copy objects and arrays that you want to change. For example, updating a nested object could look like this:

```
import { useState } from 'react';

export default function Form() {
  const [person, setPerson] = useState({
    name: 'Niki de Saint Phalle',
    artwork: {
      title: 'Blue Nana',
      city: 'Hamburg',
      image: 'https://i.imgur.com/Sd1AgUOm.jpg',
    }
  });

  function handleNameChange(e) {
    setPerson({
      ...person,
      name: e.target.value
    });
  }

  function handleTitleChange(e) {
    setPerson({
      ...person,
      artwork: {
        ...person.artwork,
        title: e.target.value
      }
    });
  }

  function handleCityChange(e) {
    setPerson({
      ...person,
      artwork: {
        ...person.artwork,
        city: e.target.value
      }
    });
  }

  function handleImageChange(e) {
    setPerson({
      ...person,
      artwork: {
        ...person.artwork,
        image: e.target.value
      }
    });
  }

  return (
    <>
      <label>
        Name:
        <input
          value={person.name}
          onChange={handleNameChange}
        />
      </label>
      <label>
        Title:
        <input
          value={person.artwork.title}
          onChange={handleTitleChange}
        />
      </label>
      <label>
        City:
        <input
          value={person.artwork.city}
          onChange={handleCityChange}
        />
      </label>
      <label>
        Image:
        <input
          value={person.artwork.image}
          onChange={handleImageChange}
        />
      </label>
      <p>
        <i>{person.artwork.title}</i>
        {' by '}
        {person.name}
        <br />
        (located in {person.artwork.city})
      </p>
      <img
        src={person.artwork.image}
        alt={person.artwork.title}
      />
    </>
  );
}
```

If copying objects in code gets tedious, you can use a library like [Immer](https://github.com/immerjs/use-immer) to reduce repetitive code:

```
{
  "dependencies": {
    "immer": "1.7.3",
    "react": "latest",
    "react-dom": "latest",
    "react-scripts": "latest",
    "use-immer": "0.5.1"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject"
  },
  "devDependencies": {}
}
```

## Ready to learn this topic?

Read **[Updating Objects in State](/learn/updating-objects-in-state)** to learn how to update objects correctly.

[Read More](/learn/updating-objects-in-state)

***

## Updating arrays in state[](#updating-arrays-in-state "Link for Updating arrays in state ")

Arrays are another type of mutable JavaScript objects you can store in state and should treat as read-only. Just like with objects, when you want to update an array stored in state, you need to create a new one (or make a copy of an existing one), and then set state to use the new array:

```
import { useState } from 'react';

const initialList = [
  { id: 0, title: 'Big Bellies', seen: false },
  { id: 1, title: 'Lunar Landscape', seen: false },
  { id: 2, title: 'Terracotta Army', seen: true },
];

export default function BucketList() {
  const [list, setList] = useState(
    initialList
  );

  function handleToggle(artworkId, nextSeen) {
    setList(list.map(artwork => {
      if (artwork.id === artworkId) {
        return { ...artwork, seen: nextSeen };
      } else {
        return artwork;
      }
    }));
  }

  return (
    <>
      <h1>Art Bucket List</h1>
      <h2>My list of art to see:</h2>
      <ItemList
        artworks={list}
        onToggle={handleToggle} />
    </>
  );
}

function ItemList({ artworks, onToggle }) {
  return (
    <ul>
      {artworks.map(artwork => (
        <li key={artwork.id}>
          <label>
            <input
              type="checkbox"
              checked={artwork.seen}
              onChange={e => {
                onToggle(
                  artwork.id,
                  e.target.checked
                );
              }}
            />
            {artwork.title}
          </label>
        </li>
      ))}
    </ul>
  );
}
```

If copying arrays in code gets tedious, you can use a library like [Immer](https://github.com/immerjs/use-immer) to reduce repetitive code:

```
{
  "dependencies": {
    "immer": "1.7.3",
    "react": "latest",
    "react-dom": "latest",
    "react-scripts": "latest",
    "use-immer": "0.5.1"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject"
  },
  "devDependencies": {}
}
```

## Ready to learn this topic?

Read **[Updating Arrays in State](/learn/updating-arrays-in-state)** to learn how to update arrays correctly.

[Read More](/learn/updating-arrays-in-state)

***

## What’s next?[](#whats-next "Link for What’s next? ")

Head over to [Responding to Events](/learn/responding-to-events) to start reading this chapter page by page!

Or, if you’re already familiar with these topics, why not read about [Managing State](/learn/managing-state)?

[PreviousYour UI as a Tree](/learn/understanding-your-ui-as-a-tree)

[NextResponding to Events](/learn/responding-to-events)

***

----
url: https://legacy.reactjs.org/blog/2020/12/21/data-fetching-with-react-server-components.html
----

December 21, 2020 by [Dan Abramov](https://twitter.com/dan_abramov), [Lauren Tan](https://twitter.com/potetotes), [Joseph Savona](https://twitter.com/en_JS), and [Sebastian Markbåge](https://twitter.com/sebmarkbage)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

2020 has been a long year. As it comes to an end we wanted to share a special Holiday Update on our research into zero-bundle-size **React Server Components**.

To introduce React Server Components, we have prepared a talk and a demo. If you want, you can check them out during the holidays, or later when work picks back up in the new year.



**React Server Components are still in research and development.** We are sharing this work in the spirit of transparency and to get initial feedback from the React community. There will be plenty of time for that, so **don’t feel like you have to catch up right now!**

If you want to check them out, we recommend to go in the following order:

1. **Watch the talk** to learn about React Server Components and see the demo.
2. **[Clone the demo](http://github.com/reactjs/server-components-demo)** to play with React Server Components on your computer.
3. **[Read the RFC (with FAQ at the end)](https://github.com/reactjs/rfcs/pull/188)** for a deeper technical breakdown and to provide feedback.

We are excited to hear from you on the RFC or in replies to the [@reactjs](https://twitter.com/reactjs) Twitter handle. Happy holidays, stay safe, and see you next year!

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2020-12-21-data-fetching-with-react-server-components.md)

----
url: https://react.dev/learn/sharing-state-between-components
----

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

function Panel({ title, children }) {
  const [isActive, setIsActive] = useState(false);
  return (
    <section className="panel">
      <h3>{title}</h3>
      {isActive ? (
        <p>{children}</p>
      ) : (
        <button onClick={() => setIsActive(true)}>
          Show
        </button>
      )}
    </section>
  );
}

export default function Accordion() {
  return (
    <>
      <h2>Almaty, Kazakhstan</h2>
      <Panel title="About">
        With a population of about 2 million, Almaty is Kazakhstan's largest city. From 1929 to 1997, it was its capital city.
      </Panel>
      <Panel title="Etymology">
        The name comes from <span lang="kk-KZ">алма</span>, the Kazakh word for "apple" and is often translated as "full of apples". In fact, the region surrounding Almaty is thought to be the ancestral home of the apple, and the wild <i lang="la">Malus sieversii</i> is considered a likely candidate for the ancestor of the modern domestic apple.
      </Panel>
    </>
  );
}
```

```
const [isActive, setIsActive] = useState(false);
```

And instead, add `isActive` to the `Panel`’s list of props:

```
function Panel({ title, children, isActive }) {
```

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function Accordion() {
  return (
    <>
      <h2>Almaty, Kazakhstan</h2>
      <Panel title="About" isActive={true}>
        With a population of about 2 million, Almaty is Kazakhstan's largest city. From 1929 to 1997, it was its capital city.
      </Panel>
      <Panel title="Etymology" isActive={true}>
        The name comes from <span lang="kk-KZ">алма</span>, the Kazakh word for "apple" and is often translated as "full of apples". In fact, the region surrounding Almaty is thought to be the ancestral home of the apple, and the wild <i lang="la">Malus sieversii</i> is considered a likely candidate for the ancestor of the modern domestic apple.
      </Panel>
    </>
  );
}

function Panel({ title, children, isActive }) {
  return (
    <section className="panel">
      <h3>{title}</h3>
      {isActive ? (
        <p>{children}</p>
      ) : (
        <button onClick={() => setIsActive(true)}>
          Show
        </button>
      )}
    </section>
  );
}
```

Try editing the hardcoded `isActive` values in the `Accordion` component and see the result on the screen.

### Step 3: Add state to the common parent[](#step-3-add-state-to-the-common-parent "Link for Step 3: Add state to the common parent ")

Lifting state up often changes the nature of what you’re storing as state.

In this case, only one panel should be active at a time. This means that the `Accordion` common parent component needs to keep track of *which* panel is the active one. Instead of a `boolean` value, it could use a number as the index of the active `Panel` for the state variable:

```
const [activeIndex, setActiveIndex] = useState(0);
```

When the `activeIndex` is `0`, the first panel is active, and when it’s `1`, it’s the second one.

Clicking the “Show” button in either `Panel` needs to change the active index in `Accordion`. A `Panel` can’t set the `activeIndex` state directly because it’s defined inside the `Accordion`. The `Accordion` component needs to *explicitly allow* the `Panel` component to change its state by [passing an event handler down as a prop](/learn/responding-to-events#passing-event-handlers-as-props):

```
<>

  <Panel

    isActive={activeIndex === 0}

    onShow={() => setActiveIndex(0)}

  >

    ...

  </Panel>

  <Panel

    isActive={activeIndex === 1}

    onShow={() => setActiveIndex(1)}

  >

    ...

  </Panel>

</>
```

The `<button>` inside the `Panel` will now use the `onShow` prop as its click event handler:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function Accordion() {
  const [activeIndex, setActiveIndex] = useState(0);
  return (
    <>
      <h2>Almaty, Kazakhstan</h2>
      <Panel
        title="About"
        isActive={activeIndex === 0}
        onShow={() => setActiveIndex(0)}
      >
        With a population of about 2 million, Almaty is Kazakhstan's largest city. From 1929 to 1997, it was its capital city.
      </Panel>
      <Panel
        title="Etymology"
        isActive={activeIndex === 1}
        onShow={() => setActiveIndex(1)}
      >
        The name comes from <span lang="kk-KZ">алма</span>, the Kazakh word for "apple" and is often translated as "full of apples". In fact, the region surrounding Almaty is thought to be the ancestral home of the apple, and the wild <i lang="la">Malus sieversii</i> is considered a likely candidate for the ancestor of the modern domestic apple.
      </Panel>
    </>
  );
}

function Panel({
  title,
  children,
  isActive,
  onShow
}) {
  return (
    <section className="panel">
      <h3>{title}</h3>
      {isActive ? (
        <p>{children}</p>
      ) : (
        <button onClick={onShow}>
          Show
        </button>
      )}
    </section>
  );
}
```

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function SyncedInputs() {
  return (
    <>
      <Input label="First input" />
      <Input label="Second input" />
    </>
  );
}

function Input({ label }) {
  const [text, setText] = useState('');

  function handleChange(e) {
    setText(e.target.value);
  }

  return (
    <label>
      {label}
      {' '}
      <input
        value={text}
        onChange={handleChange}
      />
    </label>
  );
}
```

[PreviousChoosing the State Structure](/learn/choosing-the-state-structure)

[NextPreserving and Resetting State](/learn/preserving-and-resetting-state)

***

----
url: https://18.react.dev/reference/react-dom/components/form
----

[API Reference](/reference/react)

[Components](/reference/react-dom/components)

# \<form>[](#undefined "Link for this heading")

### Canary

React’s extensions to `<form>` are currently only available in React’s canary and experimental channels. In stable releases of React, `<form>` works only as a [built-in browser HTML component](https://react.dev/reference/react-dom/components#all-html-components). Learn more about [React’s release channels here](/community/versioning-policy#all-release-channels).

The [built-in browser `<form>` component](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form) lets you create interactive controls for submitting information.

```
<form action={search}>

    <input name="query" />

    <button type="submit">Search</button>

</form>
```

* [Reference](#reference)
  * [`<form>`](#form)

* [Usage](#usage)

  * [Handle form submission on the client](#handle-form-submission-on-the-client)
  * [Handle form submission with a Server Action](#handle-form-submission-with-a-server-action)
  * [Display a pending state during form submission](#display-a-pending-state-during-form-submission)
  * [Optimistically updating form data](#optimistically-updating-form-data)
  * [Handling form submission errors](#handling-form-submission-errors)
  * [Display a form submission error without JavaScript](#display-a-form-submission-error-without-javascript)
  * [Handling multiple submission types](#handling-multiple-submission-types)

***

## Reference[](#reference "Link for Reference ")

### `<form>`[](#form "Link for this heading")

To create interactive controls for submitting information, render the [built-in browser `<form>` component](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form).

```
<form action={search}>

    <input name="query" />

    <button type="submit">Search</button>

</form>
```

[See more examples below.](#usage)

#### Props[](#props "Link for Props ")

`<form>` supports all [common element props.](/reference/react-dom/components/common#props)

[`action`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form#action): a URL or function. When a URL is passed to `action` the form will behave like the HTML form component. When a function is passed to `action` the function will handle the form submission. The function passed to `action` may be async and will be called with a single argument containing the [form data](https://developer.mozilla.org/en-US/docs/Web/API/FormData) of the submitted form. The `action` prop can be overridden by a `formAction` attribute on a `<button>`, `<input type="submit">`, or `<input type="image">` component.

#### Caveats[](#caveats "Link for Caveats ")

* When a function is passed to `action` or `formAction` the HTTP method will be POST regardless of value of the `method` prop.

***

## Usage[](#usage "Link for Usage ")

### Handle form submission on the client[](#handle-form-submission-on-the-client "Link for Handle form submission on the client ")

Pass a function to the `action` prop of form to run the function when the form is submitted. [`formData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData) will be passed to the function as an argument so you can access the data submitted by the form. This differs from the conventional [HTML action](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form#action), which only accepts URLs.

```
export default function Search() {
  function search(formData) {
    const query = formData.get("query");
    alert(`You searched for '${query}'`);
  }
  return (
    <form action={search}>
      <input name="query" />
      <button type="submit">Search</button>
    </form>
  );
}
```

### Handle form submission with a Server Action[](#handle-form-submission-with-a-server-action "Link for Handle form submission with a Server Action ")

Render a `<form>` with an input and submit button. Pass a Server Action (a function marked with [`'use server'`](/reference/rsc/use-server)) to the `action` prop of form to run the function when the form is submitted.

Passing a Server Action to `<form action>` allow users to submit forms without JavaScript enabled or before the code has loaded. This is beneficial to users who have a slow connection, device, or have JavaScript disabled and is similar to the way forms work when a URL is passed to the `action` prop.

You can use hidden form fields to provide data to the `<form>`’s action. The Server Action will be called with the hidden form field data as an instance of [`FormData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData).

```
import { updateCart } from './lib.js';



function AddToCart({productId}) {

  async function addToCart(formData) {

    'use server'

    const productId = formData.get('productId')

    await updateCart(productId)

  }

  return (

    <form action={addToCart}>

        <input type="hidden" name="productId" value={productId} />

        <button type="submit">Add to Cart</button>

    </form>



  );

}
```

In lieu of using hidden form fields to provide data to the `<form>`’s action, you can call the `bind` method to supply it with extra arguments. This will bind a new argument (`productId`) to the function in addition to the `formData` that is passed as an argument to the function.

```
import { updateCart } from './lib.js';



function AddToCart({productId}) {

  async function addToCart(productId, formData) {

    "use server";

    await updateCart(productId)

  }

  const addProductToCart = addToCart.bind(null, productId);

  return (

    <form action={addProductToCart}>

      <button type="submit">Add to Cart</button>

    </form>

  );

}
```

When `<form>` is rendered by a [Server Component](/reference/rsc/use-client), and a [Server Action](/reference/rsc/use-server) is passed to the `<form>`’s `action` prop, the form is [progressively enhanced](https://developer.mozilla.org/en-US/docs/Glossary/Progressive_Enhancement).

### Display a pending state during form submission[](#display-a-pending-state-during-form-submission "Link for Display a pending state during form submission ")

To display a pending state when a form is being submitted, you can call the `useFormStatus` Hook in a component rendered in a `<form>` and read the `pending` property returned.

Here, we use the `pending` property to indicate the form is submitting.

```
import { useFormStatus } from "react-dom";
import { submitForm } from "./actions.js";

function Submit() {
  const { pending } = useFormStatus();
  return (
    <button type="submit" disabled={pending}>
      {pending ? "Submitting..." : "Submit"}
    </button>
  );
}

function Form({ action }) {
  return (
    <form action={action}>
      <Submit />
    </form>
  );
}

export default function App() {
  return <Form action={submitForm} />;
}
```

To learn more about the `useFormStatus` Hook see the [reference documentation](/reference/react-dom/hooks/useFormStatus).

### Optimistically updating form data[](#optimistically-updating-form-data "Link for Optimistically updating form data ")

The `useOptimistic` Hook provides a way to optimistically update the user interface before a background operation, like a network request, completes. In the context of forms, this technique helps to make apps feel more responsive. When a user submits a form, instead of waiting for the server’s response to reflect the changes, the interface is immediately updated with the expected outcome.

For example, when a user types a message into the form and hits the “Send” button, the `useOptimistic` Hook allows the message to immediately appear in the list with a “Sending…” label, even before the message is actually sent to a server. This “optimistic” approach gives the impression of speed and responsiveness. The form then attempts to truly send the message in the background. Once the server confirms the message has been received, the “Sending…” label is removed.

```
import { useOptimistic, useState, useRef } from "react";
import { deliverMessage } from "./actions.js";

function Thread({ messages, sendMessage }) {
  const formRef = useRef();
  async function formAction(formData) {
    addOptimisticMessage(formData.get("message"));
    formRef.current.reset();
    await sendMessage(formData);
  }
  const [optimisticMessages, addOptimisticMessage] = useOptimistic(
    messages,
    (state, newMessage) => [
      ...state,
      {
        text: newMessage,
        sending: true
      }
    ]
  );

  return (
    <>
      {optimisticMessages.map((message, index) => (
        <div key={index}>
          {message.text}
          {!!message.sending && <small> (Sending...)</small>}
        </div>
      ))}
      <form action={formAction} ref={formRef}>
        <input type="text" name="message" placeholder="Hello!" />
        <button type="submit">Send</button>
      </form>
    </>
  );
}

export default function App() {
  const [messages, setMessages] = useState([
    { text: "Hello there!", sending: false, key: 1 }
  ]);
  async function sendMessage(formData) {
    const sentMessage = await deliverMessage(formData.get("message"));
    setMessages([...messages, { text: sentMessage }]);
  }
  return <Thread messages={messages} sendMessage={sendMessage} />;
}
```

### Handling form submission errors[](#handling-form-submission-errors "Link for Handling form submission errors ")

In some cases the function called by a `<form>`’s `action` prop throws an error. You can handle these errors by wrapping `<form>` in an Error Boundary. If the function called by a `<form>`’s `action` prop throws an error, the fallback for the error boundary will be displayed.

```
import { ErrorBoundary } from "react-error-boundary";

export default function Search() {
  function search() {
    throw new Error("search error");
  }
  return (
    <ErrorBoundary
      fallback={<p>There was an error while submitting the form</p>}
    >
      <form action={search}>
        <input name="query" />
        <button type="submit">Search</button>
      </form>
    </ErrorBoundary>
  );
}
```

### Display a form submission error without JavaScript[](#display-a-form-submission-error-without-javascript "Link for Display a form submission error without JavaScript ")

Displaying a form submission error message before the JavaScript bundle loads for progressive enhancement requires that:

1. `<form>` be rendered by a [Server Component](/reference/rsc/use-client)
2. the function passed to the `<form>`’s `action` prop be a [Server Action](/reference/rsc/use-server)
3. the `useActionState` Hook be used to display the error message

`useActionState` takes two parameters: a [Server Action](/reference/rsc/use-server) and an initial state. `useActionState` returns two values, a state variable and an action. The action returned by `useActionState` should be passed to the `action` prop of the form. The state variable returned by `useActionState` can be used to displayed an error message. The value returned by the [Server Action](/reference/rsc/use-server) passed to `useActionState` will be used to update the state variable.

```
import { useActionState } from "react";
import { signUpNewUser } from "./api";

export default function Page() {
  async function signup(prevState, formData) {
    "use server";
    const email = formData.get("email");
    try {
      await signUpNewUser(email);
      alert(`Added "${email}"`);
    } catch (err) {
      return err.toString();
    }
  }
  const [message, signupAction] = useActionState(signup, null);
  return (
    <>
      <h1>Signup for my newsletter</h1>
      <p>Signup with the same email twice to see an error</p>
      <form action={signupAction} id="signup-form">
        <label htmlFor="email">Email: </label>
        <input name="email" id="email" placeholder="react@example.com" />
        <button>Sign up</button>
        {!!message && <p>{message}</p>}
      </form>
    </>
  );
}
```

Learn more about updating state from a form action with the [`useActionState`](/reference/react/useActionState) docs

### Handling multiple submission types[](#handling-multiple-submission-types "Link for Handling multiple submission types ")

Forms can be designed to handle multiple submission actions based on the button pressed by the user. Each button inside a form can be associated with a distinct action or behavior by setting the `formAction` prop.

When a user taps a specific button, the form is submitted, and a corresponding action, defined by that button’s attributes and action, is executed. For instance, a form might submit an article for review by default but have a separate button with `formAction` set to save the article as a draft.

```
export default function Search() {
  function publish(formData) {
    const content = formData.get("content");
    const button = formData.get("button");
    alert(`'${content}' was published with the '${button}' button`);
  }

  function save(formData) {
    const content = formData.get("content");
    alert(`Your draft of '${content}' has been saved!`);
  }

  return (
    <form action={publish}>
      <textarea name="content" rows={4} cols={40} />
      <br />
      <button type="submit" name="button" value="submit">Publish</button>
      <button formAction={save}>Save draft</button>
    </form>
  );
}
```

[PreviousCommon (e.g. \<div>)](/reference/react-dom/components/common)

[Next\<input>](/reference/react-dom/components/input)

***

----
url: https://18.react.dev/reference/rsc/use-server
----

[API Reference](/reference/react)

[Directives](/reference/rsc/directives)

# 'use server'[](#undefined "Link for this heading")

### Canary

`'use server'` is needed only if you’re [using React Server Components](/learn/start-a-new-react-project#bleeding-edge-react-frameworks) or building a library compatible with them.

`'use server'` marks server-side functions that can be called from client-side code.

* [Reference](#reference)

  * [`'use server'`](#use-server)
  * [Security considerations](#security)
  * [Serializable arguments and return values](#serializable-parameters-and-return-values)

* [Usage](#usage)

  * [Server Actions in forms](#server-actions-in-forms)
  * [Calling a Server Action outside of `<form>`](#calling-a-server-action-outside-of-form)

***

## Reference[](#reference "Link for Reference ")

### `'use server'`[](#use-server "Link for this heading")

Add `'use server'` at the top of an async function body to mark the function as callable by the client. We call these functions *Server Actions*.

```
async function addToCart(data) {

  'use server';

  // ...

}
```

When calling a Server Action on the client, it will make a network request to the server that includes a serialized copy of any arguments passed. If the Server Action returns a value, that value will be serialized and returned to the client.

Instead of individually marking functions with `'use server'`, you can add the directive to the top of a file to mark all exports within that file as Server Actions that can be used anywhere, including imported in client code.

#### Caveats[](#caveats "Link for Caveats ")

* `'use server'` must be at the very beginning of their function or module; above any other code including imports (comments above directives are OK). They must be written with single or double quotes, not backticks.
* `'use server'` can only be used in server-side files. The resulting Server Actions can be passed to Client Components through props. See supported [types for serialization](#serializable-parameters-and-return-values).
* To import a Server Action from [client code](/reference/rsc/use-client), the directive must be used on a module level.
* Because the underlying network calls are always asynchronous, `'use server'` can only be used on async functions.
* Always treat arguments to Server Actions as untrusted input and authorize any mutations. See [security considerations](#security).
* Server Actions should be called in a [Transition](/reference/react/useTransition). Server Actions passed to [`<form action>`](/reference/react-dom/components/form#props) or [`formAction`](/reference/react-dom/components/input#props) will automatically be called in a transition.
* Server Actions are designed for mutations that update server-side state; they are not recommended for data fetching. Accordingly, frameworks implementing Server Actions typically process one action at a time and do not have a way to cache the return value.

### Security considerations[](#security "Link for Security considerations ")

Arguments to Server Actions are fully client-controlled. For security, always treat them as untrusted input, and make sure to validate and escape arguments as appropriate.

In any Server Action, make sure to validate that the logged-in user is allowed to perform that action.

### Under Construction

To prevent sending sensitive data from a Server Action, there are experimental taint APIs to prevent unique values and objects from being passed to client code.

See [experimental\_taintUniqueValue](/reference/react/experimental_taintUniqueValue) and [experimental\_taintObjectReference](/reference/react/experimental_taintObjectReference).

### Serializable arguments and return values[](#serializable-parameters-and-return-values "Link for Serializable arguments and return values ")

As client code calls the Server Action over the network, any arguments passed will need to be serializable.

Here are supported types for Server Action arguments:

* Functions that are Server Actions

* [Promises](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)

Notably, these are not supported:

* React elements, or [JSX](/learn/writing-markup-with-jsx)
* Functions, including component functions or any other function that is not a Server Action
* [Classes](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Classes_in_JavaScript)
* Objects that are instances of any class (other than the built-ins mentioned) or objects with [a null prototype](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object#null-prototype_objects)
* Symbols not registered globally, ex. `Symbol('my new symbol')`

Supported serializable return values are the same as [serializable props](/reference/rsc/use-client#passing-props-from-server-to-client-components) for a boundary Client Component.

## Usage[](#usage "Link for Usage ")

### Server Actions in forms[](#server-actions-in-forms "Link for Server Actions in forms ")

The most common use case of Server Actions will be calling server functions that mutate data. On the browser, the [HTML form element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form) is the traditional approach for a user to submit a mutation. With React Server Components, React introduces first-class support for Server Actions in [forms](/reference/react-dom/components/form).

Here is a form that allows a user to request a username.

```
// App.js



async function requestUsername(formData) {

  'use server';

  const username = formData.get('username');

  // ...

}



export default function App() {

  return (

    <form action={requestUsername}>

      <input type="text" name="username" />

      <button type="submit">Request</button>

    </form>

  );

}
```

In this example `requestUsername` is a Server Action passed to a `<form>`. When a user submits this form, there is a network request to the server function `requestUsername`. When calling a Server Action in a form, React will supply the form’s [FormData](https://developer.mozilla.org/en-US/docs/Web/API/FormData) as the first argument to the Server Action.

By passing a Server Action to the form `action`, React can [progressively enhance](https://developer.mozilla.org/en-US/docs/Glossary/Progressive_Enhancement) the form. This means that forms can be submitted before the JavaScript bundle is loaded.

#### Handling return values in forms[](#handling-return-values "Link for Handling return values in forms ")

In the username request form, there might be the chance that a username is not available. `requestUsername` should tell us if it fails or not.

To update the UI based on the result of a Server Action while supporting progressive enhancement, use [`useActionState`](/reference/react/useActionState).

```
// requestUsername.js

'use server';



export default async function requestUsername(formData) {

  const username = formData.get('username');

  if (canRequest(username)) {

    // ...

    return 'successful';

  }

  return 'failed';

}
```

```
// UsernameForm.js

'use client';



import { useActionState } from 'react';

import requestUsername from './requestUsername';



function UsernameForm() {

  const [state, action] = useActionState(requestUsername, null, 'n/a');



  return (

    <>

      <form action={action}>

        <input type="text" name="username" />

        <button type="submit">Request</button>

      </form>

      <p>Last submission request returned: {state}</p>

    </>

  );

}
```

Note that like most Hooks, `useActionState` can only be called in [client code](/reference/rsc/use-client).

### Calling a Server Action outside of `<form>`[](#calling-a-server-action-outside-of-form "Link for this heading")

Server Actions are exposed server endpoints and can be called anywhere in client code.

When using a Server Action outside of a [form](/reference/react-dom/components/form), call the Server Action in a [Transition](/reference/react/useTransition), which allows you to display a loading indicator, show [optimistic state updates](/reference/react/useOptimistic), and handle unexpected errors. Forms will automatically wrap Server Actions in transitions.

```
import incrementLike from './actions';

import { useState, useTransition } from 'react';



function LikeButton() {

  const [isPending, startTransition] = useTransition();

  const [likeCount, setLikeCount] = useState(0);



  const onClick = () => {

    startTransition(async () => {

      const currentCount = await incrementLike();

      setLikeCount(currentCount);

    });

  };



  return (

    <>

      <p>Total Likes: {likeCount}</p>

      <button onClick={onClick} disabled={isPending}>Like</button>;

    </>

  );

}
```

```
// actions.js

'use server';



let likeCount = 0;

export default async function incrementLike() {

  likeCount++;

  return likeCount;

}
```

To read a Server Action return value, you’ll need to `await` the promise returned.

[Previous'use client'](/reference/rsc/use-client)

***

----
url: https://18.react.dev/learn/updating-arrays-in-state
----

|           | avoid (mutates the array)           | prefer (returns a new array)                                        |
| --------- | ----------------------------------- | ------------------------------------------------------------------- |
| adding    | `push`, `unshift`                   | `concat`, `[...arr]` spread syntax ([example](#adding-to-an-array)) |
| removing  | `pop`, `shift`, `splice`            | `filter`, `slice` ([example](#removing-from-an-array))              |
| replacing | `splice`, `arr[i] = ...` assignment | `map` ([example](#replacing-items-in-an-array))                     |
| sorting   | `reverse`, `sort`                   | copy the array first ([example](#making-other-changes-to-an-array)) |

```
import { useState } from 'react';

let nextId = 0;

export default function List() {
  const [name, setName] = useState('');
  const [artists, setArtists] = useState([]);

  return (
    <>
      <h1>Inspiring sculptors:</h1>
      <input
        value={name}
        onChange={e => setName(e.target.value)}
      />
      <button onClick={() => {
        artists.push({
          id: nextId++,
          name: name,
        });
      }}>Add</button>
      <ul>
        {artists.map(artist => (
          <li key={artist.id}>{artist.name}</li>
        ))}
      </ul>
    </>
  );
}
```

Instead, create a *new* array which contains the existing items *and* a new item at the end. There are multiple ways to do this, but the easiest one is to use the `...` [array spread](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax#spread_in_array_literals) syntax:

```
setArtists( // Replace the state

  [ // with a new array

    ...artists, // that contains all the old items

    { id: nextId++, name: name } // and one new item at the end

  ]

);
```

Now it works correctly:

```
import { useState } from 'react';

let nextId = 0;

export default function List() {
  const [name, setName] = useState('');
  const [artists, setArtists] = useState([]);

  return (
    <>
      <h1>Inspiring sculptors:</h1>
      <input
        value={name}
        onChange={e => setName(e.target.value)}
      />
      <button onClick={() => {
        setArtists([
          ...artists,
          { id: nextId++, name: name }
        ]);
      }}>Add</button>
      <ul>
        {artists.map(artist => (
          <li key={artist.id}>{artist.name}</li>
        ))}
      </ul>
    </>
  );
}
```

The array spread syntax also lets you prepend an item by placing it *before* the original `...artists`:

```
setArtists([

  { id: nextId++, name: name },

  ...artists // Put old items at the end

]);
```

In this way, spread can do the job of both `push()` by adding to the end of an array and `unshift()` by adding to the beginning of an array. Try it in the sandbox above!

### Removing from an array[](#removing-from-an-array "Link for Removing from an array ")

The easiest way to remove an item from an array is to *filter it out*. In other words, you will produce a new array that will not contain that item. To do this, use the `filter` method, for example:

```
import { useState } from 'react';

let initialArtists = [
  { id: 0, name: 'Marta Colvin Andrade' },
  { id: 1, name: 'Lamidi Olonade Fakeye'},
  { id: 2, name: 'Louise Nevelson'},
];

export default function List() {
  const [artists, setArtists] = useState(
    initialArtists
  );

  return (
    <>
      <h1>Inspiring sculptors:</h1>
      <ul>
        {artists.map(artist => (
          <li key={artist.id}>
            {artist.name}{' '}
            <button onClick={() => {
              setArtists(
                artists.filter(a =>
                  a.id !== artist.id
                )
              );
            }}>
              Delete
            </button>
          </li>
        ))}
      </ul>
    </>
  );
}
```

Click the “Delete” button a few times, and look at its click handler.

```
setArtists(

  artists.filter(a => a.id !== artist.id)

);
```

Here, `artists.filter(a => a.id !== artist.id)` means “create an array that consists of those `artists` whose IDs are different from `artist.id`”. In other words, each artist’s “Delete” button will filter *that* artist out of the array, and then request a re-render with the resulting array. Note that `filter` does not modify the original array.

### Transforming an array[](#transforming-an-array "Link for Transforming an array ")

If you want to change some or all items of the array, you can use `map()` to create a **new** array. The function you will pass to `map` can decide what to do with each item, based on its data or its index (or both).

In this example, an array holds coordinates of two circles and a square. When you press the button, it moves only the circles down by 50 pixels. It does this by producing a new array of data using `map()`:

```
import { useState } from 'react';

let initialShapes = [
  { id: 0, type: 'circle', x: 50, y: 100 },
  { id: 1, type: 'square', x: 150, y: 100 },
  { id: 2, type: 'circle', x: 250, y: 100 },
];

export default function ShapeEditor() {
  const [shapes, setShapes] = useState(
    initialShapes
  );

  function handleClick() {
    const nextShapes = shapes.map(shape => {
      if (shape.type === 'square') {
        // No change
        return shape;
      } else {
        // Return a new circle 50px below
        return {
          ...shape,
          y: shape.y + 50,
        };
      }
    });
    // Re-render with the new array
    setShapes(nextShapes);
  }

  return (
    <>
      <button onClick={handleClick}>
        Move circles down!
      </button>
      {shapes.map(shape => (
        <div
          key={shape.id}
          style={{
          background: 'purple',
          position: 'absolute',
          left: shape.x,
          top: shape.y,
          borderRadius:
            shape.type === 'circle'
              ? '50%' : '',
          width: 20,
          height: 20,
        }} />
      ))}
    </>
  );
}
```

### Replacing items in an array[](#replacing-items-in-an-array "Link for Replacing items in an array ")

It is particularly common to want to replace one or more items in an array. Assignments like `arr[0] = 'bird'` are mutating the original array, so instead you’ll want to use `map` for this as well.

To replace an item, create a new array with `map`. Inside your `map` call, you will receive the item index as the second argument. Use it to decide whether to return the original item (the first argument) or something else:

```
import { useState } from 'react';

let initialCounters = [
  0, 0, 0
];

export default function CounterList() {
  const [counters, setCounters] = useState(
    initialCounters
  );

  function handleIncrementClick(index) {
    const nextCounters = counters.map((c, i) => {
      if (i === index) {
        // Increment the clicked counter
        return c + 1;
      } else {
        // The rest haven't changed
        return c;
      }
    });
    setCounters(nextCounters);
  }

  return (
    <ul>
      {counters.map((counter, i) => (
        <li key={i}>
          {counter}
          <button onClick={() => {
            handleIncrementClick(i);
          }}>+1</button>
        </li>
      ))}
    </ul>
  );
}
```

### Inserting into an array[](#inserting-into-an-array "Link for Inserting into an array ")

Sometimes, you may want to insert an item at a particular position that’s neither at the beginning nor at the end. To do this, you can use the `...` array spread syntax together with the `slice()` method. The `slice()` method lets you cut a “slice” of the array. To insert an item, you will create an array that spreads the slice *before* the insertion point, then the new item, and then the rest of the original array.

In this example, the Insert button always inserts at the index `1`:

```
import { useState } from 'react';

let nextId = 3;
const initialArtists = [
  { id: 0, name: 'Marta Colvin Andrade' },
  { id: 1, name: 'Lamidi Olonade Fakeye'},
  { id: 2, name: 'Louise Nevelson'},
];

export default function List() {
  const [name, setName] = useState('');
  const [artists, setArtists] = useState(
    initialArtists
  );

  function handleClick() {
    const insertAt = 1; // Could be any index
    const nextArtists = [
      // Items before the insertion point:
      ...artists.slice(0, insertAt),
      // New item:
      { id: nextId++, name: name },
      // Items after the insertion point:
      ...artists.slice(insertAt)
    ];
    setArtists(nextArtists);
    setName('');
  }

  return (
    <>
      <h1>Inspiring sculptors:</h1>
      <input
        value={name}
        onChange={e => setName(e.target.value)}
      />
      <button onClick={handleClick}>
        Insert
      </button>
      <ul>
        {artists.map(artist => (
          <li key={artist.id}>{artist.name}</li>
        ))}
      </ul>
    </>
  );
}
```

### Making other changes to an array[](#making-other-changes-to-an-array "Link for Making other changes to an array ")

There are some things you can’t do with the spread syntax and non-mutating methods like `map()` and `filter()` alone. For example, you may want to reverse or sort an array. The JavaScript `reverse()` and `sort()` methods are mutating the original array, so you can’t use them directly.

**However, you can copy the array first, and then make changes to it.**

For example:

```
import { useState } from 'react';

const initialList = [
  { id: 0, title: 'Big Bellies' },
  { id: 1, title: 'Lunar Landscape' },
  { id: 2, title: 'Terracotta Army' },
];

export default function List() {
  const [list, setList] = useState(initialList);

  function handleClick() {
    const nextList = [...list];
    nextList.reverse();
    setList(nextList);
  }

  return (
    <>
      <button onClick={handleClick}>
        Reverse
      </button>
      <ul>
        {list.map(artwork => (
          <li key={artwork.id}>{artwork.title}</li>
        ))}
      </ul>
    </>
  );
}
```

Here, you use the `[...list]` spread syntax to create a copy of the original array first. Now that you have a copy, you can use mutating methods like `nextList.reverse()` or `nextList.sort()`, or even assign individual items with `nextList[0] = "something"`.

However, **even if you copy an array, you can’t mutate existing items *inside* of it directly.** This is because copying is shallow—the new array will contain the same items as the original one. So if you modify an object inside the copied array, you are mutating the existing state. For example, code like this is a problem.

```
const nextList = [...list];

nextList[0].seen = true; // Problem: mutates list[0]

setList(nextList);
```

Although `nextList` and `list` are two different arrays, **`nextList[0]` and `list[0]` point to the same object.** So by changing `nextList[0].seen`, you are also changing `list[0].seen`. This is a state mutation, which you should avoid! You can solve this issue in a similar way to [updating nested JavaScript objects](/learn/updating-objects-in-state#updating-a-nested-object)—by copying individual items you want to change instead of mutating them. Here’s how.

## Updating objects inside arrays[](#updating-objects-inside-arrays "Link for Updating objects inside arrays ")

Objects are not *really* located “inside” arrays. They might appear to be “inside” in code, but each object in an array is a separate value, to which the array “points”. This is why you need to be careful when changing nested fields like `list[0]`. Another person’s artwork list may point to the same element of the array!

**When updating nested state, you need to create copies from the point where you want to update, and all the way up to the top level.** Let’s see how this works.

In this example, two separate artwork lists have the same initial state. They are supposed to be isolated, but because of a mutation, their state is accidentally shared, and checking a box in one list affects the other list:

```
import { useState } from 'react';

let nextId = 3;
const initialList = [
  { id: 0, title: 'Big Bellies', seen: false },
  { id: 1, title: 'Lunar Landscape', seen: false },
  { id: 2, title: 'Terracotta Army', seen: true },
];

export default function BucketList() {
  const [myList, setMyList] = useState(initialList);
  const [yourList, setYourList] = useState(
    initialList
  );

  function handleToggleMyList(artworkId, nextSeen) {
    const myNextList = [...myList];
    const artwork = myNextList.find(
      a => a.id === artworkId
    );
    artwork.seen = nextSeen;
    setMyList(myNextList);
  }

  function handleToggleYourList(artworkId, nextSeen) {
    const yourNextList = [...yourList];
    const artwork = yourNextList.find(
      a => a.id === artworkId
    );
    artwork.seen = nextSeen;
    setYourList(yourNextList);
  }

  return (
    <>
      <h1>Art Bucket List</h1>
      <h2>My list of art to see:</h2>
      <ItemList
        artworks={myList}
        onToggle={handleToggleMyList} />
      <h2>Your list of art to see:</h2>
      <ItemList
        artworks={yourList}
        onToggle={handleToggleYourList} />
    </>
  );
}

function ItemList({ artworks, onToggle }) {
  return (
    <ul>
      {artworks.map(artwork => (
        <li key={artwork.id}>
          <label>
            <input
              type="checkbox"
              checked={artwork.seen}
              onChange={e => {
                onToggle(
                  artwork.id,
                  e.target.checked
                );
              }}
            />
            {artwork.title}
          </label>
        </li>
      ))}
    </ul>
  );
}
```

The problem is in code like this:

```
const myNextList = [...myList];

const artwork = myNextList.find(a => a.id === artworkId);

artwork.seen = nextSeen; // Problem: mutates an existing item

setMyList(myNextList);
```

Although the `myNextList` array itself is new, the *items themselves* are the same as in the original `myList` array. So changing `artwork.seen` changes the *original* artwork item. That artwork item is also in `yourList`, which causes the bug. Bugs like this can be difficult to think about, but thankfully they disappear if you avoid mutating state.

**You can use `map` to substitute an old item with its updated version without mutation.**

```
setMyList(myList.map(artwork => {

  if (artwork.id === artworkId) {

    // Create a *new* object with changes

    return { ...artwork, seen: nextSeen };

  } else {

    // No changes

    return artwork;

  }

}));
```

Here, `...` is the object spread syntax used to [create a copy of an object.](/learn/updating-objects-in-state#copying-objects-with-the-spread-syntax)

With this approach, none of the existing state items are being mutated, and the bug is fixed:

```
import { useState } from 'react';

let nextId = 3;
const initialList = [
  { id: 0, title: 'Big Bellies', seen: false },
  { id: 1, title: 'Lunar Landscape', seen: false },
  { id: 2, title: 'Terracotta Army', seen: true },
];

export default function BucketList() {
  const [myList, setMyList] = useState(initialList);
  const [yourList, setYourList] = useState(
    initialList
  );

  function handleToggleMyList(artworkId, nextSeen) {
    setMyList(myList.map(artwork => {
      if (artwork.id === artworkId) {
        // Create a *new* object with changes
        return { ...artwork, seen: nextSeen };
      } else {
        // No changes
        return artwork;
      }
    }));
  }

  function handleToggleYourList(artworkId, nextSeen) {
    setYourList(yourList.map(artwork => {
      if (artwork.id === artworkId) {
        // Create a *new* object with changes
        return { ...artwork, seen: nextSeen };
      } else {
        // No changes
        return artwork;
      }
    }));
  }

  return (
    <>
      <h1>Art Bucket List</h1>
      <h2>My list of art to see:</h2>
      <ItemList
        artworks={myList}
        onToggle={handleToggleMyList} />
      <h2>Your list of art to see:</h2>
      <ItemList
        artworks={yourList}
        onToggle={handleToggleYourList} />
    </>
  );
}

function ItemList({ artworks, onToggle }) {
  return (
    <ul>
      {artworks.map(artwork => (
        <li key={artwork.id}>
          <label>
            <input
              type="checkbox"
              checked={artwork.seen}
              onChange={e => {
                onToggle(
                  artwork.id,
                  e.target.checked
                );
              }}
            />
            {artwork.title}
          </label>
        </li>
      ))}
    </ul>
  );
}
```

In general, **you should only mutate objects that you have just created.** If you were inserting a *new* artwork, you could mutate it, but if you’re dealing with something that’s already in state, you need to make a copy.

### Write concise update logic with Immer[](#write-concise-update-logic-with-immer "Link for Write concise update logic with Immer ")

Updating nested arrays without mutation can get a little bit repetitive. [Just as with objects](/learn/updating-objects-in-state#write-concise-update-logic-with-immer):

* Generally, you shouldn’t need to update state more than a couple of levels deep. If your state objects are very deep, you might want to [restructure them differently](/learn/choosing-the-state-structure#avoid-deeply-nested-state) so that they are flat.
* If you don’t want to change your state structure, you might prefer to use [Immer](https://github.com/immerjs/use-immer), which lets you write using the convenient but mutating syntax and takes care of producing the copies for you.

Here is the Art Bucket List example rewritten with Immer:

```
{
  "dependencies": {
    "immer": "1.7.3",
    "react": "latest",
    "react-dom": "latest",
    "react-scripts": "latest",
    "use-immer": "0.5.1"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject"
  },
  "devDependencies": {}
}
```

Note how with Immer, **mutation like `artwork.seen = nextSeen` is now okay:**

```
updateMyTodos(draft => {

  const artwork = draft.find(a => a.id === artworkId);

  artwork.seen = nextSeen;

});
```

```
import { useState } from 'react';

const initialProducts = [{
  id: 0,
  name: 'Baklava',
  count: 1,
}, {
  id: 1,
  name: 'Cheese',
  count: 5,
}, {
  id: 2,
  name: 'Spaghetti',
  count: 2,
}];

export default function ShoppingCart() {
  const [
    products,
    setProducts
  ] = useState(initialProducts)

  function handleIncreaseClick(productId) {

  }

  return (
    <ul>
      {products.map(product => (
        <li key={product.id}>
          {product.name}
          {' '}
          (<b>{product.count}</b>)
          <button onClick={() => {
            handleIncreaseClick(product.id);
          }}>
            +
          </button>
        </li>
      ))}
    </ul>
  );
}
```

[PreviousUpdating Objects in State](/learn/updating-objects-in-state)

[NextManaging State](/learn/managing-state)

***

----
url: https://18.react.dev/reference/react/useActionState
----

[API Reference](/reference/react)

[Hooks](/reference/react/hooks)

# useActionState[](#undefined "Link for this heading")

### Canary

The `useActionState` Hook is currently only available in React’s Canary and experimental channels. Learn more about [release channels here](/community/versioning-policy#all-release-channels). In addition, you need to use a framework that supports [React Server Components](/reference/rsc/use-client) to get the full benefit of `useActionState`.

### Note

In earlier React Canary versions, this API was part of React DOM and called `useFormState`.

`useActionState` is a Hook that allows you to update state based on the result of a form action.

```
const [state, formAction, isPending] = useActionState(fn, initialState, permalink?);
```

* [Reference](#reference)
  * [`useActionState(action, initialState, permalink?)`](#useactionstate)
* [Usage](#usage)
  * [Using information returned by a form action](#using-information-returned-by-a-form-action)
* [Troubleshooting](#troubleshooting)
  * [My action can no longer read the submitted form data](#my-action-can-no-longer-read-the-submitted-form-data)

***

## Reference[](#reference "Link for Reference ")

### `useActionState(action, initialState, permalink?)`[](#useactionstate "Link for this heading")

Call `useActionState` at the top level of your component to create component state that is updated [when a form action is invoked](/reference/react-dom/components/form). You pass `useActionState` an existing form action function as well as an initial state, and it returns a new action that you use in your form, along with the latest form state and whether the Action is still pending. The latest form state is also passed to the function that you provided.

```
import { useActionState } from "react";



async function increment(previousState, formData) {

  return previousState + 1;

}



function StatefulForm({}) {

  const [state, formAction] = useActionState(increment, 0);

  return (

    <form>

      {state}

      <button formAction={formAction}>Increment</button>

    </form>

  )

}
```

The form state is the value returned by the action when the form was last submitted. If the form has not yet been submitted, it is the initial state that you pass.

If used with a Server Action, `useActionState` allows the server’s response from submitting the form to be shown even before hydration has completed.

[See more examples below.](#usage)

#### Parameters[](#parameters "Link for Parameters ")

* `fn`: The function to be called when the form is submitted or button pressed. When the function is called, it will receive the previous state of the form (initially the `initialState` that you pass, subsequently its previous return value) as its initial argument, followed by the arguments that a form action normally receives.
* `initialState`: The value you want the state to be initially. It can be any serializable value. This argument is ignored after the action is first invoked.
* **optional** `permalink`: A string containing the unique page URL that this form modifies. For use on pages with dynamic content (eg: feeds) in conjunction with progressive enhancement: if `fn` is a [server action](/reference/rsc/use-server) and the form is submitted before the JavaScript bundle loads, the browser will navigate to the specified permalink URL, rather than the current page’s URL. Ensure that the same form component is rendered on the destination page (including the same action `fn` and `permalink`) so that React knows how to pass the state through. Once the form has been hydrated, this parameter has no effect.

#### Returns[](#returns "Link for Returns ")

`useActionState` returns an array with the following values:

1. The current state. During the first render, it will match the `initialState` you have passed. After the action is invoked, it will match the value returned by the action.
2. A new action that you can pass as the `action` prop to your `form` component or `formAction` prop to any `button` component within the form.
3. The `isPending` flag that tells you whether there is a pending Transition.

#### Caveats[](#caveats "Link for Caveats ")

* When used with a framework that supports React Server Components, `useActionState` lets you make forms interactive before JavaScript has executed on the client. When used without Server Components, it is equivalent to component local state.
* The function passed to `useActionState` receives an extra argument, the previous or initial state, as its first argument. This makes its signature different than if it were used directly as a form action without using `useActionState`.

***

## Usage[](#usage "Link for Usage ")

### Using information returned by a form action[](#using-information-returned-by-a-form-action "Link for Using information returned by a form action ")

Call `useActionState` at the top level of your component to access the return value of an action from the last time a form was submitted.

```
import { useActionState } from 'react';

import { action } from './actions.js';



function MyComponent() {

  const [state, formAction] = useActionState(action, null);

  // ...

  return (

    <form action={formAction}>

      {/* ... */}

    </form>

  );

}
```

`useActionState` returns an array with the following items:

1. The current state of the form, which is initially set to the initial state you provided, and after the form is submitted is set to the return value of the action you provided.
2. A new action that you pass to `<form>` as its `action` prop.
3. A pending state that you can utilise whilst your action is processing.

When the form is submitted, the action function that you provided will be called. Its return value will become the new current state of the form.

The action that you provide will also receive a new first argument, namely the current state of the form. The first time the form is submitted, this will be the initial state you provided, while with subsequent submissions, it will be the return value from the last time the action was called. The rest of the arguments are the same as if `useActionState` had not been used.

```
function action(currentState, formData) {

  // ...

  return 'next state';

}
```

#### Display information after submitting a form[](#display-information-after-submitting-a-form "Link for Display information after submitting a form")

#### Example 1 of 2:Display form errors[](#display-form-errors "Link for this heading")

To display messages such as an error message or toast that’s returned by a Server Action, wrap the action in a call to `useActionState`.

```
import { useActionState, useState } from "react";
import { addToCart } from "./actions.js";

function AddToCartForm({itemID, itemTitle}) {
  const [message, formAction, isPending] = useActionState(addToCart, null);
  return (
    <form action={formAction}>
      <h2>{itemTitle}</h2>
      <input type="hidden" name="itemID" value={itemID} />
      <button type="submit">Add to Cart</button>
      {isPending ? "Loading..." : message}
    </form>
  );
}

export default function App() {
  return (
    <>
      <AddToCartForm itemID="1" itemTitle="JavaScript: The Definitive Guide" />
      <AddToCartForm itemID="2" itemTitle="JavaScript: The Good Parts" />
    </>
  )
}
```

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### My action can no longer read the submitted form data[](#my-action-can-no-longer-read-the-submitted-form-data "Link for My action can no longer read the submitted form data ")

When you wrap an action with `useActionState`, it gets an extra argument *as its first argument*. The submitted form data is therefore its *second* argument instead of its first as it would usually be. The new first argument that gets added is the current state of the form.

```
function action(currentState, formData) {

  // ...

}
```

[PreviousHooks](/reference/react/hooks)

[NextuseCallback](/reference/react/useCallback)

***

----
url: https://18.react.dev/reference/react-dom/server/renderToPipeableStream
----

[API Reference](/reference/react)

[Server APIs](/reference/react-dom/server)

# renderToPipeableStream[](#undefined "Link for this heading")

`renderToPipeableStream` renders a React tree to a pipeable [Node.js Stream.](https://nodejs.org/api/stream.html)

```
const { pipe, abort } = renderToPipeableStream(reactNode, options?)
```

***

## Reference[](#reference "Link for Reference ")

### `renderToPipeableStream(reactNode, options?)`[](#rendertopipeablestream "Link for this heading")

Call `renderToPipeableStream` to render your React tree as HTML into a [Node.js Stream.](https://nodejs.org/api/stream.html#writable-streams)

```
import { renderToPipeableStream } from 'react-dom/server';



const { pipe } = renderToPipeableStream(<App />, {

  bootstrapScripts: ['/main.js'],

  onShellReady() {

    response.setHeader('content-type', 'text/html');

    pipe(response);

  }

});
```

***

## Usage[](#usage "Link for Usage ")

### Rendering a React tree as HTML to a Node.js Stream[](#rendering-a-react-tree-as-html-to-a-nodejs-stream "Link for Rendering a React tree as HTML to a Node.js Stream ")

Call `renderToPipeableStream` to render your React tree as HTML into a [Node.js Stream:](https://nodejs.org/api/stream.html#writable-streams)

```
import { renderToPipeableStream } from 'react-dom/server';



// The route handler syntax depends on your backend framework

app.use('/', (request, response) => {

  const { pipe } = renderToPipeableStream(<App />, {

    bootstrapScripts: ['/main.js'],

    onShellReady() {

      response.setHeader('content-type', 'text/html');

      pipe(response);

    }

  });

});
```

Along with the root component, you need to provide a list of bootstrap `<script>` paths. Your root component should return **the entire document including the root `<html>` tag.**

For example, it might look like this:

```
export default function App() {

  return (

    <html>

      <head>

        <meta charSet="utf-8" />

        <meta name="viewport" content="width=device-width, initial-scale=1" />

        <link rel="stylesheet" href="/styles.css"></link>

        <title>My app</title>

      </head>

      <body>

        <Router />

      </body>

    </html>

  );

}
```

React will inject the [doctype](https://developer.mozilla.org/en-US/docs/Glossary/Doctype) and your bootstrap `<script>` tags into the resulting HTML stream:

```
<!DOCTYPE html>

<html>

  <!-- ... HTML from your components ... -->

</html>

<script src="/main.js" async=""></script>
```

On the client, your bootstrap script should [hydrate the entire `document` with a call to `hydrateRoot`:](/reference/react-dom/client/hydrateRoot#hydrating-an-entire-document)

```
import { hydrateRoot } from 'react-dom/client';

import App from './App.js';



hydrateRoot(document, <App />);
```

This will attach event listeners to the server-generated HTML and make it interactive.

##### Deep Dive#### Reading CSS and JS asset paths from the build output[](#reading-css-and-js-asset-paths-from-the-build-output "Link for Reading CSS and JS asset paths from the build output ")

The final asset URLs (like JavaScript and CSS files) are often hashed after the build. For example, instead of `styles.css` you might end up with `styles.123456.css`. Hashing static asset filenames guarantees that every distinct build of the same asset will have a different filename. This is useful because it lets you safely enable long-term caching for static assets: a file with a certain name would never change content.

However, if you don’t know the asset URLs until after the build, there’s no way for you to put them in the source code. For example, hardcoding `"/styles.css"` into JSX like earlier wouldn’t work. To keep them out of your source code, your root component can read the real filenames from a map passed as a prop:

```
export default function App({ assetMap }) {

  return (

    <html>

      <head>

        ...

        <link rel="stylesheet" href={assetMap['styles.css']}></link>

        ...

      </head>

      ...

    </html>

  );

}
```

On the server, render `<App assetMap={assetMap} />` and pass your `assetMap` with the asset URLs:

```
// You'd need to get this JSON from your build tooling, e.g. read it from the build output.

const assetMap = {

  'styles.css': '/styles.123456.css',

  'main.js': '/main.123456.js'

};



app.use('/', (request, response) => {

  const { pipe } = renderToPipeableStream(<App assetMap={assetMap} />, {

    bootstrapScripts: [assetMap['main.js']],

    onShellReady() {

      response.setHeader('content-type', 'text/html');

      pipe(response);

    }

  });

});
```

Since your server is now rendering `<App assetMap={assetMap} />`, you need to render it with `assetMap` on the client too to avoid hydration errors. You can serialize and pass `assetMap` to the client like this:

```
// You'd need to get this JSON from your build tooling.

const assetMap = {

  'styles.css': '/styles.123456.css',

  'main.js': '/main.123456.js'

};



app.use('/', (request, response) => {

  const { pipe } = renderToPipeableStream(<App assetMap={assetMap} />, {

    // Careful: It's safe to stringify() this because this data isn't user-generated.

    bootstrapScriptContent: `window.assetMap = ${JSON.stringify(assetMap)};`,

    bootstrapScripts: [assetMap['main.js']],

    onShellReady() {

      response.setHeader('content-type', 'text/html');

      pipe(response);

    }

  });

});
```

In the example above, the `bootstrapScriptContent` option adds an extra inline `<script>` tag that sets the global `window.assetMap` variable on the client. This lets the client code read the same `assetMap`:

```
import { hydrateRoot } from 'react-dom/client';

import App from './App.js';



hydrateRoot(document, <App assetMap={window.assetMap} />);
```

Both client and server render `App` with the same `assetMap` prop, so there are no hydration errors.

***

### Streaming more content as it loads[](#streaming-more-content-as-it-loads "Link for Streaming more content as it loads ")

Streaming allows the user to start seeing the content even before all the data has loaded on the server. For example, consider a profile page that shows a cover, a sidebar with friends and photos, and a list of posts:

```
function ProfilePage() {

  return (

    <ProfileLayout>

      <ProfileCover />

      <Sidebar>

        <Friends />

        <Photos />

      </Sidebar>

      <Posts />

    </ProfileLayout>

  );

}
```

Imagine that loading data for `<Posts />` takes some time. Ideally, you’d want to show the rest of the profile page content to the user without waiting for the posts. To do this, [wrap `Posts` in a `<Suspense>` boundary:](/reference/react/Suspense#displaying-a-fallback-while-content-is-loading)

```
function ProfilePage() {

  return (

    <ProfileLayout>

      <ProfileCover />

      <Sidebar>

        <Friends />

        <Photos />

      </Sidebar>

      <Suspense fallback={<PostsGlimmer />}>

        <Posts />

      </Suspense>

    </ProfileLayout>

  );

}
```

This tells React to start streaming the HTML before `Posts` loads its data. React will send the HTML for the loading fallback (`PostsGlimmer`) first, and then, when `Posts` finishes loading its data, React will send the remaining HTML along with an inline `<script>` tag that replaces the loading fallback with that HTML. From the user’s perspective, the page will first appear with the `PostsGlimmer`, later replaced by the `Posts`.

You can further [nest `<Suspense>` boundaries](/reference/react/Suspense#revealing-nested-content-as-it-loads) to create a more granular loading sequence:

```
function ProfilePage() {

  return (

    <ProfileLayout>

      <ProfileCover />

      <Suspense fallback={<BigSpinner />}>

        <Sidebar>

          <Friends />

          <Photos />

        </Sidebar>

        <Suspense fallback={<PostsGlimmer />}>

          <Posts />

        </Suspense>

      </Suspense>

    </ProfileLayout>

  );

}
```

***

### Specifying what goes into the shell[](#specifying-what-goes-into-the-shell "Link for Specifying what goes into the shell ")

The part of your app outside of any `<Suspense>` boundaries is called *the shell:*

```
function ProfilePage() {

  return (

    <ProfileLayout>

      <ProfileCover />

      <Suspense fallback={<BigSpinner />}>

        <Sidebar>

          <Friends />

          <Photos />

        </Sidebar>

        <Suspense fallback={<PostsGlimmer />}>

          <Posts />

        </Suspense>

      </Suspense>

    </ProfileLayout>

  );

}
```

It determines the earliest loading state that the user may see:

```
<ProfileLayout>

  <ProfileCover />

  <BigSpinner />

</ProfileLayout>
```

If you wrap the whole app into a `<Suspense>` boundary at the root, the shell will only contain that spinner. However, that’s not a pleasant user experience because seeing a big spinner on the screen can feel slower and more annoying than waiting a bit more and seeing the real layout. This is why usually you’ll want to place the `<Suspense>` boundaries so that the shell feels *minimal but complete*—like a skeleton of the entire page layout.

The `onShellReady` callback fires when the entire shell has been rendered. Usually, you’ll start streaming then:

```
const { pipe } = renderToPipeableStream(<App />, {

  bootstrapScripts: ['/main.js'],

  onShellReady() {

    response.setHeader('content-type', 'text/html');

    pipe(response);

  }

});
```

By the time `onShellReady` fires, components in nested `<Suspense>` boundaries might still be loading data.

***

### Logging crashes on the server[](#logging-crashes-on-the-server "Link for Logging crashes on the server ")

By default, all errors on the server are logged to console. You can override this behavior to log crash reports:

```
const { pipe } = renderToPipeableStream(<App />, {

  bootstrapScripts: ['/main.js'],

  onShellReady() {

    response.setHeader('content-type', 'text/html');

    pipe(response);

  },

  onError(error) {

    console.error(error);

    logServerCrashReport(error);

  }

});
```

If you provide a custom `onError` implementation, don’t forget to also log errors to the console like above.

***

### Recovering from errors inside the shell[](#recovering-from-errors-inside-the-shell "Link for Recovering from errors inside the shell ")

In this example, the shell contains `ProfileLayout`, `ProfileCover`, and `PostsGlimmer`:

```
function ProfilePage() {

  return (

    <ProfileLayout>

      <ProfileCover />

      <Suspense fallback={<PostsGlimmer />}>

        <Posts />

      </Suspense>

    </ProfileLayout>

  );

}
```

If an error occurs while rendering those components, React won’t have any meaningful HTML to send to the client. Override `onShellError` to send a fallback HTML that doesn’t rely on server rendering as the last resort:

```
const { pipe } = renderToPipeableStream(<App />, {

  bootstrapScripts: ['/main.js'],

  onShellReady() {

    response.setHeader('content-type', 'text/html');

    pipe(response);

  },

  onShellError(error) {

    response.statusCode = 500;

    response.setHeader('content-type', 'text/html');

    response.send('<h1>Something went wrong</h1>'); 

  },

  onError(error) {

    console.error(error);

    logServerCrashReport(error);

  }

});
```

If there is an error while generating the shell, both `onError` and `onShellError` will fire. Use `onError` for error reporting and use `onShellError` to send the fallback HTML document. Your fallback HTML does not have to be an error page. Instead, you may include an alternative shell that renders your app on the client only.

***

### Recovering from errors outside the shell[](#recovering-from-errors-outside-the-shell "Link for Recovering from errors outside the shell ")

In this example, the `<Posts />` component is wrapped in `<Suspense>` so it is *not* a part of the shell:

```
function ProfilePage() {

  return (

    <ProfileLayout>

      <ProfileCover />

      <Suspense fallback={<PostsGlimmer />}>

        <Posts />

      </Suspense>

    </ProfileLayout>

  );

}
```

If an error happens in the `Posts` component or somewhere inside it, React will [try to recover from it:](/reference/react/Suspense#providing-a-fallback-for-server-errors-and-client-only-content)

1. It will emit the loading fallback for the closest `<Suspense>` boundary (`PostsGlimmer`) into the HTML.
2. It will “give up” on trying to render the `Posts` content on the server anymore.
3. When the JavaScript code loads on the client, React will *retry* rendering `Posts` on the client.

If retrying rendering `Posts` on the client *also* fails, React will throw the error on the client. As with all the errors thrown during rendering, the [closest parent error boundary](/reference/react/Component#static-getderivedstatefromerror) determines how to present the error to the user. In practice, this means that the user will see a loading indicator until it is certain that the error is not recoverable.

If retrying rendering `Posts` on the client succeeds, the loading fallback from the server will be replaced with the client rendering output. The user will not know that there was a server error. However, the server `onError` callback and the client [`onRecoverableError`](/reference/react-dom/client/hydrateRoot#hydrateroot) callbacks will fire so that you can get notified about the error.

***

### Setting the status code[](#setting-the-status-code "Link for Setting the status code ")

Streaming introduces a tradeoff. You want to start streaming the page as early as possible so that the user can see the content sooner. However, once you start streaming, you can no longer set the response status code.

By [dividing your app](#specifying-what-goes-into-the-shell) into the shell (above all `<Suspense>` boundaries) and the rest of the content, you’ve already solved a part of this problem. If the shell errors, you’ll get the `onShellError` callback which lets you set the error status code. Otherwise, you know that the app may recover on the client, so you can send “OK”.

```
const { pipe } = renderToPipeableStream(<App />, {

  bootstrapScripts: ['/main.js'],

  onShellReady() {

    response.statusCode = 200;

    response.setHeader('content-type', 'text/html');

    pipe(response);

  },

  onShellError(error) {

    response.statusCode = 500;

    response.setHeader('content-type', 'text/html');

    response.send('<h1>Something went wrong</h1>'); 

  },

  onError(error) {

    console.error(error);

    logServerCrashReport(error);

  }

});
```

If a component *outside* the shell (i.e. inside a `<Suspense>` boundary) throws an error, React will not stop rendering. This means that the `onError` callback will fire, but you will still get `onShellReady` instead of `onShellError`. This is because React will try to recover from that error on the client, [as described above.](#recovering-from-errors-outside-the-shell)

However, if you’d like, you can use the fact that something has errored to set the status code:

```
let didError = false;



const { pipe } = renderToPipeableStream(<App />, {

  bootstrapScripts: ['/main.js'],

  onShellReady() {

    response.statusCode = didError ? 500 : 200;

    response.setHeader('content-type', 'text/html');

    pipe(response);

  },

  onShellError(error) {

    response.statusCode = 500;

    response.setHeader('content-type', 'text/html');

    response.send('<h1>Something went wrong</h1>'); 

  },

  onError(error) {

    didError = true;

    console.error(error);

    logServerCrashReport(error);

  }

});
```

This will only catch errors outside the shell that happened while generating the initial shell content, so it’s not exhaustive. If knowing whether an error occurred for some content is critical, you can move it up into the shell.

***

### Handling different errors in different ways[](#handling-different-errors-in-different-ways "Link for Handling different errors in different ways ")

You can [create your own `Error` subclasses](https://javascript.info/custom-errors) and use the [`instanceof`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/instanceof) operator to check which error is thrown. For example, you can define a custom `NotFoundError` and throw it from your component. Then your `onError`, `onShellReady`, and `onShellError` callbacks can do something different depending on the error type:

```
let didError = false;

let caughtError = null;



function getStatusCode() {

  if (didError) {

    if (caughtError instanceof NotFoundError) {

      return 404;

    } else {

      return 500;

    }

  } else {

    return 200;

  }

}



const { pipe } = renderToPipeableStream(<App />, {

  bootstrapScripts: ['/main.js'],

  onShellReady() {

    response.statusCode = getStatusCode();

    response.setHeader('content-type', 'text/html');

    pipe(response);

  },

  onShellError(error) {

   response.statusCode = getStatusCode();

   response.setHeader('content-type', 'text/html');

   response.send('<h1>Something went wrong</h1>'); 

  },

  onError(error) {

    didError = true;

    caughtError = error;

    console.error(error);

    logServerCrashReport(error);

  }

});
```

Keep in mind that once you emit the shell and start streaming, you can’t change the status code.

***

### Waiting for all content to load for crawlers and static generation[](#waiting-for-all-content-to-load-for-crawlers-and-static-generation "Link for Waiting for all content to load for crawlers and static generation ")

Streaming offers a better user experience because the user can see the content as it becomes available.

However, when a crawler visits your page, or if you’re generating the pages at the build time, you might want to let all of the content load first and then produce the final HTML output instead of revealing it progressively.

You can wait for all the content to load using the `onAllReady` callback:

```
let didError = false;

let isCrawler = // ... depends on your bot detection strategy ...



const { pipe } = renderToPipeableStream(<App />, {

  bootstrapScripts: ['/main.js'],

  onShellReady() {

    if (!isCrawler) {

      response.statusCode = didError ? 500 : 200;

      response.setHeader('content-type', 'text/html');

      pipe(response);

    }

  },

  onShellError(error) {

    response.statusCode = 500;

    response.setHeader('content-type', 'text/html');

    response.send('<h1>Something went wrong</h1>'); 

  },

  onAllReady() {

    if (isCrawler) {

      response.statusCode = didError ? 500 : 200;

      response.setHeader('content-type', 'text/html');

      pipe(response);      

    }

  },

  onError(error) {

    didError = true;

    console.error(error);

    logServerCrashReport(error);

  }

});
```

A regular visitor will get a stream of progressively loaded content. A crawler will receive the final HTML output after all the data loads. However, this also means that the crawler will have to wait for *all* data, some of which might be slow to load or error. Depending on your app, you could choose to send the shell to the crawlers too.

***

### Aborting server rendering[](#aborting-server-rendering "Link for Aborting server rendering ")

You can force the server rendering to “give up” after a timeout:

```
const { pipe, abort } = renderToPipeableStream(<App />, {

  // ...

});



setTimeout(() => {

  abort();

}, 10000);
```

React will flush the remaining loading fallbacks as HTML, and will attempt to render the rest on the client.

[PreviousrenderToNodeStream](/reference/react-dom/server/renderToNodeStream)

[NextrenderToReadableStream](/reference/react-dom/server/renderToReadableStream)

***

----
url: https://legacy.reactjs.org/docs/portals.html
----

> These docs are old and won’t be updated. Go to [react.dev](https://react.dev/) for the new React docs.
>
> These new documentation pages teach modern React and include live examples:
>
> * [`createPortal`](https://react.dev/reference/react-dom/createPortal)

Portals provide a first-class way to render children into a DOM node that exists outside the DOM hierarchy of the parent component.

```
ReactDOM.createPortal(child, container)
```

The first argument (`child`) is any [renderable React child](/docs/react-component.html#render), such as an element, string, or fragment. The second argument (`container`) is a DOM element.

## [](#usage)Usage

Normally, when you return an element from a component’s render method, it’s mounted into the DOM as a child of the nearest parent node:

```
render() {
  // React mounts a new div and renders the children into it
  return (
    <div>      {this.props.children}
    </div>  );
}
```

However, sometimes it’s useful to insert a child into a different location in the DOM:

```
render() {
  // React does *not* create a new div. It renders the children into `domNode`.
  // `domNode` is any valid DOM node, regardless of its location in the DOM.
  return ReactDOM.createPortal(
    this.props.children,
    domNode  );
}
```

A typical use case for portals is when a parent component has an `overflow: hidden` or `z-index` style, but you need the child to visually “break out” of its container. For example, dialogs, hovercards, and tooltips.

> Note:
>
> When working with portals, remember that [managing keyboard focus](/docs/accessibility.html#programmatically-managing-focus) becomes very important.
>
> For modal dialogs, ensure that everyone can interact with them by following the [WAI-ARIA Modal Authoring Practices](https://www.w3.org/WAI/ARIA/apg/patterns/dialogmodal/).

[**Try it on CodePen**](https://codepen.io/gaearon/pen/yzMaBd)

## [](#event-bubbling-through-portals)Event Bubbling Through Portals

Even though a portal can be anywhere in the DOM tree, it behaves like a normal React child in every other way. Features like context work exactly the same regardless of whether the child is a portal, as the portal still exists in the *React tree* regardless of position in the *DOM tree*.

This includes event bubbling. An event fired from inside a portal will propagate to ancestors in the containing *React tree*, even if those elements are not ancestors in the *DOM tree*. Assuming the following HTML structure:

```
<html>
  <body>
    <div id="app-root"></div>
    <div id="modal-root"></div>
  </body>
</html>
```

A `Parent` component in `#app-root` would be able to catch an uncaught, bubbling event from the sibling node `#modal-root`.

```
// These two containers are siblings in the DOM
const appRoot = document.getElementById('app-root');
const modalRoot = document.getElementById('modal-root');

class Modal extends React.Component {
  constructor(props) {
    super(props);
    this.el = document.createElement('div');
  }

  componentDidMount() {
    // The portal element is inserted in the DOM tree after
    // the Modal's children are mounted, meaning that children
    // will be mounted on a detached DOM node. If a child
    // component requires to be attached to the DOM tree
    // immediately when mounted, for example to measure a
    // DOM node, or uses 'autoFocus' in a descendant, add
    // state to Modal and only render the children when Modal
    // is inserted in the DOM tree.
    modalRoot.appendChild(this.el);
  }

  componentWillUnmount() {
    modalRoot.removeChild(this.el);
  }

  render() {
    return ReactDOM.createPortal(      this.props.children,      this.el    );  }
}

class Parent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {clicks: 0};
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {    // This will fire when the button in Child is clicked,    // updating Parent's state, even though button    // is not direct descendant in the DOM.    this.setState(state => ({      clicks: state.clicks + 1    }));  }
  render() {
    return (
      <div onClick={this.handleClick}>        <p>Number of clicks: {this.state.clicks}</p>
        <p>
          Open up the browser DevTools
          to observe that the button
          is not a child of the div
          with the onClick handler.
        </p>
        <Modal>          <Child />        </Modal>      </div>
    );
  }
}

function Child() {
  // The click event on this button will bubble up to parent,  // because there is no 'onClick' attribute defined  return (
    <div className="modal">
      <button>Click</button>    </div>
  );
}

const root = ReactDOM.createRoot(appRoot);
root.render(<Parent />);
```

[**Try it on CodePen**](https://codepen.io/gaearon/pen/jGBWpE)

Catching an event bubbling up from a portal in a parent component allows the development of more flexible abstractions that are not inherently reliant on portals. For example, if you render a `<Modal />` component, the parent can capture its events regardless of whether it’s implemented using portals.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/portals.md)

----
url: https://legacy.reactjs.org/blog/2015/06/12/deprecating-jstransform-and-react-tools.html
----

June 12, 2015 by [Paul O’Shannessy](https://twitter.com/zpao)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

Today we’re announcing the deprecation of react-tools and JSTransform.

As many people have noticed already, React and React Native have both switched their respective build systems to make use of [Babel](http://babeljs.io/). This replaced [JSTransform](https://github.com/facebook/jstransform), the source transformation tool that we wrote at Facebook. JSTransform has been really good for us over the past several years, however as the JavaScript language continues to evolve, the architecture we used has begun to show its age. We’ve faced maintenance issues and lagged behind implementing new language features. Last year, Babel (previously 6to5) exploded onto the scene, implementing new features at an amazing pace. Since then it has evolved a solid plugin API, and implemented some of our non-standard language features (JSX and Flow type annotations).

react-tools has always been a very thin wrapper around JSTransform. It has served as a great tool for the community to get up and running, but at this point we’re ready to [let it go](https://www.youtube.com/watch?v=moSFlvxnbgk). We won’t ship a new version for v0.14.

## [](#migrating-to-babel)Migrating to Babel

Many people in the React and broader JavaScript community have already adopted Babel. It has [integrations with a number of tools](http://babeljs.io/docs/setup/). Depending on your tool, you’ll want to read up on the instructions.

We’ve been working with the Babel team as we started making use of it and we’re confident that it will be the right tool to use with React.

## [](#other-deprecations)Other Deprecations

### [](#esprima-fb)esprima-fb

As a result of no longer maintaining JSTransform, we no longer have a need to maintain our Esprima fork ([esprima-fb](https://github.com/facebook/esprima/)). The upstream Esprima and other esprima-based forks, like Espree, have been doing an excellent job of supporting new language features recently. If you have a need of an esprima-based parser, we encourage you to look into using one of those.

Alternatively, if you need to parse JSX, take a look at [acorn](https://github.com/marijnh/acorn) parser in combination with [acorn-jsx](https://github.com/RReverser/acorn-jsx) plugin which is used inside of Babel and thus always supports the latest syntax.

### [](#jsxtransformer)JSXTransformer

JSXTransformer is another tool we built specifically for consuming JSX in the browser. It was always intended as a quick way to prototype code before setting up a build process. It would look for `<script>` tags with `type="text/jsx"` and then transform and run. This ran the same code that react-tools ran on the server. Babel ships with [a nearly identical tool](https://babeljs.io/docs/usage/browser/), which has already been integrated into [JS Bin](https://jsbin.com/).

We’ll be deprecating JSXTransformer, however the current version will still be available from various CDNs and Bower.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2015-06-12-deprecating-jstransform-and-react-tools.md)

----
url: https://react.dev/learn/responding-to-events
----

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
export default function Button() {
  return (
    <button>
      I don't do anything
    </button>
  );
}
```

You can make it show a message when a user clicks by following these three steps:

1. Declare a function called `handleClick` *inside* your `Button` component.
2. Implement the logic inside that function (use `alert` to show the message).
3. Add `onClick={handleClick}` to the `<button>` JSX.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
export default function Button() {
  function handleClick() {
    alert('You clicked me!');
  }

  return (
    <button onClick={handleClick}>
      Click me
    </button>
  );
}
```

You defined the `handleClick` function and then [passed it as a prop](/learn/passing-props-to-a-component) to `<button>`. `handleClick` is an **event handler.** Event handler functions:

* Are usually defined *inside* your components.
* Have names that start with `handle`, followed by the name of the event.

By convention, it is common to name event handlers as `handle` followed by the event name. You’ll often see `onClick={handleClick}`, `onMouseEnter={handleMouseEnter}`, and so on.

Alternatively, you can define an event handler inline in the JSX:

```
<button onClick={function handleClick() {

  alert('You clicked me!');

}}>
```

Or, more concisely, using an arrow function:

```
<button onClick={() => {

  alert('You clicked me!');

}}>
```

All of these styles are equivalent. Inline event handlers are convenient for short functions.

### Pitfall

Functions passed to event handlers must be passed, not called. For example:

| passing a function (correct)     | calling a function (incorrect)     |
| -------------------------------- | ---------------------------------- |
| `<button onClick={handleClick}>` | `<button onClick={handleClick()}>` |

The difference is subtle. In the first example, the `handleClick` function is passed as an `onClick` event handler. This tells React to remember it and only call your function when the user clicks the button.

In the second example, the `()` at the end of `handleClick()` fires the function *immediately* during [rendering](/learn/render-and-commit), without any clicks. This is because JavaScript inside the [JSX `{` and `}`](/learn/javascript-in-jsx-with-curly-braces) executes right away.

When you write code inline, the same pitfall presents itself in a different way:

| passing a function (correct)            | calling a function (incorrect)    |
| --------------------------------------- | --------------------------------- |
| `<button onClick={() => alert('...')}>` | `<button onClick={alert('...')}>` |

Passing inline code like this won’t fire on click—it fires every time the component renders:

```
// This alert fires when the component renders, not when clicked!

<button onClick={alert('You clicked me!')}>
```

If you want to define your event handler inline, wrap it in an anonymous function like so:

```
<button onClick={() => alert('You clicked me!')}>
```

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
function AlertButton({ message, children }) {
  return (
    <button onClick={() => alert(message)}>
      {children}
    </button>
  );
}

export default function Toolbar() {
  return (
    <div>
      <AlertButton message="Playing!">
        Play Movie
      </AlertButton>
      <AlertButton message="Uploading!">
        Upload Image
      </AlertButton>
    </div>
  );
}
```

This lets these two buttons show different messages. Try changing the messages passed to them.

### Passing event handlers as props[](#passing-event-handlers-as-props "Link for Passing event handlers as props ")

Often you’ll want the parent component to specify a child’s event handler. Consider buttons: depending on where you’re using a `Button` component, you might want to execute a different function—perhaps one plays a movie and another uploads an image.

To do this, pass a prop the component receives from its parent as the event handler like so:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
function Button({ onClick, children }) {
  return (
    <button onClick={onClick}>
      {children}
    </button>
  );
}

function PlayButton({ movieName }) {
  function handlePlayClick() {
    alert(`Playing ${movieName}!`);
  }

  return (
    <Button onClick={handlePlayClick}>
      Play "{movieName}"
    </Button>
  );
}

function UploadButton() {
  return (
    <Button onClick={() => alert('Uploading!')}>
      Upload Image
    </Button>
  );
}

export default function Toolbar() {
  return (
    <div>
      <PlayButton movieName="Kiki's Delivery Service" />
      <UploadButton />
    </div>
  );
}
```

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
function Button({ onSmash, children }) {
  return (
    <button onClick={onSmash}>
      {children}
    </button>
  );
}

export default function App() {
  return (
    <div>
      <Button onSmash={() => alert('Playing!')}>
        Play Movie
      </Button>
      <Button onSmash={() => alert('Uploading!')}>
        Upload Image
      </Button>
    </div>
  );
}
```

In this example, `<button onClick={onSmash}>` shows that the browser `<button>` (lowercase) still needs a prop called `onClick`, but the prop name received by your custom `Button` component is up to you!

When your component supports multiple interactions, you might name event handler props for app-specific concepts. For example, this `Toolbar` component receives `onPlayMovie` and `onUploadImage` event handlers:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
export default function App() {
  return (
    <Toolbar
      onPlayMovie={() => alert('Playing!')}
      onUploadImage={() => alert('Uploading!')}
    />
  );
}

function Toolbar({ onPlayMovie, onUploadImage }) {
  return (
    <div>
      <Button onClick={onPlayMovie}>
        Play Movie
      </Button>
      <Button onClick={onUploadImage}>
        Upload Image
      </Button>
    </div>
  );
}

function Button({ onClick, children }) {
  return (
    <button onClick={onClick}>
      {children}
    </button>
  );
}
```

Notice how the `App` component does not need to know *what* `Toolbar` will do with `onPlayMovie` or `onUploadImage`. That’s an implementation detail of the `Toolbar`. Here, `Toolbar` passes them down as `onClick` handlers to its `Button`s, but it could later also trigger them on a keyboard shortcut. Naming props after app-specific interactions like `onPlayMovie` gives you the flexibility to change how they’re used later.

### Note

Make sure that you use the appropriate HTML tags for your event handlers. For example, to handle clicks, use [`<button onClick={handleClick}>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button) instead of `<div onClick={handleClick}>`. Using a real browser `<button>` enables built-in browser behaviors like keyboard navigation. If you don’t like the default browser styling of a button and want to make it look more like a link or a different UI element, you can achieve it with CSS. [Learn more about writing accessible markup.](https://developer.mozilla.org/en-US/docs/Learn/Accessibility/HTML)

## Event propagation[](#event-propagation "Link for Event propagation ")

Event handlers will also catch events from any children your component might have. We say that an event “bubbles” or “propagates” up the tree: it starts with where the event happened, and then goes up the tree.

This `<div>` contains two buttons. Both the `<div>` *and* each button have their own `onClick` handlers. Which handlers do you think will fire when you click a button?

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
export default function Toolbar() {
  return (
    <div className="Toolbar" onClick={() => {
      alert('You clicked on the toolbar!');
    }}>
      <button onClick={() => alert('Playing!')}>
        Play Movie
      </button>
      <button onClick={() => alert('Uploading!')}>
        Upload Image
      </button>
    </div>
  );
}
```

If you click on either button, its `onClick` will run first, followed by the parent `<div>`’s `onClick`. So two messages will appear. If you click the toolbar itself, only the parent `<div>`’s `onClick` will run.

### Pitfall

All events propagate in React except `onScroll`, which only works on the JSX tag you attach it to.

### Stopping propagation[](#stopping-propagation "Link for Stopping propagation ")

Event handlers receive an **event object** as their only argument. By convention, it’s usually called `e`, which stands for “event”. You can use this object to read information about the event.

That event object also lets you stop the propagation. If you want to prevent an event from reaching parent components, you need to call `e.stopPropagation()` like this `Button` component does:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
function Button({ onClick, children }) {
  return (
    <button onClick={e => {
      e.stopPropagation();
      onClick();
    }}>
      {children}
    </button>
  );
}

export default function Toolbar() {
  return (
    <div className="Toolbar" onClick={() => {
      alert('You clicked on the toolbar!');
    }}>
      <Button onClick={() => alert('Playing!')}>
        Play Movie
      </Button>
      <Button onClick={() => alert('Uploading!')}>
        Upload Image
      </Button>
    </div>
  );
}
```

```
<div onClickCapture={() => { /* this runs first */ }}>

  <button onClick={e => e.stopPropagation()} />

  <button onClick={e => e.stopPropagation()} />

</div>
```

```
function Button({ onClick, children }) {

  return (

    <button onClick={e => {

      e.stopPropagation();

      onClick();

    }}>

      {children}

    </button>

  );

}
```

You could add more code to this handler before calling the parent `onClick` event handler, too. This pattern provides an *alternative* to propagation. It lets the child component handle the event, while also letting the parent component specify some additional behavior. Unlike propagation, it’s not automatic. But the benefit of this pattern is that you can clearly follow the whole chain of code that executes as a result of some event.

If you rely on propagation and it’s difficult to trace which handlers execute and why, try this approach instead.

### Preventing default behavior[](#preventing-default-behavior "Link for Preventing default behavior ")

Some browser events have default behavior associated with them. For example, a `<form>` submit event, which happens when a button inside of it is clicked, will reload the whole page by default:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
export default function Signup() {
  return (
    <form onSubmit={() => alert('Submitting!')}>
      <input />
      <button>Send</button>
    </form>
  );
}
```

You can call `e.preventDefault()` on the event object to stop this from happening:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
export default function Signup() {
  return (
    <form onSubmit={e => {
      e.preventDefault();
      alert('Submitting!');
    }}>
      <input />
      <button>Send</button>
    </form>
  );
}
```

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
export default function LightSwitch() {
  function handleClick() {
    let bodyStyle = document.body.style;
    if (bodyStyle.backgroundColor === 'black') {
      bodyStyle.backgroundColor = 'white';
    } else {
      bodyStyle.backgroundColor = 'black';
    }
  }

  return (
    <button onClick={handleClick()}>
      Toggle the lights
    </button>
  );
}
```

[PreviousAdding Interactivity](/learn/adding-interactivity)

[NextState: A Component's Memory](/learn/state-a-components-memory)

***

----
url: https://react.dev/reference/react-dom/preloadModule
----

[API Reference](/reference/react)

[APIs](/reference/react-dom)

# preloadModule[](#undefined "Link for this heading")

### Note

[React-based frameworks](/learn/creating-a-react-app) frequently handle resource loading for you, so you might not have to call this API yourself. Consult your framework’s documentation for details.

`preloadModule` lets you eagerly fetch an ESM module that you expect to use.

```
preloadModule("https://example.com/module.js", {as: "script"});
```

* [Reference](#reference)
  * [`preloadModule(href, options)`](#preloadmodule)

* [Usage](#usage)

  * [Preloading when rendering](#preloading-when-rendering)
  * [Preloading in an event handler](#preloading-in-an-event-handler)

***

## Reference[](#reference "Link for Reference ")

### `preloadModule(href, options)`[](#preloadmodule "Link for this heading")

To preload an ESM module, call the `preloadModule` function from `react-dom`.

```
import { preloadModule } from 'react-dom';



function AppRoot() {

  preloadModule("https://example.com/module.js", {as: "script"});

  // ...

}
```

***

## Usage[](#usage "Link for Usage ")

### Preloading when rendering[](#preloading-when-rendering "Link for Preloading when rendering ")

Call `preloadModule` when rendering a component if you know that it or its children will use a specific module.

```
import { preloadModule } from 'react-dom';



function AppRoot() {

  preloadModule("https://example.com/module.js", {as: "script"});

  return ...;

}
```

If you want the browser to start executing the module immediately (rather than just downloading it), use [`preinitModule`](/reference/react-dom/preinitModule) instead. If you want to load a script that isn’t an ESM module, use [`preload`](/reference/react-dom/preload).

### Preloading in an event handler[](#preloading-in-an-event-handler "Link for Preloading in an event handler ")

Call `preloadModule` in an event handler before transitioning to a page or state where the module will be needed. This gets the process started earlier than if you call it during the rendering of the new page or state.

```
import { preloadModule } from 'react-dom';



function CallToAction() {

  const onClick = () => {

    preloadModule("https://example.com/module.js", {as: "script"});

    startWizard();

  }

  return (

    <button onClick={onClick}>Start Wizard</button>

  );

}
```

[Previouspreload](/reference/react-dom/preload)

[NextClient APIs](/reference/react-dom/client)

***

----
url: https://18.react.dev/reference/react-dom/preinitModule
----

[API Reference](/reference/react)

[APIs](/reference/react-dom)

# preinitModule[](#undefined "Link for this heading")

### Canary

The `preinitModule` function is currently only available in React’s Canary and experimental channels. Learn more about [React’s release channels here](/community/versioning-policy#all-release-channels).

### Note

[React-based frameworks](/learn/start-a-new-react-project) frequently handle resource loading for you, so you might not have to call this API yourself. Consult your framework’s documentation for details.

`preinitModule` lets you eagerly fetch and evaluate an ESM module.

```
preinitModule("https://example.com/module.js", {as: "script"});
```

* [Reference](#reference)
  * [`preinitModule(href, options)`](#preinitmodule)

* [Usage](#usage)

  * [Preloading when rendering](#preloading-when-rendering)
  * [Preloading in an event handler](#preloading-in-an-event-handler)

***

## Reference[](#reference "Link for Reference ")

### `preinitModule(href, options)`[](#preinitmodule "Link for this heading")

To preinit an ESM module, call the `preinitModule` function from `react-dom`.

```
import { preinitModule } from 'react-dom';



function AppRoot() {

  preinitModule("https://example.com/module.js", {as: "script"});

  // ...

}
```

***

## Usage[](#usage "Link for Usage ")

### Preloading when rendering[](#preloading-when-rendering "Link for Preloading when rendering ")

Call `preinitModule` when rendering a component if you know that it or its children will use a specific module and you’re OK with the module being evaluated and thereby taking effect immediately upon being downloaded.

```
import { preinitModule } from 'react-dom';



function AppRoot() {

  preinitModule("https://example.com/module.js", {as: "script"});

  return ...;

}
```

If you want the browser to download the module but not to execute it right away, use [`preloadModule`](/reference/react-dom/preloadModule) instead. If you want to preinit a script that isn’t an ESM module, use [`preinit`](/reference/react-dom/preinit).

### Preloading in an event handler[](#preloading-in-an-event-handler "Link for Preloading in an event handler ")

Call `preinitModule` in an event handler before transitioning to a page or state where the module will be needed. This gets the process started earlier than if you call it during the rendering of the new page or state.

```
import { preinitModule } from 'react-dom';



function CallToAction() {

  const onClick = () => {

    preinitModule("https://example.com/module.js", {as: "script"});

    startWizard();

  }

  return (

    <button onClick={onClick}>Start Wizard</button>

  );

}
```

[Previouspreinit](/reference/react-dom/preinit)

[Nextpreload](/reference/react-dom/preload)

***

----
url: https://legacy.reactjs.org/docs/lifting-state-up.html
----

> These docs are old and won’t be updated. Go to [react.dev](https://react.dev/) for the new React docs.
>
> These new documentation pages teach modern React and include live examples:
>
> * [Sharing State Between Components](https://react.dev/learn/sharing-state-between-components)

Often, several components need to reflect the same changing data. We recommend lifting the shared state up to their closest common ancestor. Let’s see how this works in action.

In this section, we will create a temperature calculator that calculates whether the water would boil at a given temperature.

We will start with a component called `BoilingVerdict`. It accepts the `celsius` temperature as a prop, and prints whether it is enough to boil the water:

```
function BoilingVerdict(props) {
  if (props.celsius >= 100) {
    return <p>The water would boil.</p>;  }
  return <p>The water would not boil.</p>;}
```

Next, we will create a component called `Calculator`. It renders an `<input>` that lets you enter the temperature, and keeps its value in `this.state.temperature`.

Additionally, it renders the `BoilingVerdict` for the current input value.

```
class Calculator extends React.Component {
  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
    this.state = {temperature: ''};  }

  handleChange(e) {
    this.setState({temperature: e.target.value});  }

  render() {
    const temperature = this.state.temperature;    return (
      <fieldset>
        <legend>Enter temperature in Celsius:</legend>
        <input          value={temperature}          onChange={this.handleChange} />        <BoilingVerdict          celsius={parseFloat(temperature)} />      </fieldset>
    );
  }
}
```

[**Try it on CodePen**](https://codepen.io/gaearon/pen/ZXeOBm?editors=0010)

## [](#adding-a-second-input)Adding a Second Input

Our new requirement is that, in addition to a Celsius input, we provide a Fahrenheit input, and they are kept in sync.

We can start by extracting a `TemperatureInput` component from `Calculator`. We will add a new `scale` prop to it that can either be `"c"` or `"f"`:

```
const scaleNames = {  c: 'Celsius',  f: 'Fahrenheit'};
class TemperatureInput extends React.Component {
  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
    this.state = {temperature: ''};
  }

  handleChange(e) {
    this.setState({temperature: e.target.value});
  }

  render() {
    const temperature = this.state.temperature;
    const scale = this.props.scale;    return (
      <fieldset>
        <legend>Enter temperature in {scaleNames[scale]}:</legend>        <input value={temperature}
               onChange={this.handleChange} />
      </fieldset>
    );
  }
}
```

We can now change the `Calculator` to render two separate temperature inputs:

```
class Calculator extends React.Component {
  render() {
    return (
      <div>
        <TemperatureInput scale="c" />        <TemperatureInput scale="f" />      </div>
    );
  }
}
```

[**Try it on CodePen**](https://codepen.io/gaearon/pen/jGBryx?editors=0010)

We have two inputs now, but when you enter the temperature in one of them, the other doesn’t update. This contradicts our requirement: we want to keep them in sync.

We also can’t display the `BoilingVerdict` from `Calculator`. The `Calculator` doesn’t know the current temperature because it is hidden inside the `TemperatureInput`.

## [](#writing-conversion-functions)Writing Conversion Functions

First, we will write two functions to convert from Celsius to Fahrenheit and back:

```
function toCelsius(fahrenheit) {
  return (fahrenheit - 32) * 5 / 9;
}

function toFahrenheit(celsius) {
  return (celsius * 9 / 5) + 32;
}
```

These two functions convert numbers. We will write another function that takes a string `temperature` and a converter function as arguments and returns a string. We will use it to calculate the value of one input based on the other input.

It returns an empty string on an invalid `temperature`, and it keeps the output rounded to the third decimal place:

```
function tryConvert(temperature, convert) {
  const input = parseFloat(temperature);
  if (Number.isNaN(input)) {
    return '';
  }
  const output = convert(input);
  const rounded = Math.round(output * 1000) / 1000;
  return rounded.toString();
}
```

For example, `tryConvert('abc', toCelsius)` returns an empty string, and `tryConvert('10.22', toFahrenheit)` returns `'50.396'`.

## [](#lifting-state-up)Lifting State Up

Currently, both `TemperatureInput` components independently keep their values in the local state:

```
class TemperatureInput extends React.Component {
  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
    this.state = {temperature: ''};  }

  handleChange(e) {
    this.setState({temperature: e.target.value});  }

  render() {
    const temperature = this.state.temperature;    // ...  
```

However, we want these two inputs to be in sync with each other. When we update the Celsius input, the Fahrenheit input should reflect the converted temperature, and vice versa.

In React, sharing state is accomplished by moving it up to the closest common ancestor of the components that need it. This is called “lifting state up”. We will remove the local state from the `TemperatureInput` and move it into the `Calculator` instead.

If the `Calculator` owns the shared state, it becomes the “source of truth” for the current temperature in both inputs. It can instruct them both to have values that are consistent with each other. Since the props of both `TemperatureInput` components are coming from the same parent `Calculator` component, the two inputs will always be in sync.

Let’s see how this works step by step.

First, we will replace `this.state.temperature` with `this.props.temperature` in the `TemperatureInput` component. For now, let’s pretend `this.props.temperature` already exists, although we will need to pass it from the `Calculator` in the future:

```
  render() {
    // Before: const temperature = this.state.temperature;
    const temperature = this.props.temperature;    // ...
```

We know that [props are read-only](/docs/components-and-props.html#props-are-read-only). When the `temperature` was in the local state, the `TemperatureInput` could just call `this.setState()` to change it. However, now that the `temperature` is coming from the parent as a prop, the `TemperatureInput` has no control over it.

In React, this is usually solved by making a component “controlled”. Just like the DOM `<input>` accepts both a `value` and an `onChange` prop, so can the custom `TemperatureInput` accept both `temperature` and `onTemperatureChange` props from its parent `Calculator`.

Now, when the `TemperatureInput` wants to update its temperature, it calls `this.props.onTemperatureChange`:

```
  handleChange(e) {
    // Before: this.setState({temperature: e.target.value});
    this.props.onTemperatureChange(e.target.value);    // ...
```

> Note:
>
> There is no special meaning to either `temperature` or `onTemperatureChange` prop names in custom components. We could have called them anything else, like name them `value` and `onChange` which is a common convention.

The `onTemperatureChange` prop will be provided together with the `temperature` prop by the parent `Calculator` component. It will handle the change by modifying its own local state, thus re-rendering both inputs with the new values. We will look at the new `Calculator` implementation very soon.

Before diving into the changes in the `Calculator`, let’s recap our changes to the `TemperatureInput` component. We have removed the local state from it, and instead of reading `this.state.temperature`, we now read `this.props.temperature`. Instead of calling `this.setState()` when we want to make a change, we now call `this.props.onTemperatureChange()`, which will be provided by the `Calculator`:

```
class TemperatureInput extends React.Component {
  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
  }

  handleChange(e) {
    this.props.onTemperatureChange(e.target.value);  }

  render() {
    const temperature = this.props.temperature;    const scale = this.props.scale;
    return (
      <fieldset>
        <legend>Enter temperature in {scaleNames[scale]}:</legend>
        <input value={temperature}
               onChange={this.handleChange} />
      </fieldset>
    );
  }
}
```

Now let’s turn to the `Calculator` component.

We will store the current input’s `temperature` and `scale` in its local state. This is the state we “lifted up” from the inputs, and it will serve as the “source of truth” for both of them. It is the minimal representation of all the data we need to know in order to render both inputs.

For example, if we enter 37 into the Celsius input, the state of the `Calculator` component will be:

```
{
  temperature: '37',
  scale: 'c'
}
```

If we later edit the Fahrenheit field to be 212, the state of the `Calculator` will be:

```
{
  temperature: '212',
  scale: 'f'
}
```

We could have stored the value of both inputs but it turns out to be unnecessary. It is enough to store the value of the most recently changed input, and the scale that it represents. We can then infer the value of the other input based on the current `temperature` and `scale` alone.

The inputs stay in sync because their values are computed from the same state:

```
class Calculator extends React.Component {
  constructor(props) {
    super(props);
    this.handleCelsiusChange = this.handleCelsiusChange.bind(this);
    this.handleFahrenheitChange = this.handleFahrenheitChange.bind(this);
    this.state = {temperature: '', scale: 'c'};  }

  handleCelsiusChange(temperature) {
    this.setState({scale: 'c', temperature});  }

  handleFahrenheitChange(temperature) {
    this.setState({scale: 'f', temperature});  }

  render() {
    const scale = this.state.scale;    const temperature = this.state.temperature;    const celsius = scale === 'f' ? tryConvert(temperature, toCelsius) : temperature;    const fahrenheit = scale === 'c' ? tryConvert(temperature, toFahrenheit) : temperature;
    return (
      <div>
        <TemperatureInput
          scale="c"
          temperature={celsius}          onTemperatureChange={this.handleCelsiusChange} />        <TemperatureInput
          scale="f"
          temperature={fahrenheit}          onTemperatureChange={this.handleFahrenheitChange} />        <BoilingVerdict
          celsius={parseFloat(celsius)} />      </div>
    );
  }
}
```

[**Try it on CodePen**](https://codepen.io/gaearon/pen/WZpxpz?editors=0010)

Now, no matter which input you edit, `this.state.temperature` and `this.state.scale` in the `Calculator` get updated. One of the inputs gets the value as is, so any user input is preserved, and the other input value is always recalculated based on it.

Let’s recap what happens when you edit an input:

* React calls the function specified as `onChange` on the DOM `<input>`. In our case, this is the `handleChange` method in the `TemperatureInput` component.
* The `handleChange` method in the `TemperatureInput` component calls `this.props.onTemperatureChange()` with the new desired value. Its props, including `onTemperatureChange`, were provided by its parent component, the `Calculator`.
* When it previously rendered, the `Calculator` had specified that `onTemperatureChange` of the Celsius `TemperatureInput` is the `Calculator`’s `handleCelsiusChange` method, and `onTemperatureChange` of the Fahrenheit `TemperatureInput` is the `Calculator`’s `handleFahrenheitChange` method. So either of these two `Calculator` methods gets called depending on which input we edited.
* Inside these methods, the `Calculator` component asks React to re-render itself by calling `this.setState()` with the new input value and the current scale of the input we just edited.
* React calls the `Calculator` component’s `render` method to learn what the UI should look like. The values of both inputs are recomputed based on the current temperature and the active scale. The temperature conversion is performed here.
* React calls the `render` methods of the individual `TemperatureInput` components with their new props specified by the `Calculator`. It learns what their UI should look like.
* React calls the `render` method of the `BoilingVerdict` component, passing the temperature in Celsius as its props.
* React DOM updates the DOM with the boiling verdict and to match the desired input values. The input we just edited receives its current value, and the other input is updated to the temperature after conversion.

Every update goes through the same steps so the inputs stay in sync.

## [](#lessons-learned)Lessons Learned

There should be a single “source of truth” for any data that changes in a React application. Usually, the state is first added to the component that needs it for rendering. Then, if other components also need it, you can lift it up to their closest common ancestor. Instead of trying to sync the state between different components, you should rely on the [top-down data flow](/docs/state-and-lifecycle.html#the-data-flows-down).

Lifting state involves writing more “boilerplate” code than two-way binding approaches, but as a benefit, it takes less work to find and isolate bugs. Since any state “lives” in some component and that component alone can change it, the surface area for bugs is greatly reduced. Additionally, you can implement any custom logic to reject or transform user input.

If something can be derived from either props or state, it probably shouldn’t be in the state. For example, instead of storing both `celsiusValue` and `fahrenheitValue`, we store just the last edited `temperature` and its `scale`. The value of the other input can always be calculated from them in the `render()` method. This lets us clear or apply rounding to the other field without losing any precision in the user input.

When you see something wrong in the UI, you can use [React Developer Tools](https://github.com/facebook/react/tree/main/packages/react-devtools) to inspect the props and move up the tree until you find the component responsible for updating the state. This lets you trace the bugs to their source:

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/lifting-state-up.md)

* Previous article

  [Forms](/docs/forms.html)

* Next article

  [Composition vs Inheritance](/docs/composition-vs-inheritance.html)

----
url: https://legacy.reactjs.org/docs/dom-elements.html
----

> These docs are old and won’t be updated. Go to [react.dev](https://react.dev/) for the new React docs.
>
> These new documentation pages teach modern React and include live examples:
>
> * [Common components (e.g. `<div>`)](https://react.dev/reference/react-dom/components/common)
> * [`<input>`](https://react.dev/reference/react-dom/components/input)
> * [`<option>`](https://react.dev/reference/react-dom/components/option)
> * [`<progress>`](https://react.dev/reference/react-dom/components/progress)
> * [`<select>`](https://react.dev/reference/react-dom/components/select)
> * [`<textarea>`](https://react.dev/reference/react-dom/components/textarea)

React implements a browser-independent DOM system for performance and cross-browser compatibility. We took the opportunity to clean up a few rough edges in browser DOM implementations.

In React, all DOM properties and attributes (including event handlers) should be camelCased. For example, the HTML attribute `tabindex` corresponds to the attribute `tabIndex` in React. The exception is `aria-*` and `data-*` attributes, which should be lowercased. For example, you can keep `aria-label` as `aria-label`.

## [](#differences-in-attributes)Differences In Attributes

There are a number of attributes that work differently between React and HTML:

### [](#checked)checked

The `checked` attribute is supported by `<input>` components of type `checkbox` or `radio`. You can use it to set whether the component is checked. This is useful for building controlled components. `defaultChecked` is the uncontrolled equivalent, which sets whether the component is checked when it is first mounted.

### [](#classname)className

To specify a CSS class, use the `className` attribute. This applies to all regular DOM and SVG elements like `<div>`, `<a>`, and others.

If you use React with Web Components (which is uncommon), use the `class` attribute instead.

### [](#dangerouslysetinnerhtml)dangerouslySetInnerHTML

`dangerouslySetInnerHTML` is React’s replacement for using `innerHTML` in the browser DOM. In general, setting HTML from code is risky because it’s easy to inadvertently expose your users to a [cross-site scripting (XSS)](https://en.wikipedia.org/wiki/Cross-site_scripting) attack. So, you can set HTML directly from React, but you have to type out `dangerouslySetInnerHTML` and pass an object with a `__html` key, to remind yourself that it’s dangerous. For example:

```
function createMarkup() {
  return {__html: 'First &middot; Second'};
}

function MyComponent() {
  return <div dangerouslySetInnerHTML={createMarkup()} />;
}
```

### [](#htmlfor)htmlFor

Since `for` is a reserved word in JavaScript, React elements use `htmlFor` instead.

### [](#onchange)onChange

The `onChange` event behaves as you would expect it to: whenever a form field is changed, this event is fired. We intentionally do not use the existing browser behavior because `onChange` is a misnomer for its behavior and React relies on this event to handle user input in real time.

### [](#selected)selected

If you want to mark an `<option>` as selected, reference the value of that option in the `value` of its `<select>` instead. Check out [“The select Tag”](/docs/forms.html#the-select-tag) for detailed instructions.

### [](#style)style

> Note
>
> Some examples in the documentation use `style` for convenience, but **using the `style` attribute as the primary means of styling elements is generally not recommended.** In most cases, [`className`](#classname) should be used to reference classes defined in an external CSS stylesheet. `style` is most often used in React applications to add dynamically-computed styles at render time. See also [FAQ: Styling and CSS](/docs/faq-styling.html).

The `style` attribute accepts a JavaScript object with camelCased properties rather than a CSS string. This is consistent with the DOM `style` JavaScript property, is more efficient, and prevents XSS security holes. For example:

```
const divStyle = {
  color: 'blue',
  backgroundImage: 'url(' + imgUrl + ')',
};

function HelloWorldComponent() {
  return <div style={divStyle}>Hello World!</div>;
}
```

Note that styles are not autoprefixed. To support older browsers, you need to supply corresponding style properties:

```
const divStyle = {
  WebkitTransition: 'all', // note the capital 'W' here
  msTransition: 'all' // 'ms' is the only lowercase vendor prefix
};

function ComponentWithTransition() {
  return <div style={divStyle}>This should work cross-browser</div>;
}
```

Style keys are camelCased in order to be consistent with accessing the properties on DOM nodes from JS (e.g. `node.style.backgroundImage`). Vendor prefixes [other than `ms`](https://www.andismith.com/blogs/2012/02/modernizr-prefixed/) should begin with a capital letter. This is why `WebkitTransition` has an uppercase “W”.

React will automatically append a “px” suffix to certain numeric inline style properties. If you want to use units other than “px”, specify the value as a string with the desired unit. For example:

```
// Result style: '10px'
<div style={{ height: 10 }}>
  Hello World!
</div>

// Result style: '10%'
<div style={{ height: '10%' }}>
  Hello World!
</div>
```

Not all style properties are converted to pixel strings though. Certain ones remain unitless (eg `zoom`, `order`, `flex`). A complete list of unitless properties can be seen [here](https://github.com/facebook/react/blob/4131af3e4bf52f3a003537ec95a1655147c81270/src/renderers/dom/shared/CSSProperty.js#L15-L59).

### [](#suppresscontenteditablewarning)suppressContentEditableWarning

Normally, there is a warning when an element with children is also marked as `contentEditable`, because it won’t work. This attribute suppresses that warning. Don’t use this unless you are building a library like [Draft.js](https://facebook.github.io/draft-js/) that manages `contentEditable` manually.

### [](#suppresshydrationwarning)suppressHydrationWarning

If you use server-side React rendering, normally there is a warning when the server and the client render different content. However, in some rare cases, it is very hard or impossible to guarantee an exact match. For example, timestamps are expected to differ on the server and on the client.

If you set `suppressHydrationWarning` to `true`, React will not warn you about mismatches in the attributes and the content of that element. It only works one level deep, and is intended to be used as an escape hatch. Don’t overuse it. You can read more about hydration in the [`ReactDOM.hydrateRoot()` documentation](/docs/react-dom-client.html#hydrateroot).

### [](#value)value

The `value` attribute is supported by `<input>`, `<select>` and `<textarea>` components. You can use it to set the value of the component. This is useful for building controlled components. `defaultValue` is the uncontrolled equivalent, which sets the value of the component when it is first mounted.

## [](#all-supported-html-attributes)All Supported HTML Attributes

As of React 16, any standard [or custom](/blog/2017/09/08/dom-attributes-in-react-16.html) DOM attributes are fully supported.

React has always provided a JavaScript-centric API to the DOM. Since React components often take both custom and DOM-related props, React uses the `camelCase` convention just like the DOM APIs:

```
<div tabIndex={-1} />      // Just like node.tabIndex DOM API
<div className="Button" /> // Just like node.className DOM API
<input readOnly={true} />  // Just like node.readOnly DOM API
```

These props work similarly to the corresponding HTML attributes, with the exception of the special cases documented above.

Some of the DOM attributes supported by React include:

```
accept acceptCharset accessKey action allowFullScreen alt async autoComplete
autoFocus autoPlay capture cellPadding cellSpacing challenge charSet checked
cite classID className colSpan cols content contentEditable contextMenu controls
controlsList coords crossOrigin data dateTime default defer dir disabled
download draggable encType form formAction formEncType formMethod formNoValidate
formTarget frameBorder headers height hidden high href hrefLang htmlFor
httpEquiv icon id inputMode integrity is keyParams keyType kind label lang list
loop low manifest marginHeight marginWidth max maxLength media mediaGroup method
min minLength multiple muted name noValidate nonce open optimum pattern
placeholder poster preload profile radioGroup readOnly rel required reversed
role rowSpan rows sandbox scope scoped scrolling seamless selected shape size
sizes span spellCheck src srcDoc srcLang srcSet start step style summary
tabIndex target title type useMap value width wmode wrap
```

Similarly, all SVG attributes are fully supported:

```
accentHeight accumulate additive alignmentBaseline allowReorder alphabetic
amplitude arabicForm ascent attributeName attributeType autoReverse azimuth
baseFrequency baseProfile baselineShift bbox begin bias by calcMode capHeight
clip clipPath clipPathUnits clipRule colorInterpolation
colorInterpolationFilters colorProfile colorRendering contentScriptType
contentStyleType cursor cx cy d decelerate descent diffuseConstant direction
display divisor dominantBaseline dur dx dy edgeMode elevation enableBackground
end exponent externalResourcesRequired fill fillOpacity fillRule filter
filterRes filterUnits floodColor floodOpacity focusable fontFamily fontSize
fontSizeAdjust fontStretch fontStyle fontVariant fontWeight format from fx fy
g1 g2 glyphName glyphOrientationHorizontal glyphOrientationVertical glyphRef
gradientTransform gradientUnits hanging horizAdvX horizOriginX ideographic
imageRendering in in2 intercept k k1 k2 k3 k4 kernelMatrix kernelUnitLength
kerning keyPoints keySplines keyTimes lengthAdjust letterSpacing lightingColor
limitingConeAngle local markerEnd markerHeight markerMid markerStart
markerUnits markerWidth mask maskContentUnits maskUnits mathematical mode
numOctaves offset opacity operator order orient orientation origin overflow
overlinePosition overlineThickness paintOrder panose1 pathLength
patternContentUnits patternTransform patternUnits pointerEvents points
pointsAtX pointsAtY pointsAtZ preserveAlpha preserveAspectRatio primitiveUnits
r radius refX refY renderingIntent repeatCount repeatDur requiredExtensions
requiredFeatures restart result rotate rx ry scale seed shapeRendering slope
spacing specularConstant specularExponent speed spreadMethod startOffset
stdDeviation stemh stemv stitchTiles stopColor stopOpacity
strikethroughPosition strikethroughThickness string stroke strokeDasharray
strokeDashoffset strokeLinecap strokeLinejoin strokeMiterlimit strokeOpacity
strokeWidth surfaceScale systemLanguage tableValues targetX targetY textAnchor
textDecoration textLength textRendering to transform u1 u2 underlinePosition
underlineThickness unicode unicodeBidi unicodeRange unitsPerEm vAlphabetic
vHanging vIdeographic vMathematical values vectorEffect version vertAdvY
vertOriginX vertOriginY viewBox viewTarget visibility widths wordSpacing
writingMode x x1 x2 xChannelSelector xHeight xlinkActuate xlinkArcrole
xlinkHref xlinkRole xlinkShow xlinkTitle xlinkType xmlns xmlnsXlink xmlBase
xmlLang xmlSpace y y1 y2 yChannelSelector z zoomAndPan
```

You may also use custom attributes as long as they’re fully lowercase.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/reference-dom-elements.md)

----
url: https://legacy.reactjs.org/blog/2014/12/19/react-js-conf-diversity-scholarship.html
----

December 19, 2014 by [Paul O’Shannessy](https://twitter.com/zpao)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

Today I’m really happy to announce the React.js Conf Diversity Scholarship! We believe that a diverse set of viewpoints and opinions is really important to build a thriving community. In an ideal world, every part of the tech community would be made up of people from all walks of life. However the reality is that we must be proactive and make an effort to make sure everybody has a voice. As conference organizers we worked closely with the Diversity Team here at Facebook to set aside 10 tickets and provide a scholarship. 10 tickets may not be many in the grand scheme but we really believe that this will have a positive impact on the discussions we have at the conference.

I’m really excited about this and I hope you are too! The full announcement is below:

***

The Diversity Team at Facebook is excited to announce that we are now accepting applications for the React.js Conf scholarship!

Beginning today, those studying or working in computer science or a related field can apply for an all-expense paid scholarship to attend the React.js Conf at Facebook’s Headquarters in Menlo Park, CA on January 28 & 29, 2015. React opens a world of new possibilities such as server-side rendering, real-time updates, different rendering targets like SVG and canvas. Join us at React.js Conf to shape the future of client-side applications! For more information about the React.js conference, please see the [website](http://conf.reactjs.com/) and [previous](/blog/2014/10/27/react-js-conf.html) [updates](/blog/2014/11/24/react-js-conf-updates.html) on our blog.

At Facebook, we believe that anyone anywhere can make a positive impact by developing products to make the world more open and connected to the people and things they care about. Given the current realities of the tech industry and the lack of representation of communities we seek to serve, applicants currently under-represented in Computer Science and related fields are strongly encouraged to apply. Facebook will make determinations on scholarship recipients in its sole discretion. Facebook complies with all equal opportunity laws.

To apply for the scholarship, please visit the Application Page: <https://www.surveymonkey.com/s/XVJGK6R>

## [](#award-includes)Award Includes

* Paid registration fee for the React.js Conf January 28 & 29th at Facebook’s Headquarters in Menlo Park, CA
* Paid travel and lodging expenses
* Additional $200 meal stipend

## [](#important-dates)Important Dates

* Monday, January 5, 2015: Applications for the React.js Conf Scholarship must be submitted in full
* Friday, January 9, 2015: Award recipients will be notified by email of their acceptance
* Wednesday & Thursday, January 28 & 29, 2015: React.js Conf

## [](#eligibility)Eligibility

* Must currently be studying or working in Computer Science or a related field
* International applicants are welcome, but you will be responsible for securing your own visa to attend the conference
* You must be available to attend the full duration of React.js conf on January 28 and 29 at Facebook Headquarters in Menlo Park

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2014-12-19-react-js-conf-diversity-scholarship.md)

----
url: https://18.react.dev/learn/extracting-state-logic-into-a-reducer
----

```
import { useState } from 'react';
import AddTask from './AddTask.js';
import TaskList from './TaskList.js';

export default function TaskApp() {
  const [tasks, setTasks] = useState(initialTasks);

  function handleAddTask(text) {
    setTasks([
      ...tasks,
      {
        id: nextId++,
        text: text,
        done: false,
      },
    ]);
  }

  function handleChangeTask(task) {
    setTasks(
      tasks.map((t) => {
        if (t.id === task.id) {
          return task;
        } else {
          return t;
        }
      })
    );
  }

  function handleDeleteTask(taskId) {
    setTasks(tasks.filter((t) => t.id !== taskId));
  }

  return (
    <>
      <h1>Prague itinerary</h1>
      <AddTask onAddTask={handleAddTask} />
      <TaskList
        tasks={tasks}
        onChangeTask={handleChangeTask}
        onDeleteTask={handleDeleteTask}
      />
    </>
  );
}

let nextId = 3;
const initialTasks = [
  {id: 0, text: 'Visit Kafka Museum', done: true},
  {id: 1, text: 'Watch a puppet show', done: false},
  {id: 2, text: 'Lennon Wall pic', done: false},
];
```

```
function handleAddTask(text) {

  setTasks([

    ...tasks,

    {

      id: nextId++,

      text: text,

      done: false,

    },

  ]);

}



function handleChangeTask(task) {

  setTasks(

    tasks.map((t) => {

      if (t.id === task.id) {

        return task;

      } else {

        return t;

      }

    })

  );

}



function handleDeleteTask(taskId) {

  setTasks(tasks.filter((t) => t.id !== taskId));

}
```

Remove all the state setting logic. What you are left with are three event handlers:

* `handleAddTask(text)` is called when the user presses “Add”.
* `handleChangeTask(task)` is called when the user toggles a task or presses “Save”.
* `handleDeleteTask(taskId)` is called when the user presses “Delete”.

Managing state with reducers is slightly different from directly setting state. Instead of telling React “what to do” by setting state, you specify “what the user just did” by dispatching “actions” from your event handlers. (The state update logic will live elsewhere!) So instead of “setting `tasks`” via an event handler, you’re dispatching an “added/changed/deleted a task” action. This is more descriptive of the user’s intent.

```
function handleAddTask(text) {

  dispatch({

    type: 'added',

    id: nextId++,

    text: text,

  });

}



function handleChangeTask(task) {

  dispatch({

    type: 'changed',

    task: task,

  });

}



function handleDeleteTask(taskId) {

  dispatch({

    type: 'deleted',

    id: taskId,

  });

}
```

The object you pass to `dispatch` is called an “action”:

```
function handleDeleteTask(taskId) {

  dispatch(

    // "action" object:

    {

      type: 'deleted',

      id: taskId,

    }

  );

}
```

It is a regular JavaScript object. You decide what to put in it, but generally it should contain the minimal information about *what happened*. (You will add the `dispatch` function itself in a later step.)

### Note

An action object can have any shape.

By convention, it is common to give it a string `type` that describes what happened, and pass any additional information in other fields. The `type` is specific to a component, so in this example either `'added'` or `'added_task'` would be fine. Choose a name that says what happened!

```
dispatch({

  // specific to component

  type: 'what_happened',

  // other fields go here

});
```

### Step 2: Write a reducer function[](#step-2-write-a-reducer-function "Link for Step 2: Write a reducer function ")

A reducer function is where you will put your state logic. It takes two arguments, the current state and the action object, and it returns the next state:

```
function yourReducer(state, action) {

  // return next state for React to set

}
```

React will set the state to what you return from the reducer.

To move your state setting logic from your event handlers to a reducer function in this example, you will:

1. Declare the current state (`tasks`) as the first argument.
2. Declare the `action` object as the second argument.
3. Return the *next* state from the reducer (which React will set the state to).

Here is all the state setting logic migrated to a reducer function:

```
function tasksReducer(tasks, action) {

  if (action.type === 'added') {

    return [

      ...tasks,

      {

        id: action.id,

        text: action.text,

        done: false,

      },

    ];

  } else if (action.type === 'changed') {

    return tasks.map((t) => {

      if (t.id === action.task.id) {

        return action.task;

      } else {

        return t;

      }

    });

  } else if (action.type === 'deleted') {

    return tasks.filter((t) => t.id !== action.id);

  } else {

    throw Error('Unknown action: ' + action.type);

  }

}
```

Because the reducer function takes state (`tasks`) as an argument, you can **declare it outside of your component.** This decreases the indentation level and can make your code easier to read.

### Note

The code above uses if/else statements, but it’s a convention to use [switch statements](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/switch) inside reducers. The result is the same, but it can be easier to read switch statements at a glance.

We’ll be using them throughout the rest of this documentation like so:

```
function tasksReducer(tasks, action) {

  switch (action.type) {

    case 'added': {

      return [

        ...tasks,

        {

          id: action.id,

          text: action.text,

          done: false,

        },

      ];

    }

    case 'changed': {

      return tasks.map((t) => {

        if (t.id === action.task.id) {

          return action.task;

        } else {

          return t;

        }

      });

    }

    case 'deleted': {

      return tasks.filter((t) => t.id !== action.id);

    }

    default: {

      throw Error('Unknown action: ' + action.type);

    }

  }

}
```

We recommend wrapping each `case` block into the `{` and `}` curly braces so that variables declared inside of different `case`s don’t clash with each other. Also, a `case` should usually end with a `return`. If you forget to `return`, the code will “fall through” to the next `case`, which can lead to mistakes!

If you’re not yet comfortable with switch statements, using if/else is completely fine.

##### Deep Dive#### Why are reducers called this way?[](#why-are-reducers-called-this-way "Link for Why are reducers called this way? ")

Although reducers can “reduce” the amount of code inside your component, they are actually named after the [`reduce()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce) operation that you can perform on arrays.

The `reduce()` operation lets you take an array and “accumulate” a single value out of many:

```
const arr = [1, 2, 3, 4, 5];

const sum = arr.reduce(

  (result, number) => result + number

); // 1 + 2 + 3 + 4 + 5
```

The function you pass to `reduce` is known as a “reducer”. It takes the *result so far* and the *current item,* then it returns the *next result.* React reducers are an example of the same idea: they take the *state so far* and the *action*, and return the *next state.* In this way, they accumulate actions over time into state.

You could even use the `reduce()` method with an `initialState` and an array of `actions` to calculate the final state by passing your reducer function to it:

```
import tasksReducer from './tasksReducer.js';

let initialState = [];
let actions = [
  {type: 'added', id: 1, text: 'Visit Kafka Museum'},
  {type: 'added', id: 2, text: 'Watch a puppet show'},
  {type: 'deleted', id: 1},
  {type: 'added', id: 3, text: 'Lennon Wall pic'},
];

let finalState = actions.reduce(tasksReducer, initialState);

const output = document.getElementById('output');
output.textContent = JSON.stringify(finalState, null, 2);
```

You probably won’t need to do this yourself, but this is similar to what React does!

### Step 3: Use the reducer from your component[](#step-3-use-the-reducer-from-your-component "Link for Step 3: Use the reducer from your component ")

Finally, you need to hook up the `tasksReducer` to your component. Import the `useReducer` Hook from React:

```
import { useReducer } from 'react';
```

Then you can replace `useState`:

```
const [tasks, setTasks] = useState(initialTasks);
```

with `useReducer` like so:

```
const [tasks, dispatch] = useReducer(tasksReducer, initialTasks);
```

```
import { useReducer } from 'react';
import AddTask from './AddTask.js';
import TaskList from './TaskList.js';

export default function TaskApp() {
  const [tasks, dispatch] = useReducer(tasksReducer, initialTasks);

  function handleAddTask(text) {
    dispatch({
      type: 'added',
      id: nextId++,
      text: text,
    });
  }

  function handleChangeTask(task) {
    dispatch({
      type: 'changed',
      task: task,
    });
  }

  function handleDeleteTask(taskId) {
    dispatch({
      type: 'deleted',
      id: taskId,
    });
  }

  return (
    <>
      <h1>Prague itinerary</h1>
      <AddTask onAddTask={handleAddTask} />
      <TaskList
        tasks={tasks}
        onChangeTask={handleChangeTask}
        onDeleteTask={handleDeleteTask}
      />
    </>
  );
}

function tasksReducer(tasks, action) {
  switch (action.type) {
    case 'added': {
      return [
        ...tasks,
        {
          id: action.id,
          text: action.text,
          done: false,
        },
      ];
    }
    case 'changed': {
      return tasks.map((t) => {
        if (t.id === action.task.id) {
          return action.task;
        } else {
          return t;
        }
      });
    }
    case 'deleted': {
      return tasks.filter((t) => t.id !== action.id);
    }
    default: {
      throw Error('Unknown action: ' + action.type);
    }
  }
}

let nextId = 3;
const initialTasks = [
  {id: 0, text: 'Visit Kafka Museum', done: true},
  {id: 1, text: 'Watch a puppet show', done: false},
  {id: 2, text: 'Lennon Wall pic', done: false},
];
```

If you want, you can even move the reducer to a different file:

```
import { useReducer } from 'react';
import AddTask from './AddTask.js';
import TaskList from './TaskList.js';
import tasksReducer from './tasksReducer.js';

export default function TaskApp() {
  const [tasks, dispatch] = useReducer(tasksReducer, initialTasks);

  function handleAddTask(text) {
    dispatch({
      type: 'added',
      id: nextId++,
      text: text,
    });
  }

  function handleChangeTask(task) {
    dispatch({
      type: 'changed',
      task: task,
    });
  }

  function handleDeleteTask(taskId) {
    dispatch({
      type: 'deleted',
      id: taskId,
    });
  }

  return (
    <>
      <h1>Prague itinerary</h1>
      <AddTask onAddTask={handleAddTask} />
      <TaskList
        tasks={tasks}
        onChangeTask={handleChangeTask}
        onDeleteTask={handleDeleteTask}
      />
    </>
  );
}

let nextId = 3;
const initialTasks = [
  {id: 0, text: 'Visit Kafka Museum', done: true},
  {id: 1, text: 'Watch a puppet show', done: false},
  {id: 2, text: 'Lennon Wall pic', done: false},
];
```

```
{
  "dependencies": {
    "immer": "1.7.3",
    "react": "latest",
    "react-dom": "latest",
    "react-scripts": "latest",
    "use-immer": "0.5.1"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject"
  },
  "devDependencies": {}
}
```

```
import { useReducer } from 'react';
import Chat from './Chat.js';
import ContactList from './ContactList.js';
import { initialState, messengerReducer } from './messengerReducer';

export default function Messenger() {
  const [state, dispatch] = useReducer(messengerReducer, initialState);
  const message = state.message;
  const contact = contacts.find((c) => c.id === state.selectedId);
  return (
    <div>
      <ContactList
        contacts={contacts}
        selectedId={state.selectedId}
        dispatch={dispatch}
      />
      <Chat
        key={contact.id}
        message={message}
        contact={contact}
        dispatch={dispatch}
      />
    </div>
  );
}

const contacts = [
  {id: 0, name: 'Taylor', email: 'taylor@mail.com'},
  {id: 1, name: 'Alice', email: 'alice@mail.com'},
  {id: 2, name: 'Bob', email: 'bob@mail.com'},
];
```

[PreviousPreserving and Resetting State](/learn/preserving-and-resetting-state)

[NextPassing Data Deeply with Context](/learn/passing-data-deeply-with-context)

***

----
url: https://react.dev/learn/passing-data-deeply-with-context
----

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import Heading from './Heading.js';
import Section from './Section.js';

export default function Page() {
  return (
    <Section>
      <Heading level={1}>Title</Heading>
      <Heading level={2}>Heading</Heading>
      <Heading level={3}>Sub-heading</Heading>
      <Heading level={4}>Sub-sub-heading</Heading>
      <Heading level={5}>Sub-sub-sub-heading</Heading>
      <Heading level={6}>Sub-sub-sub-sub-heading</Heading>
    </Section>
  );
}
```

Let’s say you want multiple headings within the same `Section` to always have the same size:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import Heading from './Heading.js';
import Section from './Section.js';

export default function Page() {
  return (
    <Section>
      <Heading level={1}>Title</Heading>
      <Section>
        <Heading level={2}>Heading</Heading>
        <Heading level={2}>Heading</Heading>
        <Heading level={2}>Heading</Heading>
        <Section>
          <Heading level={3}>Sub-heading</Heading>
          <Heading level={3}>Sub-heading</Heading>
          <Heading level={3}>Sub-heading</Heading>
          <Section>
            <Heading level={4}>Sub-sub-heading</Heading>
            <Heading level={4}>Sub-sub-heading</Heading>
            <Heading level={4}>Sub-sub-heading</Heading>
          </Section>
        </Section>
      </Section>
    </Section>
  );
}
```

Currently, you pass the `level` prop to each `<Heading>` separately:

```
<Section>

  <Heading level={3}>About</Heading>

  <Heading level={3}>Photos</Heading>

  <Heading level={3}>Videos</Heading>

</Section>
```

It would be nice if you could pass the `level` prop to the `<Section>` component instead and remove it from the `<Heading>`. This way you could enforce that all headings in the same section have the same size:

```
<Section level={3}>

  <Heading>About</Heading>

  <Heading>Photos</Heading>

  <Heading>Videos</Heading>

</Section>
```

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { createContext } from 'react';

export const LevelContext = createContext(1);
```

The only argument to `createContext` is the *default* value. Here, `1` refers to the biggest heading level, but you could pass any kind of value (even an object). You will see the significance of the default value in the next step.

### Step 2: Use the context[](#step-2-use-the-context "Link for Step 2: Use the context ")

Import the `useContext` Hook from React and your context:

```
import { useContext } from 'react';

import { LevelContext } from './LevelContext.js';
```

Currently, the `Heading` component reads `level` from props:

```
export default function Heading({ level, children }) {

  // ...

}
```

Instead, remove the `level` prop and read the value from the context you just imported, `LevelContext`:

```
export default function Heading({ children }) {

  const level = useContext(LevelContext);

  // ...

}
```

`useContext` is a Hook. Just like `useState` and `useReducer`, you can only call a Hook immediately inside a React component (not inside loops or conditions). **`useContext` tells React that the `Heading` component wants to read the `LevelContext`.**

Now that the `Heading` component doesn’t have a `level` prop, you don’t need to pass the level prop to `Heading` in your JSX like this anymore:

```
<Section>

  <Heading level={4}>Sub-sub-heading</Heading>

  <Heading level={4}>Sub-sub-heading</Heading>

  <Heading level={4}>Sub-sub-heading</Heading>

</Section>
```

Update the JSX so that it’s the `Section` that receives it instead:

```
<Section level={4}>

  <Heading>Sub-sub-heading</Heading>

  <Heading>Sub-sub-heading</Heading>

  <Heading>Sub-sub-heading</Heading>

</Section>
```

As a reminder, this is the markup that you were trying to get working:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import Heading from './Heading.js';
import Section from './Section.js';

export default function Page() {
  return (
    <Section level={1}>
      <Heading>Title</Heading>
      <Section level={2}>
        <Heading>Heading</Heading>
        <Heading>Heading</Heading>
        <Heading>Heading</Heading>
        <Section level={3}>
          <Heading>Sub-heading</Heading>
          <Heading>Sub-heading</Heading>
          <Heading>Sub-heading</Heading>
          <Section level={4}>
            <Heading>Sub-sub-heading</Heading>
            <Heading>Sub-sub-heading</Heading>
            <Heading>Sub-sub-heading</Heading>
          </Section>
        </Section>
      </Section>
    </Section>
  );
}
```

Notice this example doesn’t quite work, yet! All the headings have the same size because **even though you’re *using* the context, you have not *provided* it yet.** React doesn’t know where to get it!

If you don’t provide the context, React will use the default value you’ve specified in the previous step. In this example, you specified `1` as the argument to `createContext`, so `useContext(LevelContext)` returns `1`, setting all those headings to `<h1>`. Let’s fix this problem by having each `Section` provide its own context.

### Step 3: Provide the context[](#step-3-provide-the-context "Link for Step 3: Provide the context ")

The `Section` component currently renders its children:

```
export default function Section({ children }) {

  return (

    <section className="section">

      {children}

    </section>

  );

}
```

**Wrap them with a context provider** to provide the `LevelContext` to them:

```
import { LevelContext } from './LevelContext.js';



export default function Section({ level, children }) {

  return (

    <section className="section">

      <LevelContext value={level}>

        {children}

      </LevelContext>

    </section>

  );

}
```

This tells React: “if any component inside this `<Section>` asks for `LevelContext`, give them this `level`.” The component will use the value of the nearest `<LevelContext>` in the UI tree above it.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import Heading from './Heading.js';
import Section from './Section.js';

export default function Page() {
  return (
    <Section level={1}>
      <Heading>Title</Heading>
      <Section level={2}>
        <Heading>Heading</Heading>
        <Heading>Heading</Heading>
        <Heading>Heading</Heading>
        <Section level={3}>
          <Heading>Sub-heading</Heading>
          <Heading>Sub-heading</Heading>
          <Heading>Sub-heading</Heading>
          <Section level={4}>
            <Heading>Sub-sub-heading</Heading>
            <Heading>Sub-sub-heading</Heading>
            <Heading>Sub-sub-heading</Heading>
          </Section>
        </Section>
      </Section>
    </Section>
  );
}
```

It’s the same result as the original code, but you did not need to pass the `level` prop to each `Heading` component! Instead, it “figures out” its heading level by asking the closest `Section` above:

1. You pass a `level` prop to the `<Section>`.
2. `Section` wraps its children into `<LevelContext value={level}>`.
3. `Heading` asks the closest value of `LevelContext` above with `useContext(LevelContext)`.

## Using and providing context from the same component[](#using-and-providing-context-from-the-same-component "Link for Using and providing context from the same component ")

Currently, you still have to specify each section’s `level` manually:

```
export default function Page() {

  return (

    <Section level={1}>

      ...

      <Section level={2}>

        ...

        <Section level={3}>

          ...
```

Since context lets you read information from a component above, each `Section` could read the `level` from the `Section` above, and pass `level + 1` down automatically. Here is how you could do it:

```
import { useContext } from 'react';

import { LevelContext } from './LevelContext.js';



export default function Section({ children }) {

  const level = useContext(LevelContext);

  return (

    <section className="section">

      <LevelContext value={level + 1}>

        {children}

      </LevelContext>

    </section>

  );

}
```

With this change, you don’t need to pass the `level` prop *either* to the `<Section>` or to the `<Heading>`:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import Heading from './Heading.js';
import Section from './Section.js';

export default function Page() {
  return (
    <Section>
      <Heading>Title</Heading>
      <Section>
        <Heading>Heading</Heading>
        <Heading>Heading</Heading>
        <Heading>Heading</Heading>
        <Section>
          <Heading>Sub-heading</Heading>
          <Heading>Sub-heading</Heading>
          <Heading>Sub-heading</Heading>
          <Section>
            <Heading>Sub-sub-heading</Heading>
            <Heading>Sub-sub-heading</Heading>
            <Heading>Sub-sub-heading</Heading>
          </Section>
        </Section>
      </Section>
    </Section>
  );
}
```

Now both `Heading` and `Section` read the `LevelContext` to figure out how “deep” they are. And the `Section` wraps its children into the `LevelContext` to specify that anything inside of it is at a “deeper” level.

### Note

This example uses heading levels because they show visually how nested components can override context. But context is useful for many other use cases too. You can pass down any information needed by the entire subtree: the current color theme, the currently logged in user, and so on.

## Context passes through intermediate components[](#context-passes-through-intermediate-components "Link for Context passes through intermediate components ")

You can insert as many components as you like between the component that provides context and the one that uses it. This includes both built-in components like `<div>` and components you might build yourself.

In this example, the same `Post` component (with a dashed border) is rendered at two different nesting levels. Notice that the `<Heading>` inside of it gets its level automatically from the closest `<Section>`:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import Heading from './Heading.js';
import Section from './Section.js';

export default function ProfilePage() {
  return (
    <Section>
      <Heading>My Profile</Heading>
      <Post
        title="Hello traveller!"
        body="Read about my adventures."
      />
      <AllPosts />
    </Section>
  );
}

function AllPosts() {
  return (
    <Section>
      <Heading>Posts</Heading>
      <RecentPosts />
    </Section>
  );
}

function RecentPosts() {
  return (
    <Section>
      <Heading>Recent Posts</Heading>
      <Post
        title="Flavors of Lisbon"
        body="...those pastéis de nata!"
      />
      <Post
        title="Buenos Aires in the rhythm of tango"
        body="I loved it!"
      />
    </Section>
  );
}

function Post({ title, body }) {
  return (
    <Section isFancy={true}>
      <Heading>
        {title}
      </Heading>
      <p><i>{body}</i></p>
    </Section>
  );
}
```

  3. Wrap children into `<MyContext value={...}>` to provide it from a parent.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';
import { places } from './data.js';
import { getImageUrl } from './utils.js';

export default function App() {
  const [isLarge, setIsLarge] = useState(false);
  const imageSize = isLarge ? 150 : 100;
  return (
    <>
      <label>
        <input
          type="checkbox"
          checked={isLarge}
          onChange={e => {
            setIsLarge(e.target.checked);
          }}
        />
        Use large images
      </label>
      <hr />
      <List imageSize={imageSize} />
    </>
  )
}

function List({ imageSize }) {
  const listItems = places.map(place =>
    <li key={place.id}>
      <Place
        place={place}
        imageSize={imageSize}
      />
    </li>
  );
  return <ul>{listItems}</ul>;
}

function Place({ place, imageSize }) {
  return (
    <>
      <PlaceImage
        place={place}
        imageSize={imageSize}
      />
      <p>
        <b>{place.name}</b>
        {': ' + place.description}
      </p>
    </>
  );
}

function PlaceImage({ place, imageSize }) {
  return (
    <img
      src={getImageUrl(place)}
      alt={place.name}
      width={imageSize}
      height={imageSize}
    />
  );
}
```

[PreviousExtracting State Logic into a Reducer](/learn/extracting-state-logic-into-a-reducer)

[NextScaling Up with Reducer and Context](/learn/scaling-up-with-reducer-and-context)

***

----
url: https://18.react.dev/reference/react/createRef
----

[API Reference](/reference/react)

[Legacy React APIs](/reference/react/legacy)

# createRef[](#undefined "Link for this heading")

### Pitfall

`createRef` is mostly used for [class components.](/reference/react/Component) Function components typically rely on [`useRef`](/reference/react/useRef) instead.

`createRef` creates a [ref](/learn/referencing-values-with-refs) object which can contain arbitrary value.

```
class MyInput extends Component {

  inputRef = createRef();

  // ...

}
```

* [Reference](#reference)
  * [`createRef()`](#createref)
* [Usage](#usage)
  * [Declaring a ref in a class component](#declaring-a-ref-in-a-class-component)
* [Alternatives](#alternatives)
  * [Migrating from a class with `createRef` to a function with `useRef`](#migrating-from-a-class-with-createref-to-a-function-with-useref)

***

## Reference[](#reference "Link for Reference ")

### `createRef()`[](#createref "Link for this heading")

Call `createRef` to declare a [ref](/learn/referencing-values-with-refs) inside a [class component.](/reference/react/Component)

```
import { createRef, Component } from 'react';



class MyComponent extends Component {

  intervalRef = createRef();

  inputRef = createRef();

  // ...
```

***

## Usage[](#usage "Link for Usage ")

### Declaring a ref in a class component[](#declaring-a-ref-in-a-class-component "Link for Declaring a ref in a class component ")

To declare a ref inside a [class component,](/reference/react/Component) call `createRef` and assign its result to a class field:

```
import { Component, createRef } from 'react';



class Form extends Component {

  inputRef = createRef();



  // ...

}
```

If you now pass `ref={this.inputRef}` to an `<input>` in your JSX, React will populate `this.inputRef.current` with the input DOM node. For example, here is how you make a button that focuses the input:

```
import { Component, createRef } from 'react';

export default class Form extends Component {
  inputRef = createRef();

  handleClick = () => {
    this.inputRef.current.focus();
  }

  render() {
    return (
      <>
        <input ref={this.inputRef} />
        <button onClick={this.handleClick}>
          Focus the input
        </button>
      </>
    );
  }
}
```

### Pitfall

`createRef` is mostly used for [class components.](/reference/react/Component) Function components typically rely on [`useRef`](/reference/react/useRef) instead.

***

## Alternatives[](#alternatives "Link for Alternatives ")

### Migrating from a class with `createRef` to a function with `useRef`[](#migrating-from-a-class-with-createref-to-a-function-with-useref "Link for this heading")

We recommend using function components instead of [class components](/reference/react/Component) in new code. If you have some existing class components using `createRef`, here is how you can convert them. This is the original code:

```
import { Component, createRef } from 'react';

export default class Form extends Component {
  inputRef = createRef();

  handleClick = () => {
    this.inputRef.current.focus();
  }

  render() {
    return (
      <>
        <input ref={this.inputRef} />
        <button onClick={this.handleClick}>
          Focus the input
        </button>
      </>
    );
  }
}
```

When you [convert this component from a class to a function,](/reference/react/Component#alternatives) replace calls to `createRef` with calls to [`useRef`:](/reference/react/useRef)

```
import { useRef } from 'react';

export default function Form() {
  const inputRef = useRef(null);

  function handleClick() {
    inputRef.current.focus();
  }

  return (
    <>
      <input ref={inputRef} />
      <button onClick={handleClick}>
        Focus the input
      </button>
    </>
  );
}
```

[PreviouscreateFactory](/reference/react/createFactory)

[NextisValidElement](/reference/react/isValidElement)

***

----
url: https://18.react.dev/community/docs-contributors
----

[Community](/community)

# Docs Contributors[](#undefined "Link for this heading")

React documentation is written and maintained by the [React team](/community/team) and [external contributors.](https://github.com/reactjs/react.dev/graphs/contributors) On this page, we’d like to thank a few people who’ve made significant contributions to this site.

## Content[](#content "Link for Content ")

* [Rachel Nabors](https://twitter.com/RachelNabors): editing, writing, illustrating
* [Dan Abramov](https://twitter.com/dan_abramov): writing, curriculum design

* [Dan Abramov](https://twitter.com/dan_abramov): site development
* [Rick Hanlon](https://twitter.com/rickhanlonii): site development
* [Harish Kumar](https://www.strek.in/): development and maintenance
* [Luna Ruan](https://twitter.com/lunaruan): sandbox improvements

We’d also like to thank countless alpha testers and community members who gave us feedback along the way.

[PreviousMeet the Team](/community/team)

[NextTranslations](/community/translations)

***

----
url: https://legacy.reactjs.org/blog/2018/03/27/update-on-async-rendering.html
----

March 27, 2018 by [Brian Vaughn](https://github.com/bvaughn)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

For over a year, the React team has been working to implement asynchronous rendering. Last month during his talk at JSConf Iceland, [Dan unveiled some of the exciting new possibilities async rendering unlocks](/blog/2018/03/01/sneak-peek-beyond-react-16.html). Now we’d like to share with you some of the lessons we’ve learned while working on these features, and some recipes to help prepare your components for async rendering when it launches.

One of the biggest lessons we’ve learned is that some of our legacy component lifecycles tend to encourage unsafe coding practices. They are:

* `componentWillMount`
* `componentWillReceiveProps`
* `componentWillUpdate`

These lifecycle methods have often been misunderstood and subtly misused; furthermore, we anticipate that their potential misuse may be more problematic with async rendering. Because of this, we will be adding an “UNSAFE\_” prefix to these lifecycles in an upcoming release. (Here, “unsafe” refers not to security but instead conveys that code using these lifecycles will be more likely to have bugs in future versions of React, especially once async rendering is enabled.)

## [](#gradual-migration-path)Gradual Migration Path

[React follows semantic versioning](/blog/2016/02/19/new-versioning-scheme.html), so this change will be gradual. Our current plan is:

* **16.3**: Introduce aliases for the unsafe lifecycles, `UNSAFE_componentWillMount`, `UNSAFE_componentWillReceiveProps`, and `UNSAFE_componentWillUpdate`. (Both the old lifecycle names and the new aliases will work in this release.)
* **A future 16.x release**: Enable deprecation warning for `componentWillMount`, `componentWillReceiveProps`, and `componentWillUpdate`. (Both the old lifecycle names and the new aliases will work in this release, but the old names will log a DEV-mode warning.)
* **17.0**: Remove `componentWillMount`, `componentWillReceiveProps`, and `componentWillUpdate` . (Only the new “UNSAFE\_” lifecycle names will work from this point forward.)

**Note that if you’re a React application developer, you don’t have to do anything about the legacy methods yet. The primary purpose of the upcoming version 16.3 release is to enable open source project maintainers to update their libraries in advance of any deprecation warnings. Those warnings will not be enabled until a future 16.x release.**

We maintain over 50,000 React components at Facebook, and we don’t plan to rewrite them all immediately. We understand that migrations take time. We will take the gradual migration path along with everyone in the React community.

If you don’t have the time to migrate or test these components, we recommend running a [“codemod”](https://medium.com/@cpojer/effective-javascript-codemods-5a6686bb46fb) script that renames them automatically:

```
cd your_project
npx react-codemod rename-unsafe-lifecycles
```

Learn more about this codemod on the [16.9.0 release post.](https://reactjs.org/blog/2019/08/08/react-v16.9.0.html#renaming-unsafe-lifecycle-methods)

***

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

## [](#migrating-from-legacy-lifecycles)Migrating from Legacy Lifecycles

If you’d like to start using the new component APIs introduced in React 16.3 (or if you’re a maintainer looking to update your library in advance) here are a few examples that we hope will help you to start thinking about components a bit differently. Over time, we plan to add additional “recipes” to our documentation that show how to perform common tasks in a way that avoids the problematic lifecycles.

Before we begin, here’s a quick overview of the lifecycle changes planned for version 16.3:

* We are **adding the following lifecycle aliases**: `UNSAFE_componentWillMount`, `UNSAFE_componentWillReceiveProps`, and `UNSAFE_componentWillUpdate`. (Both the old lifecycle names and the new aliases will be supported.)
* We are **introducing two new lifecycles**, static `getDerivedStateFromProps` and `getSnapshotBeforeUpdate`.

### [](#new-lifecycle-getderivedstatefromprops)New lifecycle: `getDerivedStateFromProps`

```
class Example extends React.Component {
  static getDerivedStateFromProps(props, state) {
    // ...
  }
}
```

The new static `getDerivedStateFromProps` lifecycle is invoked after a component is instantiated as well as before it is re-rendered. It can return an object to update `state`, or `null` to indicate that the new `props` do not require any `state` updates.

Together with `componentDidUpdate`, this new lifecycle should cover all use cases for the legacy `componentWillReceiveProps`.

> Note:
>
> Both the older `componentWillReceiveProps` and the new `getDerivedStateFromProps` methods add significant complexity to components. This often leads to [bugs](/blog/2018/06/07/you-probably-dont-need-derived-state.html#common-bugs-when-using-derived-state). Consider **[simpler alternatives to derived state](/blog/2018/06/07/you-probably-dont-need-derived-state.html)** to make components predictable and maintainable.

### [](#new-lifecycle-getsnapshotbeforeupdate)New lifecycle: `getSnapshotBeforeUpdate`

```
class Example extends React.Component {
  getSnapshotBeforeUpdate(prevProps, prevState) {
    // ...
  }
}
```

The new `getSnapshotBeforeUpdate` lifecycle is called right before mutations are made (e.g. before the DOM is updated). The return value for this lifecycle will be passed as the third parameter to `componentDidUpdate`. (This lifecycle isn’t often needed, but can be useful in cases like manually preserving scroll position during rerenders.)

Together with `componentDidUpdate`, this new lifecycle should cover all use cases for the legacy `componentWillUpdate`.

You can find their type signatures [in this gist](https://gist.github.com/gaearon/88634d27abbc4feeb40a698f760f3264).

We’ll look at examples of how both of these lifecycles can be used below.

## [](#examples)Examples

* [Initializing state](#initializing-state)
* [Fetching external data](#fetching-external-data)
* [Adding event listeners (or subscriptions)](#adding-event-listeners-or-subscriptions)
* [Updating `state` based on props](#updating-state-based-on-props)
* [Invoking external callbacks](#invoking-external-callbacks)
* [Side effects on props change](#side-effects-on-props-change)
* [Fetching external data when props change](#fetching-external-data-when-props-change)
* [Reading DOM properties before an update](#reading-dom-properties-before-an-update)

> Note
>
> For brevity, the examples below are written using the experimental class properties transform, but the same migration strategies apply without it.

### [](#initializing-state)Initializing state

This example shows a component with `setState` calls inside of `componentWillMount`:

```
// Before
class ExampleComponent extends React.Component {
  state = {};

  componentWillMount() {    this.setState({      currentColor: this.props.defaultColor,      palette: 'rgb',    });  }}
```

The simplest refactor for this type of component is to move state initialization to the constructor or to a property initializer, like so:

```
// After
class ExampleComponent extends React.Component {
  state = {    currentColor: this.props.defaultColor,    palette: 'rgb',  };}
```

### [](#fetching-external-data)Fetching external data

Here is an example of a component that uses `componentWillMount` to fetch external data:

```
// Before
class ExampleComponent extends React.Component {
  state = {
    externalData: null,
  };

  componentWillMount() {    this._asyncRequest = loadMyAsyncData().then(      externalData => {        this._asyncRequest = null;        this.setState({externalData});      }    );  }
  componentWillUnmount() {
    if (this._asyncRequest) {
      this._asyncRequest.cancel();
    }
  }

  render() {
    if (this.state.externalData === null) {
      // Render loading state ...
    } else {
      // Render real UI ...
    }
  }
}
```

The above code is problematic for both server rendering (where the external data won’t be used) and the upcoming async rendering mode (where the request might be initiated multiple times).

The recommended upgrade path for most use cases is to move data-fetching into `componentDidMount`:

```
// After
class ExampleComponent extends React.Component {
  state = {
    externalData: null,
  };

  componentDidMount() {    this._asyncRequest = loadMyAsyncData().then(      externalData => {        this._asyncRequest = null;        this.setState({externalData});      }    );  }
  componentWillUnmount() {
    if (this._asyncRequest) {
      this._asyncRequest.cancel();
    }
  }

  render() {
    if (this.state.externalData === null) {
      // Render loading state ...
    } else {
      // Render real UI ...
    }
  }
}
```

There is a common misconception that fetching in `componentWillMount` lets you avoid the first empty rendering state. In practice this was never true because React has always executed `render` immediately after `componentWillMount`. If the data is not available by the time `componentWillMount` fires, the first `render` will still show a loading state regardless of where you initiate the fetch. This is why moving the fetch to `componentDidMount` has no perceptible effect in the vast majority of cases.

> Note
>
> Some advanced use-cases (e.g. libraries like Relay) may want to experiment with eagerly prefetching async data. An example of how this can be done is available [here](https://gist.github.com/bvaughn/89700e525ff423a75ffb63b1b1e30a8f).
>
> In the longer term, the canonical way to fetch data in React components will likely be based on the “suspense” API [introduced at JSConf Iceland](/blog/2018/03/01/sneak-peek-beyond-react-16.html). Both simple data fetching solutions and libraries like Apollo and Relay will be able to use it under the hood. It is significantly less verbose than either of the above solutions, but will not be finalized in time for the 16.3 release.
>
> When supporting server rendering, it’s currently necessary to provide the data synchronously – `componentWillMount` was often used for this purpose but the constructor can be used as a replacement. The upcoming suspense APIs will make async data fetching cleanly possible for both client and server rendering.

### [](#adding-event-listeners-or-subscriptions)Adding event listeners (or subscriptions)

Here is an example of a component that subscribes to an external event dispatcher when mounting:

```
// Before
class ExampleComponent extends React.Component {
  componentWillMount() {    this.setState({      subscribedValue: this.props.dataSource.value,    });    // This is not safe; it can leak!    this.props.dataSource.subscribe(      this.handleSubscriptionChange    );  }
  componentWillUnmount() {
    this.props.dataSource.unsubscribe(
      this.handleSubscriptionChange
    );
  }

  handleSubscriptionChange = dataSource => {
    this.setState({
      subscribedValue: dataSource.value,
    });
  };
}
```

Unfortunately, this can cause memory leaks for server rendering (where `componentWillUnmount` will never be called) and async rendering (where rendering might be interrupted before it completes, causing `componentWillUnmount` not to be called).

People often assume that `componentWillMount` and `componentWillUnmount` are always paired, but that is not guaranteed. Only once `componentDidMount` has been called does React guarantee that `componentWillUnmount` will later be called for clean up.

For this reason, the recommended way to add listeners/subscriptions is to use the `componentDidMount` lifecycle:

```
// After
class ExampleComponent extends React.Component {
  state = {    subscribedValue: this.props.dataSource.value,  };  componentDidMount() {    // Event listeners are only safe to add after mount,    // So they won't leak if mount is interrupted or errors.    this.props.dataSource.subscribe(      this.handleSubscriptionChange    );    // External values could change between render and mount,    // In some cases it may be important to handle this case.    if (      this.state.subscribedValue !==      this.props.dataSource.value    ) {      this.setState({        subscribedValue: this.props.dataSource.value,      });    }  }
  componentWillUnmount() {
    this.props.dataSource.unsubscribe(
      this.handleSubscriptionChange
    );
  }

  handleSubscriptionChange = dataSource => {
    this.setState({
      subscribedValue: dataSource.value,
    });
  };
}
```

Sometimes it is important to update subscriptions in response to property changes. If you’re using a library like Redux or MobX, the library’s container component should handle this for you. For application authors, we’ve created a small library, [`create-subscription`](https://github.com/facebook/react/tree/main/packages/create-subscription), to help with this. We’ll publish it along with React 16.3.

Rather than passing a subscribable `dataSource` prop as we did in the example above, we could use `create-subscription` to pass in the subscribed value:

```
import {createSubscription} from 'create-subscription';

const Subscription = createSubscription({
  getCurrentValue(sourceProp) {
    // Return the current value of the subscription (sourceProp).
    return sourceProp.value;
  },

  subscribe(sourceProp, callback) {
    function handleSubscriptionChange() {
      callback(sourceProp.value);
    }

    // Subscribe (e.g. add an event listener) to the subscription (sourceProp).
    // Call callback(newValue) whenever a subscription changes.
    sourceProp.subscribe(handleSubscriptionChange);

    // Return an unsubscribe method.
    return function unsubscribe() {
      sourceProp.unsubscribe(handleSubscriptionChange);
    };
  },
});

// Rather than passing the subscribable source to our ExampleComponent,
// We could just pass the subscribed value directly:
<Subscription source={dataSource}>
  {value => <ExampleComponent subscribedValue={value} />}
</Subscription>;
```

> Note
>
> Libraries like Relay/Apollo should manage subscriptions manually with the same techniques as `create-subscription` uses under the hood (as referenced [here](https://gist.github.com/bvaughn/d569177d70b50b58bff69c3c4a5353f3)) in a way that is most optimized for their library usage.

### [](#updating-state-based-on-props)Updating `state` based on `props`

> Note:
>
> Both the older `componentWillReceiveProps` and the new `getDerivedStateFromProps` methods add significant complexity to components. This often leads to [bugs](/blog/2018/06/07/you-probably-dont-need-derived-state.html#common-bugs-when-using-derived-state). Consider **[simpler alternatives to derived state](/blog/2018/06/07/you-probably-dont-need-derived-state.html)** to make components predictable and maintainable.

Here is an example of a component that uses the legacy `componentWillReceiveProps` lifecycle to update `state` based on new `props` values:

```
// Before
class ExampleComponent extends React.Component {
  state = {
    isScrollingDown: false,
  };

  componentWillReceiveProps(nextProps) {    if (this.props.currentRow !== nextProps.currentRow) {      this.setState({        isScrollingDown:          nextProps.currentRow > this.props.currentRow,      });    }  }}
```

Although the above code is not problematic in itself, the `componentWillReceiveProps` lifecycle is often mis-used in ways that *do* present problems. Because of this, the method will be deprecated.

As of version 16.3, the recommended way to update `state` in response to `props` changes is with the new `static getDerivedStateFromProps` lifecycle. It is called when a component is created and each time it re-renders due to changes to props or state:

```
// After
class ExampleComponent extends React.Component {
  // Initialize state in constructor,
  // Or with a property initializer.
  state = {    isScrollingDown: false,    lastRow: null,  };
  static getDerivedStateFromProps(props, state) {    if (props.currentRow !== state.lastRow) {      return {        isScrollingDown: props.currentRow > state.lastRow,        lastRow: props.currentRow,      };    }
    // Return null to indicate no change to state.
    return null;
  }
}
```

You may notice in the example above that `props.currentRow` is mirrored in state (as `state.lastRow`). This enables `getDerivedStateFromProps` to access the previous props value in the same way as is done in `componentWillReceiveProps`.

You may wonder why we don’t just pass previous props as a parameter to `getDerivedStateFromProps`. We considered this option when designing the API, but ultimately decided against it for two reasons:

* A `prevProps` parameter would be null the first time `getDerivedStateFromProps` was called (after instantiation), requiring an if-not-null check to be added any time `prevProps` was accessed.
* Not passing the previous props to this function is a step toward freeing up memory in future versions of React. (If React does not need to pass previous props to lifecycles, then it does not need to keep the previous `props` object in memory.)

> Note
>
> If you’re writing a shared component, the [`react-lifecycles-compat`](https://github.com/reactjs/react-lifecycles-compat) polyfill enables the new `getDerivedStateFromProps` lifecycle to be used with older versions of React as well. [Learn more about how to use it below.](#open-source-project-maintainers)

### [](#invoking-external-callbacks)Invoking external callbacks

Here is an example of a component that calls an external function when its internal state changes:

```
// Before
class ExampleComponent extends React.Component {
  componentWillUpdate(nextProps, nextState) {    if (      this.state.someStatefulValue !==      nextState.someStatefulValue    ) {      nextProps.onChange(nextState.someStatefulValue);    }  }}
```

Sometimes people use `componentWillUpdate` out of a misplaced fear that by the time `componentDidUpdate` fires, it is “too late” to update the state of other components. This is not the case. React ensures that any `setState` calls that happen during `componentDidMount` and `componentDidUpdate` are flushed before the user sees the updated UI. In general, it is better to avoid cascading updates like this, but in some cases they are necessary (for example, if you need to position a tooltip after measuring the rendered DOM element).

Either way, it is unsafe to use `componentWillUpdate` for this purpose in async mode, because the external callback might get called multiple times for a single update. Instead, the `componentDidUpdate` lifecycle should be used since it is guaranteed to be invoked only once per update:

```
// After
class ExampleComponent extends React.Component {
  componentDidUpdate(prevProps, prevState) {    if (      this.state.someStatefulValue !==      prevState.someStatefulValue    ) {      this.props.onChange(this.state.someStatefulValue);    }  }}
```

### [](#side-effects-on-props-change)Side effects on props change

Similar to the [example above](#invoking-external-callbacks), sometimes components have side effects when `props` change.

```
// Before
class ExampleComponent extends React.Component {
  componentWillReceiveProps(nextProps) {    if (this.props.isVisible !== nextProps.isVisible) {      logVisibleChange(nextProps.isVisible);    }  }}
```

Like `componentWillUpdate`, `componentWillReceiveProps` might get called multiple times for a single update. For this reason it is important to avoid putting side effects in this method. Instead, `componentDidUpdate` should be used since it is guaranteed to be invoked only once per update:

```
// After
class ExampleComponent extends React.Component {
  componentDidUpdate(prevProps, prevState) {    if (this.props.isVisible !== prevProps.isVisible) {      logVisibleChange(this.props.isVisible);    }  }}
```

### [](#fetching-external-data-when-props-change)Fetching external data when `props` change

Here is an example of a component that fetches external data based on `props` values:

```
// Before
class ExampleComponent extends React.Component {
  state = {
    externalData: null,
  };

  componentDidMount() {
    this._loadAsyncData(this.props.id);
  }

  componentWillReceiveProps(nextProps) {    if (nextProps.id !== this.props.id) {      this.setState({externalData: null});      this._loadAsyncData(nextProps.id);    }  }
  componentWillUnmount() {
    if (this._asyncRequest) {
      this._asyncRequest.cancel();
    }
  }

  render() {
    if (this.state.externalData === null) {
      // Render loading state ...
    } else {
      // Render real UI ...
    }
  }

  _loadAsyncData(id) {
    this._asyncRequest = loadMyAsyncData(id).then(
      externalData => {
        this._asyncRequest = null;
        this.setState({externalData});
      }
    );
  }
}
```

The recommended upgrade path for this component is to move data updates into `componentDidUpdate`. You can also use the new `getDerivedStateFromProps` lifecycle to clear stale data before rendering the new props:

```
// After
class ExampleComponent extends React.Component {
  state = {
    externalData: null,
  };

  static getDerivedStateFromProps(props, state) {    // Store prevId in state so we can compare when props change.    // Clear out previously-loaded data (so we don't render stale stuff).    if (props.id !== state.prevId) {      return {        externalData: null,        prevId: props.id,      };    }    // No state update necessary    return null;  }
  componentDidMount() {
    this._loadAsyncData(this.props.id);
  }

  componentDidUpdate(prevProps, prevState) {    if (this.state.externalData === null) {      this._loadAsyncData(this.props.id);    }  }
  componentWillUnmount() {
    if (this._asyncRequest) {
      this._asyncRequest.cancel();
    }
  }

  render() {
    if (this.state.externalData === null) {
      // Render loading state ...
    } else {
      // Render real UI ...
    }
  }

  _loadAsyncData(id) {
    this._asyncRequest = loadMyAsyncData(id).then(
      externalData => {
        this._asyncRequest = null;
        this.setState({externalData});
      }
    );
  }
}
```

> Note
>
> If you’re using an HTTP library that supports cancellation, like [axios](https://www.npmjs.com/package/axios), then it’s simple to cancel an in-progress request when unmounting. For native Promises, you can use an approach like [the one shown here](https://gist.github.com/bvaughn/982ab689a41097237f6e9860db7ca8d6).

### [](#reading-dom-properties-before-an-update)Reading DOM properties before an update

Here is an example of a component that reads a property from the DOM before an update in order to maintain scroll position within a list:

```
class ScrollingList extends React.Component {
  listRef = null;
  previousScrollOffset = null;

  componentWillUpdate(nextProps, nextState) {    // Are we adding new items to the list?    // Capture the scroll position so we can adjust scroll later.    if (this.props.list.length < nextProps.list.length) {      this.previousScrollOffset =        this.listRef.scrollHeight - this.listRef.scrollTop;    }  }
  componentDidUpdate(prevProps, prevState) {    // If previousScrollOffset is set, we've just added new items.    // Adjust scroll so these new items don't push the old ones out of view.    if (this.previousScrollOffset !== null) {      this.listRef.scrollTop =        this.listRef.scrollHeight -        this.previousScrollOffset;      this.previousScrollOffset = null;    }  }
  render() {
    return (
      <div ref={this.setListRef}>
        {/* ...contents... */}
      </div>
    );
  }

  setListRef = ref => {
    this.listRef = ref;
  };
}
```

In the above example, `componentWillUpdate` is used to read the DOM property. However with async rendering, there may be delays between “render” phase lifecycles (like `componentWillUpdate` and `render`) and “commit” phase lifecycles (like `componentDidUpdate`). If the user does something like resize the window during this time, the `scrollHeight` value read from `componentWillUpdate` will be stale.

The solution to this problem is to use the new “commit” phase lifecycle, `getSnapshotBeforeUpdate`. This method gets called *immediately before* mutations are made (e.g. before the DOM is updated). It can return a value for React to pass as a parameter to `componentDidUpdate`, which gets called *immediately after* mutations.

The two lifecycles can be used together like this:

```
class ScrollingList extends React.Component {
  listRef = null;

  getSnapshotBeforeUpdate(prevProps, prevState) {    // Are we adding new items to the list?    // Capture the scroll position so we can adjust scroll later.    if (prevProps.list.length < this.props.list.length) {      return (        this.listRef.scrollHeight - this.listRef.scrollTop      );    }    return null;  }
  componentDidUpdate(prevProps, prevState, snapshot) {    // If we have a snapshot value, we've just added new items.    // Adjust scroll so these new items don't push the old ones out of view.    // (snapshot here is the value returned from getSnapshotBeforeUpdate)    if (snapshot !== null) {      this.listRef.scrollTop =        this.listRef.scrollHeight - snapshot;    }  }

  render() {
    return (
      <div ref={this.setListRef}>
        {/* ...contents... */}
      </div>
    );
  }

  setListRef = ref => {
    this.listRef = ref;
  };
}
```

> Note
>
> If you’re writing a shared component, the [`react-lifecycles-compat`](https://github.com/reactjs/react-lifecycles-compat) polyfill enables the new `getSnapshotBeforeUpdate` lifecycle to be used with older versions of React as well. [Learn more about how to use it below.](#open-source-project-maintainers)

## [](#other-scenarios)Other scenarios

While we tried to cover the most common use cases in this post, we recognize that we might have missed some of them. If you are using `componentWillMount`, `componentWillUpdate`, or `componentWillReceiveProps` in ways that aren’t covered by this blog post, and aren’t sure how to migrate off these legacy lifecycles, please [file a new issue against our documentation](https://github.com/reactjs/reactjs.org/issues/new) with your code examples and as much background information as you can provide. We will update this document with new alternative patterns as they come up.

## [](#open-source-project-maintainers)Open source project maintainers

Open source maintainers might be wondering what these changes mean for shared components. If you implement the above suggestions, what happens with components that depend on the new static `getDerivedStateFromProps` lifecycle? Do you also have to release a new major version and drop compatibility for React 16.2 and older?

Fortunately, you do not!

When React 16.3 is published, we’ll also publish a new npm package, [`react-lifecycles-compat`](https://github.com/reactjs/react-lifecycles-compat). This package polyfills components so that the new `getDerivedStateFromProps` and `getSnapshotBeforeUpdate` lifecycles will also work with older versions of React (0.14.9+).

To use this polyfill, first add it as a dependency to your library:

```
# Yarn
yarn add react-lifecycles-compat

# NPM
npm install react-lifecycles-compat --save
```

Next, update your components to use the new lifecycles (as described above).

Lastly, use the polyfill to make your component backwards compatible with older versions of React:

```
import React from 'react';
import {polyfill} from 'react-lifecycles-compat';
class ExampleComponent extends React.Component {
  static getDerivedStateFromProps(props, state) {    // Your state update logic here ...
  }
}

// Polyfill your component to work with older versions of React:
polyfill(ExampleComponent);
export default ExampleComponent;
```

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2018-03-27-update-on-async-rendering.md)

----
url: https://legacy.reactjs.org/docs/faq-state.html
----

### [](#what-does-setstate-do)What does `setState` do?

`setState()` schedules an update to a component’s `state` object. When state changes, the component responds by re-rendering.

### [](#what-is-the-difference-between-state-and-props)What is the difference between `state` and `props`?

[`props`](/docs/components-and-props.html) (short for “properties”) and [`state`](/docs/state-and-lifecycle.html) are both plain JavaScript objects. While both hold information that influences the output of render, they are different in one important way: `props` get passed *to* the component (similar to function parameters) whereas `state` is managed *within* the component (similar to variables declared within a function).

Here are some good resources for further reading on when to use `props` vs `state`:

* [Props vs State](https://github.com/uberVU/react-guide/blob/master/props-vs-state.md)
* [ReactJS: Props vs. State](https://lucybain.com/blog/2016/react-state-vs-pros/)

### [](#why-is-setstate-giving-me-the-wrong-value)Why is `setState` giving me the wrong value?

In React, both `this.props` and `this.state` represent the *rendered* values, i.e. what’s currently on the screen.

Calls to `setState` are asynchronous - don’t rely on `this.state` to reflect the new value immediately after calling `setState`. Pass an updater function instead of an object if you need to compute values based on the current state (see below for details).

Example of code that will *not* behave as expected:

```
incrementCount() {
  // Note: this will *not* work as intended.
  this.setState({count: this.state.count + 1});
}

handleSomething() {
  // Let's say `this.state.count` starts at 0.
  this.incrementCount();
  this.incrementCount();
  this.incrementCount();
  // When React re-renders the component, `this.state.count` will be 1, but you expected 3.

  // This is because `incrementCount()` function above reads from `this.state.count`,
  // but React doesn't update `this.state.count` until the component is re-rendered.
  // So `incrementCount()` ends up reading `this.state.count` as 0 every time, and sets it to 1.

  // The fix is described below!
}
```

See below for how to fix this problem.

### [](#how-do-i-update-state-with-values-that-depend-on-the-current-state)How do I update state with values that depend on the current state?

Pass a function instead of an object to `setState` to ensure the call always uses the most updated version of state (see below).

### [](#what-is-the-difference-between-passing-an-object-or-a-function-in-setstate)What is the difference between passing an object or a function in `setState`?

Passing an update function allows you to access the current state value inside the updater. Since `setState` calls are batched, this lets you chain updates and ensure they build on top of each other instead of conflicting:

```
incrementCount() {
  this.setState((state) => {
    // Important: read `state` instead of `this.state` when updating.
    return {count: state.count + 1}
  });
}

handleSomething() {
  // Let's say `this.state.count` starts at 0.
  this.incrementCount();
  this.incrementCount();
  this.incrementCount();

  // If you read `this.state.count` now, it would still be 0.
  // But when React re-renders the component, it will be 3.
}
```

[Learn more about setState](/docs/react-component.html#setstate)

### [](#when-is-setstate-asynchronous)When is `setState` asynchronous?

Currently, `setState` is asynchronous inside event handlers.

This ensures, for example, that if both `Parent` and `Child` call `setState` during a click event, `Child` isn’t re-rendered twice. Instead, React “flushes” the state updates at the end of the browser event. This results in significant performance improvements in larger apps.

This is an implementation detail so avoid relying on it directly. In the future versions, React will batch updates by default in more cases.

### [](#why-doesnt-react-update-thisstate-synchronously)Why doesn’t React update `this.state` synchronously?

As explained in the previous section, React intentionally “waits” until all components call `setState()` in their event handlers before starting to re-render. This boosts performance by avoiding unnecessary re-renders.

However, you might still be wondering why React doesn’t just update `this.state` immediately without re-rendering.

There are two main reasons:

* This would break the consistency between `props` and `state`, causing issues that are very hard to debug.
* This would make some of the new features we’re working on impossible to implement.

This [GitHub comment](https://github.com/facebook/react/issues/11527#issuecomment-360199710) dives deep into the specific examples.

### [](#should-i-use-a-state-management-library-like-redux-or-mobx)Should I use a state management library like Redux or MobX?

[Maybe.](https://redux.js.org/faq/general#when-should-i-use-redux)

It’s a good idea to get to know React first, before adding in additional libraries. You can build quite complex applications using only React.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/faq-state.md)

----
url: https://18.react.dev/learn/synchronizing-with-effects
----

```
import { useEffect } from 'react';
```

Then, call it at the top level of your component and put some code inside your Effect:

```
function MyComponent() {

  useEffect(() => {

    // Code here will run after *every* render

  });

  return <div />;

}
```

Every time your component renders, React will update the screen *and then* run the code inside `useEffect`. In other words, **`useEffect` “delays” a piece of code from running until that render is reflected on the screen.**

Let’s see how you can use an Effect to synchronize with an external system. Consider a `<VideoPlayer>` React component. It would be nice to control whether it’s playing or paused by passing an `isPlaying` prop to it:

```
<VideoPlayer isPlaying={isPlaying} />;
```

Your custom `VideoPlayer` component renders the built-in browser [`<video>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video) tag:

```
function VideoPlayer({ src, isPlaying }) {

  // TODO: do something with isPlaying

  return <video src={src} />;

}
```

However, the browser `<video>` tag does not have an `isPlaying` prop. The only way to control it is to manually call the [`play()`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/play) and [`pause()`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/pause) methods on the DOM element. **You need to synchronize the value of `isPlaying` prop, which tells whether the video *should* currently be playing, with calls like `play()` and `pause()`.**

We’ll need to first [get a ref](/learn/manipulating-the-dom-with-refs) to the `<video>` DOM node.

You might be tempted to try to call `play()` or `pause()` during rendering, but that isn’t correct:

```
import { useState, useRef, useEffect } from 'react';

function VideoPlayer({ src, isPlaying }) {
  const ref = useRef(null);

  if (isPlaying) {
    ref.current.play();  // Calling these while rendering isn't allowed.
  } else {
    ref.current.pause(); // Also, this crashes.
  }

  return <video ref={ref} src={src} loop playsInline />;
}

export default function App() {
  const [isPlaying, setIsPlaying] = useState(false);
  return (
    <>
      <button onClick={() => setIsPlaying(!isPlaying)}>
        {isPlaying ? 'Pause' : 'Play'}
      </button>
      <VideoPlayer
        isPlaying={isPlaying}
        src="https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4"
      />
    </>
  );
}
```

The reason this code isn’t correct is that it tries to do something with the DOM node during rendering. In React, [rendering should be a pure calculation](/learn/keeping-components-pure) of JSX and should not contain side effects like modifying the DOM.

Moreover, when `VideoPlayer` is called for the first time, its DOM does not exist yet! There isn’t a DOM node yet to call `play()` or `pause()` on, because React doesn’t know what DOM to create until you return the JSX.

The solution here is to **wrap the side effect with `useEffect` to move it out of the rendering calculation:**

```
import { useEffect, useRef } from 'react';



function VideoPlayer({ src, isPlaying }) {

  const ref = useRef(null);



  useEffect(() => {

    if (isPlaying) {

      ref.current.play();

    } else {

      ref.current.pause();

    }

  });



  return <video ref={ref} src={src} loop playsInline />;

}
```

By wrapping the DOM update in an Effect, you let React update the screen first. Then your Effect runs.

When your `VideoPlayer` component renders (either the first time or if it re-renders), a few things will happen. First, React will update the screen, ensuring the `<video>` tag is in the DOM with the right props. Then React will run your Effect. Finally, your Effect will call `play()` or `pause()` depending on the value of `isPlaying`.

Press Play/Pause multiple times and see how the video player stays synchronized to the `isPlaying` value:

```
import { useState, useRef, useEffect } from 'react';

function VideoPlayer({ src, isPlaying }) {
  const ref = useRef(null);

  useEffect(() => {
    if (isPlaying) {
      ref.current.play();
    } else {
      ref.current.pause();
    }
  });

  return <video ref={ref} src={src} loop playsInline />;
}

export default function App() {
  const [isPlaying, setIsPlaying] = useState(false);
  return (
    <>
      <button onClick={() => setIsPlaying(!isPlaying)}>
        {isPlaying ? 'Pause' : 'Play'}
      </button>
      <VideoPlayer
        isPlaying={isPlaying}
        src="https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4"
      />
    </>
  );
}
```

In this example, the “external system” you synchronized to React state was the browser media API. You can use a similar approach to wrap legacy non-React code (like jQuery plugins) into declarative React components.

Note that controlling a video player is much more complex in practice. Calling `play()` may fail, the user might play or pause using the built-in browser controls, and so on. This example is very simplified and incomplete.

### Pitfall

By default, Effects run after *every* render. This is why code like this will **produce an infinite loop:**

```
const [count, setCount] = useState(0);

useEffect(() => {

  setCount(count + 1);

});
```

```
import { useState, useRef, useEffect } from 'react';

function VideoPlayer({ src, isPlaying }) {
  const ref = useRef(null);

  useEffect(() => {
    if (isPlaying) {
      console.log('Calling video.play()');
      ref.current.play();
    } else {
      console.log('Calling video.pause()');
      ref.current.pause();
    }
  });

  return <video ref={ref} src={src} loop playsInline />;
}

export default function App() {
  const [isPlaying, setIsPlaying] = useState(false);
  const [text, setText] = useState('');
  return (
    <>
      <input value={text} onChange={e => setText(e.target.value)} />
      <button onClick={() => setIsPlaying(!isPlaying)}>
        {isPlaying ? 'Pause' : 'Play'}
      </button>
      <VideoPlayer
        isPlaying={isPlaying}
        src="https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4"
      />
    </>
  );
}
```

You can tell React to **skip unnecessarily re-running the Effect** by specifying an array of *dependencies* as the second argument to the `useEffect` call. Start by adding an empty `[]` array to the above example on line 14:

```
  useEffect(() => {

    // ...

  }, []);
```

You should see an error saying `React Hook useEffect has a missing dependency: 'isPlaying'`:

```
import { useState, useRef, useEffect } from 'react';

function VideoPlayer({ src, isPlaying }) {
  const ref = useRef(null);

  useEffect(() => {
    if (isPlaying) {
      console.log('Calling video.play()');
      ref.current.play();
    } else {
      console.log('Calling video.pause()');
      ref.current.pause();
    }
  }, []); // This causes an error

  return <video ref={ref} src={src} loop playsInline />;
}

export default function App() {
  const [isPlaying, setIsPlaying] = useState(false);
  const [text, setText] = useState('');
  return (
    <>
      <input value={text} onChange={e => setText(e.target.value)} />
      <button onClick={() => setIsPlaying(!isPlaying)}>
        {isPlaying ? 'Pause' : 'Play'}
      </button>
      <VideoPlayer
        isPlaying={isPlaying}
        src="https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4"
      />
    </>
  );
}
```

The problem is that the code inside of your Effect *depends on* the `isPlaying` prop to decide what to do, but this dependency was not explicitly declared. To fix this issue, add `isPlaying` to the dependency array:

```
  useEffect(() => {

    if (isPlaying) { // It's used here...

      // ...

    } else {

      // ...

    }

  }, [isPlaying]); // ...so it must be declared here!
```

Now all dependencies are declared, so there is no error. Specifying `[isPlaying]` as the dependency array tells React that it should skip re-running your Effect if `isPlaying` is the same as it was during the previous render. With this change, typing into the input doesn’t cause the Effect to re-run, but pressing Play/Pause does:

```
import { useState, useRef, useEffect } from 'react';

function VideoPlayer({ src, isPlaying }) {
  const ref = useRef(null);

  useEffect(() => {
    if (isPlaying) {
      console.log('Calling video.play()');
      ref.current.play();
    } else {
      console.log('Calling video.pause()');
      ref.current.pause();
    }
  }, [isPlaying]);

  return <video ref={ref} src={src} loop playsInline />;
}

export default function App() {
  const [isPlaying, setIsPlaying] = useState(false);
  const [text, setText] = useState('');
  return (
    <>
      <input value={text} onChange={e => setText(e.target.value)} />
      <button onClick={() => setIsPlaying(!isPlaying)}>
        {isPlaying ? 'Pause' : 'Play'}
      </button>
      <VideoPlayer
        isPlaying={isPlaying}
        src="https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4"
      />
    </>
  );
}
```

The dependency array can contain multiple dependencies. React will only skip re-running the Effect if *all* of the dependencies you specify have exactly the same values as they had during the previous render. React compares the dependency values using the [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) comparison. See the [`useEffect` reference](/reference/react/useEffect#reference) for details.

**Notice that you can’t “choose” your dependencies.** You will get a lint error if the dependencies you specified don’t match what React expects based on the code inside your Effect. This helps catch many bugs in your code. If you don’t want some code to re-run, [*edit the Effect code itself* to not “need” that dependency.](/learn/lifecycle-of-reactive-effects#what-to-do-when-you-dont-want-to-re-synchronize)

### Pitfall

The behaviors without the dependency array and with an *empty* `[]` dependency array are different:

```
useEffect(() => {

  // This runs after every render

});



useEffect(() => {

  // This runs only on mount (when the component appears)

}, []);



useEffect(() => {

  // This runs on mount *and also* if either a or b have changed since the last render

}, [a, b]);
```

We’ll take a close look at what “mount” means in the next step.

##### Deep Dive#### Why was the ref omitted from the dependency array?[](#why-was-the-ref-omitted-from-the-dependency-array "Link for Why was the ref omitted from the dependency array? ")

This Effect uses *both* `ref` and `isPlaying`, but only `isPlaying` is declared as a dependency:

```
function VideoPlayer({ src, isPlaying }) {

  const ref = useRef(null);

  useEffect(() => {

    if (isPlaying) {

      ref.current.play();

    } else {

      ref.current.pause();

    }

  }, [isPlaying]);
```

This is because the `ref` object has a *stable identity:* React guarantees [you’ll always get the same object](/reference/react/useRef#returns) from the same `useRef` call on every render. It never changes, so it will never by itself cause the Effect to re-run. Therefore, it does not matter whether you include it or not. Including it is fine too:

```
function VideoPlayer({ src, isPlaying }) {

  const ref = useRef(null);

  useEffect(() => {

    if (isPlaying) {

      ref.current.play();

    } else {

      ref.current.pause();

    }

  }, [isPlaying, ref]);
```

The [`set` functions](/reference/react/useState#setstate) returned by `useState` also have stable identity, so you will often see them omitted from the dependencies too. If the linter lets you omit a dependency without errors, it is safe to do.

Omitting always-stable dependencies only works when the linter can “see” that the object is stable. For example, if `ref` was passed from a parent component, you would have to specify it in the dependency array. However, this is good because you can’t know whether the parent component always passes the same ref, or passes one of several refs conditionally. So your Effect *would* depend on which ref is passed.

### Step 3: Add cleanup if needed[](#step-3-add-cleanup-if-needed "Link for Step 3: Add cleanup if needed ")

Consider a different example. You’re writing a `ChatRoom` component that needs to connect to the chat server when it appears. You are given a `createConnection()` API that returns an object with `connect()` and `disconnect()` methods. How do you keep the component connected while it is displayed to the user?

Start by writing the Effect logic:

```
useEffect(() => {

  const connection = createConnection();

  connection.connect();

});
```

It would be slow to connect to the chat after every re-render, so you add the dependency array:

```
useEffect(() => {

  const connection = createConnection();

  connection.connect();

}, []);
```

**The code inside the Effect does not use any props or state, so your dependency array is `[]` (empty). This tells React to only run this code when the component “mounts”, i.e. appears on the screen for the first time.**

Let’s try running this code:

```
import { useEffect } from 'react';
import { createConnection } from './chat.js';

export default function ChatRoom() {
  useEffect(() => {
    const connection = createConnection();
    connection.connect();
  }, []);
  return <h1>Welcome to the chat!</h1>;
}
```

This Effect only runs on mount, so you might expect `"✅ Connecting..."` to be printed once in the console. **However, if you check the console, `"✅ Connecting..."` gets printed twice. Why does it happen?**

Imagine the `ChatRoom` component is a part of a larger app with many different screens. The user starts their journey on the `ChatRoom` page. The component mounts and calls `connection.connect()`. Then imagine the user navigates to another screen—for example, to the Settings page. The `ChatRoom` component unmounts. Finally, the user clicks Back and `ChatRoom` mounts again. This would set up a second connection—but the first connection was never destroyed! As the user navigates across the app, the connections would keep piling up.

Bugs like this are easy to miss without extensive manual testing. To help you spot them quickly, in development React remounts every component once immediately after its initial mount.

Seeing the `"✅ Connecting..."` log twice helps you notice the real issue: your code doesn’t close the connection when the component unmounts.

To fix the issue, return a *cleanup function* from your Effect:

```
  useEffect(() => {

    const connection = createConnection();

    connection.connect();

    return () => {

      connection.disconnect();

    };

  }, []);
```

React will call your cleanup function each time before the Effect runs again, and one final time when the component unmounts (gets removed). Let’s see what happens when the cleanup function is implemented:

```
import { useState, useEffect } from 'react';
import { createConnection } from './chat.js';

export default function ChatRoom() {
  useEffect(() => {
    const connection = createConnection();
    connection.connect();
    return () => connection.disconnect();
  }, []);
  return <h1>Welcome to the chat!</h1>;
}
```

```
  const connectionRef = useRef(null);

  useEffect(() => {

    // 🚩 This wont fix the bug!!!

    if (!connectionRef.current) {

      connectionRef.current = createConnection();

      connectionRef.current.connect();

    }

  }, []);
```

This makes it so you only see `"✅ Connecting..."` once in development, but it doesn’t fix the bug.

When the user navigates away, the connection still isn’t closed and when they navigate back, a new connection is created. As the user navigates across the app, the connections would keep piling up, the same as it would before the “fix”.

To fix the bug, it is not enough to just make the Effect run once. The effect needs to work after re-mounting, which means the connection needs to be cleaned up like in the solution above.

See the examples below for how to handle common patterns.

### Controlling non-React widgets[](#controlling-non-react-widgets "Link for Controlling non-React widgets ")

Sometimes you need to add UI widgets that aren’t written in React. For example, let’s say you’re adding a map component to your page. It has a `setZoomLevel()` method, and you’d like to keep the zoom level in sync with a `zoomLevel` state variable in your React code. Your Effect would look similar to this:

```
useEffect(() => {

  const map = mapRef.current;

  map.setZoomLevel(zoomLevel);

}, [zoomLevel]);
```

Note that there is no cleanup needed in this case. In development, React will call the Effect twice, but this is not a problem because calling `setZoomLevel` twice with the same value does not do anything. It may be slightly slower, but this doesn’t matter because it won’t remount needlessly in production.

Some APIs may not allow you to call them twice in a row. For example, the [`showModal`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLDialogElement/showModal) method of the built-in [`<dialog>`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLDialogElement) element throws if you call it twice. Implement the cleanup function and make it close the dialog:

```
useEffect(() => {

  const dialog = dialogRef.current;

  dialog.showModal();

  return () => dialog.close();

}, []);
```

In development, your Effect will call `showModal()`, then immediately `close()`, and then `showModal()` again. This has the same user-visible behavior as calling `showModal()` once, as you would see in production.

### Subscribing to events[](#subscribing-to-events "Link for Subscribing to events ")

If your Effect subscribes to something, the cleanup function should unsubscribe:

```
useEffect(() => {

  function handleScroll(e) {

    console.log(window.scrollX, window.scrollY);

  }

  window.addEventListener('scroll', handleScroll);

  return () => window.removeEventListener('scroll', handleScroll);

}, []);
```

In development, your Effect will call `addEventListener()`, then immediately `removeEventListener()`, and then `addEventListener()` again with the same handler. So there would be only one active subscription at a time. This has the same user-visible behavior as calling `addEventListener()` once, as in production.

### Triggering animations[](#triggering-animations "Link for Triggering animations ")

If your Effect animates something in, the cleanup function should reset the animation to the initial values:

```
useEffect(() => {

  const node = ref.current;

  node.style.opacity = 1; // Trigger the animation

  return () => {

    node.style.opacity = 0; // Reset to the initial value

  };

}, []);
```

In development, opacity will be set to `1`, then to `0`, and then to `1` again. This should have the same user-visible behavior as setting it to `1` directly, which is what would happen in production. If you use a third-party animation library with support for tweening, your cleanup function should reset the timeline to its initial state.

### Fetching data[](#fetching-data "Link for Fetching data ")

If your Effect fetches something, the cleanup function should either [abort the fetch](https://developer.mozilla.org/en-US/docs/Web/API/AbortController) or ignore its result:

```
useEffect(() => {

  let ignore = false;



  async function startFetching() {

    const json = await fetchTodos(userId);

    if (!ignore) {

      setTodos(json);

    }

  }



  startFetching();



  return () => {

    ignore = true;

  };

}, [userId]);
```

You can’t “undo” a network request that already happened, but your cleanup function should ensure that the fetch that’s *not relevant anymore* does not keep affecting your application. If the `userId` changes from `'Alice'` to `'Bob'`, cleanup ensures that the `'Alice'` response is ignored even if it arrives after `'Bob'`.

**In development, you will see two fetches in the Network tab.** There is nothing wrong with that. With the approach above, the first Effect will immediately get cleaned up so its copy of the `ignore` variable will be set to `true`. So even though there is an extra request, it won’t affect the state thanks to the `if (!ignore)` check.

**In production, there will only be one request.** If the second request in development is bothering you, the best approach is to use a solution that deduplicates requests and caches their responses between components:

```
function TodoList() {

  const todos = useSomeDataLibrary(`/api/user/${userId}/todos`);

  // ...
```

* **If you use a [framework](/learn/start-a-new-react-project#production-grade-react-frameworks), use its built-in data fetching mechanism.** Modern React frameworks have integrated data fetching mechanisms that are efficient and don’t suffer from the above pitfalls.
* **Otherwise, consider using or building a client-side cache.** Popular open source solutions include [React Query](https://tanstack.com/query/latest), [useSWR](https://swr.vercel.app/), and [React Router 6.4+.](https://beta.reactrouter.com/en/main/start/overview) You can build your own solution too, in which case you would use Effects under the hood, but add logic for deduplicating requests, caching responses, and avoiding network waterfalls (by preloading data or hoisting data requirements to routes).

You can continue fetching data directly in Effects if neither of these approaches suit you.

### Sending analytics[](#sending-analytics "Link for Sending analytics ")

Consider this code that sends an analytics event on the page visit:

```
useEffect(() => {

  logVisit(url); // Sends a POST request

}, [url]);
```

In development, `logVisit` will be called twice for every URL, so you might be tempted to try to fix that. **We recommend keeping this code as is.** Like with earlier examples, there is no *user-visible* behavior difference between running it once and running it twice. From a practical point of view, `logVisit` should not do anything in development because you don’t want the logs from the development machines to skew the production metrics. Your component remounts every time you save its file, so it logs extra visits in development anyway.

**In production, there will be no duplicate visit logs.**

To debug the analytics events you’re sending, you can deploy your app to a staging environment (which runs in production mode) or temporarily opt out of [Strict Mode](/reference/react/StrictMode) and its development-only remounting checks. You may also send analytics from the route change event handlers instead of Effects. For more precise analytics, [intersection observers](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API) can help track which components are in the viewport and how long they remain visible.

### Not an Effect: Initializing the application[](#not-an-effect-initializing-the-application "Link for Not an Effect: Initializing the application ")

Some logic should only run once when the application starts. You can put it outside your components:

```
if (typeof window !== 'undefined') { // Check if we're running in the browser.

  checkAuthToken();

  loadDataFromLocalStorage();

}



function App() {

  // ...

}
```

This guarantees that such logic only runs once after the browser loads the page.

### Not an Effect: Buying a product[](#not-an-effect-buying-a-product "Link for Not an Effect: Buying a product ")

Sometimes, even if you write a cleanup function, there’s no way to prevent user-visible consequences of running the Effect twice. For example, maybe your Effect sends a POST request like buying a product:

```
useEffect(() => {

  // 🔴 Wrong: This Effect fires twice in development, exposing a problem in the code.

  fetch('/api/buy', { method: 'POST' });

}, []);
```

You wouldn’t want to buy the product twice. However, this is also why you shouldn’t put this logic in an Effect. What if the user goes to another page and then presses Back? Your Effect would run again. You don’t want to buy the product when the user *visits* a page; you want to buy it when the user *clicks* the Buy button.

Buying is not caused by rendering; it’s caused by a specific interaction. It should run only when the user presses the button. **Delete the Effect and move your `/api/buy` request into the Buy button event handler:**

```
  function handleClick() {

    // ✅ Buying is an event because it is caused by a particular interaction.

    fetch('/api/buy', { method: 'POST' });

  }
```

**This illustrates that if remounting breaks the logic of your application, this usually uncovers existing bugs.** From a user’s perspective, visiting a page shouldn’t be different from visiting it, clicking a link, then pressing Back to view the page again. React verifies that your components abide by this principle by remounting them once in development.

## Putting it all together[](#putting-it-all-together "Link for Putting it all together ")

This playground can help you “get a feel” for how Effects work in practice.

This example uses [`setTimeout`](https://developer.mozilla.org/en-US/docs/Web/API/setTimeout) to schedule a console log with the input text to appear three seconds after the Effect runs. The cleanup function cancels the pending timeout. Start by pressing “Mount the component”:

```
import { useState, useEffect } from 'react';

function Playground() {
  const [text, setText] = useState('a');

  useEffect(() => {
    function onTimeout() {
      console.log('⏰ ' + text);
    }

    console.log('🔵 Schedule "' + text + '" log');
    const timeoutId = setTimeout(onTimeout, 3000);

    return () => {
      console.log('🟡 Cancel "' + text + '" log');
      clearTimeout(timeoutId);
    };
  }, [text]);

  return (
    <>
      <label>
        What to log:{' '}
        <input
          value={text}
          onChange={e => setText(e.target.value)}
        />
      </label>
      <h1>{text}</h1>
    </>
  );
}

export default function App() {
  const [show, setShow] = useState(false);
  return (
    <>
      <button onClick={() => setShow(!show)}>
        {show ? 'Unmount' : 'Mount'} the component
      </button>
      {show && <hr />}
      {show && <Playground />}
    </>
  );
}
```

```
export default function ChatRoom({ roomId }) {

  useEffect(() => {

    const connection = createConnection(roomId);

    connection.connect();

    return () => connection.disconnect();

  }, [roomId]);



  return <h1>Welcome to {roomId}!</h1>;

}
```

Let’s see what exactly happens as the user navigates around the app.

#### Initial render[](#initial-render "Link for Initial render ")

The user visits `<ChatRoom roomId="general" />`. Let’s [mentally substitute](/learn/state-as-a-snapshot#rendering-takes-a-snapshot-in-time) `roomId` with `'general'`:

```
  // JSX for the first render (roomId = "general")

  return <h1>Welcome to general!</h1>;
```

**The Effect is *also* a part of the rendering output.** The first render’s Effect becomes:

```
  // Effect for the first render (roomId = "general")

  () => {

    const connection = createConnection('general');

    connection.connect();

    return () => connection.disconnect();

  },

  // Dependencies for the first render (roomId = "general")

  ['general']
```

React runs this Effect, which connects to the `'general'` chat room.

#### Re-render with same dependencies[](#re-render-with-same-dependencies "Link for Re-render with same dependencies ")

Let’s say `<ChatRoom roomId="general" />` re-renders. The JSX output is the same:

```
  // JSX for the second render (roomId = "general")

  return <h1>Welcome to general!</h1>;
```

React sees that the rendering output has not changed, so it doesn’t update the DOM.

The Effect from the second render looks like this:

```
  // Effect for the second render (roomId = "general")

  () => {

    const connection = createConnection('general');

    connection.connect();

    return () => connection.disconnect();

  },

  // Dependencies for the second render (roomId = "general")

  ['general']
```

React compares `['general']` from the second render with `['general']` from the first render. **Because all dependencies are the same, React *ignores* the Effect from the second render.** It never gets called.

#### Re-render with different dependencies[](#re-render-with-different-dependencies "Link for Re-render with different dependencies ")

Then, the user visits `<ChatRoom roomId="travel" />`. This time, the component returns different JSX:

```
  // JSX for the third render (roomId = "travel")

  return <h1>Welcome to travel!</h1>;
```

React updates the DOM to change `"Welcome to general"` into `"Welcome to travel"`.

The Effect from the third render looks like this:

```
  // Effect for the third render (roomId = "travel")

  () => {

    const connection = createConnection('travel');

    connection.connect();

    return () => connection.disconnect();

  },

  // Dependencies for the third render (roomId = "travel")

  ['travel']
```

```
import { useEffect, useRef } from 'react';

export default function MyInput({ value, onChange }) {
  const ref = useRef(null);

  // TODO: This doesn't quite work. Fix it.
  // ref.current.focus()    

  return (
    <input
      ref={ref}
      value={value}
      onChange={onChange}
    />
  );
}
```

To verify that your solution works, press “Show form” and verify that the input receives focus (becomes highlighted and the cursor is placed inside). Press “Hide form” and “Show form” again. Verify the input is highlighted again.

`MyInput` should only focus *on mount* rather than after every render. To verify that the behavior is right, press “Show form” and then repeatedly press the “Make it uppercase” checkbox. Clicking the checkbox should *not* focus the input above it.

[PreviousManipulating the DOM with Refs](/learn/manipulating-the-dom-with-refs)

[NextYou Might Not Need an Effect](/learn/you-might-not-need-an-effect)

***

----
url: https://react.dev/reference/react/cacheSignal
----

[API Reference](/reference/react)

[APIs](/reference/react/apis)

# cacheSignal[](#undefined "Link for this heading")

### React Server Components

`cacheSignal` is currently only used with [React Server Components](/blog/2023/03/22/react-labs-what-we-have-been-working-on-march-2023#react-server-components).

`cacheSignal` allows you to know when the `cache()` lifetime is over.

```
const signal = cacheSignal();
```

* [Reference](#reference)
  * [`cacheSignal`](#cachesignal)

* [Usage](#usage)

  * [Cancel in-flight requests](#cancel-in-flight-requests)
  * [Ignore errors after React has finished rendering](#ignore-errors-after-react-has-finished-rendering)

***

## Reference[](#reference "Link for Reference ")

### `cacheSignal`[](#cachesignal "Link for this heading")

Call `cacheSignal` to get an `AbortSignal`.

```
import {cacheSignal} from 'react';

async function Component() {

  await fetch(url, { signal: cacheSignal() });

}
```

When React has finished rendering, the `AbortSignal` will be aborted. This allows you to cancel any in-flight work that is no longer needed. Rendering is considered finished when:

* React has successfully completed rendering
* the render was aborted
* the render has failed

#### Parameters[](#parameters "Link for Parameters ")

This function does not accept any parameters.

#### Returns[](#returns "Link for Returns ")

`cacheSignal` returns an `AbortSignal` if called during rendering. Otherwise `cacheSignal()` returns `null`.

#### Caveats[](#caveats "Link for Caveats ")

* `cacheSignal` is currently for use in [React Server Components](/reference/rsc/server-components) only. In Client Components, it will always return `null`. In the future it will also be used for Client Component when a client cache refreshes or invalidates. You should not assume it’ll always be null on the client.
* If called outside of rendering, `cacheSignal` will return `null` to make it clear that the current scope isn’t cached forever.

***

## Usage[](#usage "Link for Usage ")

### Cancel in-flight requests[](#cancel-in-flight-requests "Link for Cancel in-flight requests ")

Call `cacheSignal` to abort in-flight requests.

```
import {cache, cacheSignal} from 'react';

const dedupedFetch = cache(fetch);

async function Component() {

  await dedupedFetch(url, { signal: cacheSignal() });

}
```

### Pitfall

You can’t use `cacheSignal` to abort async work that was started outside of rendering e.g.

```
import {cacheSignal} from 'react';

// 🚩 Pitfall: The request will not actually be aborted if the rendering of `Component` is finished.

const response = fetch(url, { signal: cacheSignal() });

async function Component() {

  await response;

}
```

### Ignore errors after React has finished rendering[](#ignore-errors-after-react-has-finished-rendering "Link for Ignore errors after React has finished rendering ")

If a function throws, it may be due to cancellation (e.g. the Database connection has been closed). You can use the `aborted` property to check if the error was due to cancellation or a real error. You may want to ignore errors that were due to cancellation.

```
import {cacheSignal} from "react";

import {queryDatabase, logError} from "./database";



async function getData(id) {

  try {

     return await queryDatabase(id);

  } catch (x) {

     if (!cacheSignal()?.aborted) {

        // only log if it's a real error and not due to cancellation

       logError(x);

     }

     return null;

  }

}



async function Component({id}) {

  const data = await getData(id);

  if (data === null) {

    return <div>No data available</div>;

  }

  return <div>{data.name}</div>;

}
```

[Previouscache](/reference/react/cache)

[NextcaptureOwnerStack](/reference/react/captureOwnerStack)

***

----
url: https://react.dev/blog/2025/12/03/critical-security-vulnerability-in-react-server-components
----

[Blog](/blog)

# Critical Security Vulnerability in React Server Components[](#undefined "Link for this heading")

December 3, 2025 by [The React Team](/community/team)

***

There is an unauthenticated remote code execution vulnerability in React Server Components.

We recommend upgrading immediately.

***

On November 29th, Lachlan Davidson reported a security vulnerability in React that allows unauthenticated remote code execution by exploiting a flaw in how React decodes payloads sent to React Server Function endpoints.

Even if your app does not implement any React Server Function endpoints it may still be vulnerable if your app supports React Server Components.

This vulnerability was disclosed as [CVE-2025-55182](https://www.cve.org/CVERecord?id=CVE-2025-55182) and is rated CVSS 10.0.

The vulnerability is present in versions 19.0, 19.1.0, 19.1.1, and 19.2.0 of:

* [react-server-dom-webpack](https://www.npmjs.com/package/react-server-dom-webpack)
* [react-server-dom-parcel](https://www.npmjs.com/package/react-server-dom-parcel)
* [react-server-dom-turbopack](https://www.npmjs.com/package/react-server-dom-turbopack?activeTab=readme)

## Immediate Action Required[](#immediate-action-required "Link for Immediate Action Required ")

A fix was introduced in versions [19.0.1](https://github.com/facebook/react/releases/tag/v19.0.1), [19.1.2](https://github.com/facebook/react/releases/tag/v19.1.2), and [19.2.1](https://github.com/facebook/react/releases/tag/v19.2.1). If you are using any of the above packages please upgrade to any of the fixed versions immediately.

If your app’s React code does not use a server, your app is not affected by this vulnerability. If your app does not use a framework, bundler, or bundler plugin that supports React Server Components, your app is not affected by this vulnerability.

### Affected frameworks and bundlers[](#affected-frameworks-and-bundlers "Link for Affected frameworks and bundlers ")

Some React frameworks and bundlers depended on, had peer dependencies for, or included the vulnerable React packages. The following React frameworks & bundlers are affected: [next](https://www.npmjs.com/package/next), [react-router](https://www.npmjs.com/package/react-router), [waku](https://www.npmjs.com/package/waku), [@parcel/rsc](https://www.npmjs.com/package/@parcel/rsc), [@vitejs/plugin-rsc](https://www.npmjs.com/package/@vitejs/plugin-rsc), and [rwsdk](https://www.npmjs.com/package/rwsdk).

See the [update instructions below](#update-instructions) for how to upgrade to these patches.

### Hosting Provider Mitigations[](#hosting-provider-mitigations "Link for Hosting Provider Mitigations ")

We have worked with a number of hosting providers to apply temporary mitigations.

You should not depend on these to secure your app, and still update immediately.

### Vulnerability overview[](#vulnerability-overview "Link for Vulnerability overview ")

[React Server Functions](https://react.dev/reference/rsc/server-functions) allow a client to call a function on a server. React provides integration points and tools that frameworks and bundlers use to help React code run on both the client and the server. React translates requests on the client into HTTP requests which are forwarded to a server. On the server, React translates the HTTP request into a function call and returns the needed data to the client.

An unauthenticated attacker could craft a malicious HTTP request to any Server Function endpoint that, when deserialized by React, achieves remote code execution on the server. Further details of the vulnerability will be provided after the rollout of the fix is complete.

## Update Instructions[](#update-instructions "Link for Update Instructions ")

### Note

These instructions have been updated to include the new vulnerabilities:

* **Denial of Service - High Severity**: [CVE-2025-55184](https://www.cve.org/CVERecord?id=CVE-2025-55184) and [CVE-2025-67779](https://www.cve.org/CVERecord?id=CVE-2025-67779) (CVSS 7.5)
* **Source Code Exposure - Medium Severity**: [CVE-2025-55183](https://www.cve.org/CVERecord?id=CVE-2025-55183) (CVSS 5.3)
* **Denial of Service - High Severity**: January 26, 2026 [CVE-2026-23864](https://www.cve.org/CVERecord?id=CVE-2026-23864) (CVSS 7.5)

See the [follow-up blog post](/blog/2025/12/11/denial-of-service-and-source-code-exposure-in-react-server-components) for more info.

***

*Updated January 26, 2026.*

### Next.js[](#update-next-js "Link for Next.js ")

All users should upgrade to the latest patched version in their release line:

```
npm install next@14.2.35  // for 13.3.x, 13.4.x, 13.5.x, 14.x

npm install next@15.0.8   // for 15.0.x

npm install next@15.1.12  // for 15.1.x

npm install next@15.2.9   // for 15.2.x

npm install next@15.3.9   // for 15.3.x

npm install next@15.4.11  // for 15.4.x

npm install next@15.5.10  // for 15.5.x

npm install next@16.0.11  // for 16.0.x

npm install next@16.1.5   // for 16.1.x



npm install next@15.6.0-canary.60   // for 15.x canary releases

npm install next@16.1.0-canary.19   // for 16.x canary releases
```

15.0.8, 15.1.12, 15.2.9, 15.3.9, 15.4.10, 15.5.10, 15.6.0-canary.61, 16.0.11, 16.1.5

If you are on version `13.3` or later version of Next.js 13 (`13.3.x`, `13.4.x`, or `13.5.x`) please upgrade to version `14.2.35`.

If you are on `next@14.3.0-canary.77` or a later canary release, downgrade to the latest stable 14.x release:

```
npm install next@14
```

See the [Next.js blog](https://nextjs.org/blog/security-update-2025-12-11) for the latest update instructions and the [previous changelog](https://nextjs.org/blog/CVE-2025-66478) for more info.

### React Router[](#update-react-router "Link for React Router ")

If you are using React Router’s unstable RSC APIs, you should upgrade the following package.json dependencies if they exist:

```
npm install react@latest

npm install react-dom@latest

npm install react-server-dom-parcel@latest

npm install react-server-dom-webpack@latest

npm install @vitejs/plugin-rsc@latest
```

### Expo[](#expo "Link for Expo ")

To learn more about mitigating, read the article on [expo.dev/changelog](https://expo.dev/changelog/mitigating-critical-security-vulnerability-in-react-server-components).

### Redwood SDK[](#update-redwood-sdk "Link for Redwood SDK ")

Ensure you are on rwsdk>=1.0.0-alpha.0

For the latest beta version:

```
npm install rwsdk@latest
```

Upgrade to the latest `react-server-dom-webpack`:

```
npm install react@latest react-dom@latest react-server-dom-webpack@latest
```

See [Redwood docs](https://docs.rwsdk.com/migrating/) for more migration instructions.

### Waku[](#update-waku "Link for Waku ")

Upgrade to the latest `react-server-dom-webpack`:

```
npm install react@latest react-dom@latest react-server-dom-webpack@latest waku@latest
```

See [Waku announcement](https://github.com/wakujs/waku/discussions/1823) for more migration instructions.

### `@vitejs/plugin-rsc`[](#vitejs-plugin-rsc "Link for this heading")

Upgrade to the latest RSC plugin:

```
npm install react@latest react-dom@latest @vitejs/plugin-rsc@latest
```

### `react-server-dom-parcel`[](#update-react-server-dom-parcel "Link for this heading")

Update to the latest version:

```
npm install react@latest react-dom@latest react-server-dom-parcel@latest
```

### `react-server-dom-turbopack`[](#update-react-server-dom-turbopack "Link for this heading")

Update to the latest version:

```
npm install react@latest react-dom@latest react-server-dom-turbopack@latest
```

### `react-server-dom-webpack`[](#update-react-server-dom-webpack "Link for this heading")

Update to the latest version:

```
npm install react@latest react-dom@latest react-server-dom-webpack@latest
```

### React Native[](#react-native "Link for React Native ")

For React Native users not using a monorepo or `react-dom`, your `react` version should be pinned in your `package.json`, and there are no additional steps needed.

If you are using React Native in a monorepo, you should update *only* the impacted packages if they are installed:

* `react-server-dom-webpack`
* `react-server-dom-parcel`
* `react-server-dom-turbopack`

This is required to mitigate the security advisory, but you do not need to update `react` and `react-dom` so this will not cause the version mismatch error in React Native.

See [this issue](https://github.com/facebook/react-native/issues/54772#issuecomment-3617929832) for more information.

## Timeline[](#timeline "Link for Timeline ")

* **November 29th**: Lachlan Davidson reported the security vulnerability via [Meta Bug Bounty](https://bugbounty.meta.com/).
* **November 30th**: Meta security researchers confirmed and began working with the React team on a fix.
* **December 1st**: A fix was created and the React team began working with affected hosting providers and open source projects to validate the fix, implement mitigations and roll out the fix
* **December 3rd**: The fix was published to npm and the publicly disclosed as CVE-2025-55182.

## Attribution[](#attribution "Link for Attribution ")

Thank you to [Lachlan Davidson](https://github.com/lachlan2k) for discovering, reporting, and working to help fix this vulnerability.

[PreviousDenial of Service and Source Code Exposure in React Server Components](/blog/2025/12/11/denial-of-service-and-source-code-exposure-in-react-server-components)

[NextReact Conf 2025 Recap](/blog/2025/10/16/react-conf-2025-recap)

***

----
url: https://react.dev/learn/manipulating-the-dom-with-refs
----

```
import { useRef } from 'react';
```

Then, use it to declare a ref inside your component:

```
const myRef = useRef(null);
```

Finally, pass your ref as the `ref` attribute to the JSX tag for which you want to get the DOM node:

```
<div ref={myRef}>
```

The `useRef` Hook returns an object with a single property called `current`. Initially, `myRef.current` will be `null`. When React creates a DOM node for this `<div>`, React will put a reference to this node into `myRef.current`. You can then access this DOM node from your [event handlers](/learn/responding-to-events) and use the built-in [browser APIs](https://developer.mozilla.org/docs/Web/API/Element) defined on it.

```
// You can use any browser APIs, for example:

myRef.current.scrollIntoView();
```

### Example: Focusing a text input[](#example-focusing-a-text-input "Link for Example: Focusing a text input ")

In this example, clicking the button will focus the input:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useRef } from 'react';

export default function Form() {
  const inputRef = useRef(null);

  function handleClick() {
    inputRef.current.focus();
  }

  return (
    <>
      <input ref={inputRef} />
      <button onClick={handleClick}>
        Focus the input
      </button>
    </>
  );
}
```

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useRef } from 'react';

export default function CatFriends() {
  const firstCatRef = useRef(null);
  const secondCatRef = useRef(null);
  const thirdCatRef = useRef(null);

  function handleScrollToFirstCat() {
    firstCatRef.current.scrollIntoView({
      behavior: 'smooth',
      block: 'nearest',
      inline: 'center'
    });
  }

  function handleScrollToSecondCat() {
    secondCatRef.current.scrollIntoView({
      behavior: 'smooth',
      block: 'nearest',
      inline: 'center'
    });
  }

  function handleScrollToThirdCat() {
    thirdCatRef.current.scrollIntoView({
      behavior: 'smooth',
      block: 'nearest',
      inline: 'center'
    });
  }

  return (
    <>
      <nav>
        <button onClick={handleScrollToFirstCat}>
          Neo
        </button>
        <button onClick={handleScrollToSecondCat}>
          Millie
        </button>
        <button onClick={handleScrollToThirdCat}>
          Bella
        </button>
      </nav>
      <div>
        <ul>
          <li>
            <img
              src="https://placecats.com/neo/300/200"
              alt="Neo"
              ref={firstCatRef}
            />
          </li>
          <li>
            <img
              src="https://placecats.com/millie/200/200"
              alt="Millie"
              ref={secondCatRef}
            />
          </li>
          <li>
            <img
              src="https://placecats.com/bella/199/200"
              alt="Bella"
              ref={thirdCatRef}
            />
          </li>
        </ul>
      </div>
    </>
  );
}
```

##### Deep Dive#### How to manage a list of refs using a ref callback[](#how-to-manage-a-list-of-refs-using-a-ref-callback "Link for How to manage a list of refs using a ref callback ")

In the above examples, there is a predefined number of refs. However, sometimes you might need a ref to each item in the list, and you don’t know how many you will have. Something like this **wouldn’t work**:

```
<ul>

  {items.map((item) => {

    // Doesn't work!

    const ref = useRef(null);

    return <li ref={ref} />;

  })}

</ul>
```

This is because **Hooks must only be called at the top-level of your component.** You can’t call `useRef` in a loop, in a condition, or inside a `map()` call.

One possible way around this is to get a single ref to their parent element, and then use DOM manipulation methods like [`querySelectorAll`](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll) to “find” the individual child nodes from it. However, this is brittle and can break if your DOM structure changes.

Another solution is to **pass a function to the `ref` attribute.** This is called a [`ref` callback.](/reference/react-dom/components/common#ref-callback) React will call your ref callback with the DOM node when it’s time to set the ref, and call the cleanup function returned from the callback when it’s time to clear it. This lets you maintain your own array or a [Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map), and access any ref by its index or some kind of ID.

This example shows how you can use this approach to scroll to an arbitrary node in a long list:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useRef, useState } from "react";

export default function CatFriends() {
  const itemsRef = useRef(null);
  const [catList, setCatList] = useState(setupCatList);

  function scrollToCat(cat) {
    const map = getMap();
    const node = map.get(cat);
    node.scrollIntoView({
      behavior: "smooth",
      block: "nearest",
      inline: "center",
    });
  }

  function getMap() {
    if (!itemsRef.current) {
      // Initialize the Map on first usage.
      itemsRef.current = new Map();
    }
    return itemsRef.current;
  }

  return (
    <>
      <nav>
        <button onClick={() => scrollToCat(catList[0])}>Neo</button>
        <button onClick={() => scrollToCat(catList[5])}>Millie</button>
        <button onClick={() => scrollToCat(catList[8])}>Bella</button>
      </nav>
      <div>
        <ul>
          {catList.map((cat) => (
            <li
              key={cat.id}
              ref={(node) => {
                const map = getMap();
                map.set(cat, node);

                return () => {
                  map.delete(cat);
                };
              }}
            >
              <img src={cat.imageUrl} />
            </li>
          ))}
        </ul>
      </div>
    </>
  );
}

function setupCatList() {
  const catCount = 10;
  const catList = new Array(catCount)
  for (let i = 0; i < catCount; i++) {
    let imageUrl = '';
    if (i < 5) {
      imageUrl = "https://placecats.com/neo/320/240";
    } else if (i < 8) {
      imageUrl = "https://placecats.com/millie/320/240";
    } else {
      imageUrl = "https://placecats.com/bella/320/240";
    }
    catList[i] = {
      id: i,
      imageUrl,
    };
  }
  return catList;
}
```

In this example, `itemsRef` doesn’t hold a single DOM node. Instead, it holds a [Map](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Map) from item ID to a DOM node. ([Refs can hold any values!](/learn/referencing-values-with-refs)) The [`ref` callback](/reference/react-dom/components/common#ref-callback) on every list item takes care to update the Map:

```
<li

  key={cat.id}

  ref={node => {

    const map = getMap();

    // Add to the Map

    map.set(cat, node);



    return () => {

      // Remove from the Map

      map.delete(cat);

    };

  }}

>
```

This lets you read individual DOM nodes from the Map later.

### Note

When Strict Mode is enabled, ref callbacks will run twice in development.

Read more about [how this helps find bugs](/reference/react/StrictMode#fixing-bugs-found-by-re-running-ref-callbacks-in-development) in callback refs.

## Accessing another component’s DOM nodes[](#accessing-another-components-dom-nodes "Link for Accessing another component’s DOM nodes ")

### Pitfall

Refs are an escape hatch. Manually manipulating *another* component’s DOM nodes can make your code fragile.

You can pass refs from parent component to child components [just like any other prop](/learn/passing-props-to-a-component).

```
import { useRef } from 'react';



function MyInput({ ref }) {

  return <input ref={ref} />;

}



function MyForm() {

  const inputRef = useRef(null);

  return <MyInput ref={inputRef} />

}
```

In the above example, a ref is created in the parent component, `MyForm`, and is passed to the child component, `MyInput`. `MyInput` then passes the ref to `<input>`. Because `<input>` is a [built-in component](/reference/react-dom/components/common) React sets the `.current` property of the ref to the `<input>` DOM element.

The `inputRef` created in `MyForm` now points to the `<input>` DOM element returned by `MyInput`. A click handler created in `MyForm` can access `inputRef` and call `focus()` to set the focus on `<input>`.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useRef } from 'react';

function MyInput({ ref }) {
  return <input ref={ref} />;
}

export default function MyForm() {
  const inputRef = useRef(null);

  function handleClick() {
    inputRef.current.focus();
  }

  return (
    <>
      <MyInput ref={inputRef} />
      <button onClick={handleClick}>
        Focus the input
      </button>
    </>
  );
}
```

##### Deep Dive#### Exposing a subset of the API with an imperative handle[](#exposing-a-subset-of-the-api-with-an-imperative-handle "Link for Exposing a subset of the API with an imperative handle ")

In the above example, the ref passed to `MyInput` is passed on to the original DOM input element. This lets the parent component call `focus()` on it. However, this also lets the parent component do something else—for example, change its CSS styles. In uncommon cases, you may want to restrict the exposed functionality. You can do that with [`useImperativeHandle`](/reference/react/useImperativeHandle):

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useRef, useImperativeHandle } from "react";

function MyInput({ ref }) {
  const realInputRef = useRef(null);
  useImperativeHandle(ref, () => ({
    // Only expose focus and nothing else
    focus() {
      realInputRef.current.focus();
    },
  }));
  return <input ref={realInputRef} />;
};

export default function Form() {
  const inputRef = useRef(null);

  function handleClick() {
    inputRef.current.focus();
  }

  return (
    <>
      <MyInput ref={inputRef} />
      <button onClick={handleClick}>Focus the input</button>
    </>
  );
}
```

Here, `realInputRef` inside `MyInput` holds the actual input DOM node. However, [`useImperativeHandle`](/reference/react/useImperativeHandle) instructs React to provide your own special object as the value of a ref to the parent component. So `inputRef.current` inside the `Form` component will only have the `focus` method. In this case, the ref “handle” is not the DOM node, but the custom object you create inside [`useImperativeHandle`](/reference/react/useImperativeHandle) call.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useRef } from 'react';

export default function TodoList() {
  const listRef = useRef(null);
  const [text, setText] = useState('');
  const [todos, setTodos] = useState(
    initialTodos
  );

  function handleAdd() {
    const newTodo = { id: nextId++, text: text };
    setText('');
    setTodos([ ...todos, newTodo]);
    listRef.current.lastChild.scrollIntoView({
      behavior: 'smooth',
      block: 'nearest'
    });
  }

  return (
    <>
      <button onClick={handleAdd}>
        Add
      </button>
      <input
        value={text}
        onChange={e => setText(e.target.value)}
      />
      <ul ref={listRef}>
        {todos.map(todo => (
          <li key={todo.id}>{todo.text}</li>
        ))}
      </ul>
    </>
  );
}

let nextId = 0;
let initialTodos = [];
for (let i = 0; i < 20; i++) {
  initialTodos.push({
    id: nextId++,
    text: 'Todo #' + (i + 1)
  });
}
```

The issue is with these two lines:

```
setTodos([ ...todos, newTodo]);

listRef.current.lastChild.scrollIntoView();
```

In React, [state updates are queued.](/learn/queueing-a-series-of-state-updates) Usually, this is what you want. However, here it causes a problem because `setTodos` does not immediately update the DOM. So the time you scroll the list to its last element, the todo has not yet been added. This is why scrolling always “lags behind” by one item.

To fix this issue, you can force React to update (“flush”) the DOM synchronously. To do this, import `flushSync` from `react-dom` and **wrap the state update** into a `flushSync` call:

```
flushSync(() => {

  setTodos([ ...todos, newTodo]);

});

listRef.current.lastChild.scrollIntoView();
```

This will instruct React to update the DOM synchronously right after the code wrapped in `flushSync` executes. As a result, the last todo will already be in the DOM by the time you try to scroll to it:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useRef } from 'react';
import { flushSync } from 'react-dom';

export default function TodoList() {
  const listRef = useRef(null);
  const [text, setText] = useState('');
  const [todos, setTodos] = useState(
    initialTodos
  );

  function handleAdd() {
    const newTodo = { id: nextId++, text: text };
    flushSync(() => {
      setText('');
      setTodos([ ...todos, newTodo]);
    });
    listRef.current.lastChild.scrollIntoView({
      behavior: 'smooth',
      block: 'nearest'
    });
  }

  return (
    <>
      <button onClick={handleAdd}>
        Add
      </button>
      <input
        value={text}
        onChange={e => setText(e.target.value)}
      />
      <ul ref={listRef}>
        {todos.map(todo => (
          <li key={todo.id}>{todo.text}</li>
        ))}
      </ul>
    </>
  );
}

let nextId = 0;
let initialTodos = [];
for (let i = 0; i < 20; i++) {
  initialTodos.push({
    id: nextId++,
    text: 'Todo #' + (i + 1)
  });
}
```

## Best practices for DOM manipulation with refs[](#best-practices-for-dom-manipulation-with-refs "Link for Best practices for DOM manipulation with refs ")

Refs are an escape hatch. You should only use them when you have to “step outside React”. Common examples of this include managing focus, scroll position, or calling browser APIs that React does not expose.

If you stick to non-destructive actions like focusing and scrolling, you shouldn’t encounter any problems. However, if you try to **modify** the DOM manually, you can risk conflicting with the changes React is making.

To illustrate this problem, this example includes a welcome message and two buttons. The first button toggles its presence using [conditional rendering](/learn/conditional-rendering) and [state](/learn/state-a-components-memory), as you would usually do in React. The second button uses the [`remove()` DOM API](https://developer.mozilla.org/en-US/docs/Web/API/Element/remove) to forcefully remove it from the DOM outside of React’s control.

Try pressing “Toggle with setState” a few times. The message should disappear and appear again. Then press “Remove from the DOM”. This will forcefully remove it. Finally, press “Toggle with setState”:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useRef } from 'react';

export default function Counter() {
  const [show, setShow] = useState(true);
  const ref = useRef(null);

  return (
    <div>
      <button
        onClick={() => {
          setShow(!show);
        }}>
        Toggle with setState
      </button>
      <button
        onClick={() => {
          ref.current.remove();
        }}>
        Remove from the DOM
      </button>
      {show && <p ref={ref}>Hello world</p>}
    </div>
  );
}
```

* A component doesn’t expose its DOM nodes by default. You can opt into exposing a DOM node by using the `ref` prop.
* Avoid changing DOM nodes managed by React.
* If you do modify DOM nodes managed by React, modify parts that React has no reason to update.

## Try out some challenges[](#challenges "Link for Try out some challenges")

#### Challenge 1 of 4:Play and pause the video[](#play-and-pause-the-video "Link for this heading")

In this example, the button toggles a state variable to switch between a playing and a paused state. However, in order to actually play or pause the video, toggling state is not enough. You also need to call [`play()`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/play) and [`pause()`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/pause) on the DOM element for the `<video>`. Add a ref to it, and make the button work.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useRef } from 'react';

export default function VideoPlayer() {
  const [isPlaying, setIsPlaying] = useState(false);

  function handleClick() {
    const nextIsPlaying = !isPlaying;
    setIsPlaying(nextIsPlaying);
  }

  return (
    <>
      <button onClick={handleClick}>
        {isPlaying ? 'Pause' : 'Play'}
      </button>
      <video width="250">
        <source
          src="https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4"
          type="video/mp4"
        />
      </video>
    </>
  )
}
```

For an extra challenge, keep the “Play” button in sync with whether the video is playing even if the user right-clicks the video and plays it using the built-in browser media controls. You might want to listen to `onPlay` and `onPause` on the video to do that.

[PreviousReferencing Values with Refs](/learn/referencing-values-with-refs)

[NextSynchronizing with Effects](/learn/synchronizing-with-effects)

***

----
url: https://react.dev/reference/react/Children
----

[API Reference](/reference/react)

[Legacy React APIs](/reference/react/legacy)

# Children[](#undefined "Link for this heading")

### Pitfall

Using `Children` is uncommon and can lead to fragile code. [See common alternatives.](#alternatives)

`Children` lets you manipulate and transform the JSX you received as the [`children` prop.](/learn/passing-props-to-a-component#passing-jsx-as-children)

```
const mappedChildren = Children.map(children, child =>

  <div className="Row">

    {child}

  </div>

);
```

***

## Reference[](#reference "Link for Reference ")

### `Children.count(children)`[](#children-count "Link for this heading")

Call `Children.count(children)` to count the number of children in the `children` data structure.

```
import { Children } from 'react';



function RowList({ children }) {

  return (

    <>

      <h1>Total rows: {Children.count(children)}</h1>

      ...

    </>

  );

}
```

***

### `Children.forEach(children, fn, thisArg?)`[](#children-foreach "Link for this heading")

Call `Children.forEach(children, fn, thisArg?)` to run some code for each child in the `children` data structure.

```
import { Children } from 'react';



function SeparatorList({ children }) {

  const result = [];

  Children.forEach(children, (child, index) => {

    result.push(child);

    result.push(<hr key={index} />);

  });

  // ...
```

***

### `Children.map(children, fn, thisArg?)`[](#children-map "Link for this heading")

Call `Children.map(children, fn, thisArg?)` to map or transform each child in the `children` data structure.

```
import { Children } from 'react';



function RowList({ children }) {

  return (

    <div className="RowList">

      {Children.map(children, child =>

        <div className="Row">

          {child}

        </div>

      )}

    </div>

  );

}
```

***

### `Children.only(children)`[](#children-only "Link for this heading")

Call `Children.only(children)` to assert that `children` represent a single React element.

```
function Box({ children }) {

  const element = Children.only(children);

  // ...
```

***

### `Children.toArray(children)`[](#children-toarray "Link for this heading")

Call `Children.toArray(children)` to create an array out of the `children` data structure.

```
import { Children } from 'react';



export default function ReversedList({ children }) {

  const result = Children.toArray(children);

  result.reverse();

  // ...
```

#### Parameters[](#children-toarray-parameters "Link for Parameters ")

* `children`: The value of the [`children` prop](/learn/passing-props-to-a-component#passing-jsx-as-children) received by your component.

#### Returns[](#children-toarray-returns "Link for Returns ")

Returns a flat array of elements in `children`.

#### Caveats[](#children-toarray-caveats "Link for Caveats ")

* Empty nodes (`null`, `undefined`, and Booleans) will be omitted in the returned array. **The returned elements’ keys will be calculated from the original elements’ keys and their level of nesting and position.** This ensures that flattening the array does not introduce changes in behavior.

***

## Usage[](#usage "Link for Usage ")

### Transforming children[](#transforming-children "Link for Transforming children ")

To transform the children JSX that your component [receives as the `children` prop,](/learn/passing-props-to-a-component#passing-jsx-as-children) call `Children.map`:

```
import { Children } from 'react';



function RowList({ children }) {

  return (

    <div className="RowList">

      {Children.map(children, child =>

        <div className="Row">

          {child}

        </div>

      )}

    </div>

  );

}
```

In the example above, the `RowList` wraps every child it receives into a `<div className="Row">` container. For example, let’s say the parent component passes three `<p>` tags as the `children` prop to `RowList`:

```
<RowList>

  <p>This is the first item.</p>

  <p>This is the second item.</p>

  <p>This is the third item.</p>

</RowList>
```

Then, with the `RowList` implementation above, the final rendered result will look like this:

```
<div className="RowList">

  <div className="Row">

    <p>This is the first item.</p>

  </div>

  <div className="Row">

    <p>This is the second item.</p>

  </div>

  <div className="Row">

    <p>This is the third item.</p>

  </div>

</div>
```

`Children.map` is similar to [to transforming arrays with `map()`.](/learn/rendering-lists) The difference is that the `children` data structure is considered *opaque.* This means that even if it’s sometimes an array, you should not assume it’s an array or any other particular data type. This is why you should use `Children.map` if you need to transform it.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { Children } from 'react';

export default function RowList({ children }) {
  return (
    <div className="RowList">
      {Children.map(children, child =>
        <div className="Row">
          {child}
        </div>
      )}
    </div>
  );
}
```

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import RowList from './RowList.js';

export default function App() {
  return (
    <RowList>
      <p>This is the first item.</p>
      <MoreRows />
    </RowList>
  );
}

function MoreRows() {
  return (
    <>
      <p>This is the second item.</p>
      <p>This is the third item.</p>
    </>
  );
}
```

**There is no way to get the rendered output of an inner component** like `<MoreRows />` when manipulating `children`. This is why [it’s usually better to use one of the alternative solutions.](#alternatives)

***

### Running some code for each child[](#running-some-code-for-each-child "Link for Running some code for each child ")

Call `Children.forEach` to iterate over each child in the `children` data structure. It does not return any value and is similar to the [array `forEach` method.](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach) You can use it to run custom logic like constructing your own array.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { Children } from 'react';

export default function SeparatorList({ children }) {
  const result = [];
  Children.forEach(children, (child, index) => {
    result.push(child);
    result.push(<hr key={index} />);
  });
  result.pop(); // Remove the last separator
  return result;
}
```

### Pitfall

As mentioned earlier, there is no way to get the rendered output of an inner component when manipulating `children`. This is why [it’s usually better to use one of the alternative solutions.](#alternatives)

***

### Counting children[](#counting-children "Link for Counting children ")

Call `Children.count(children)` to calculate the number of children.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { Children } from 'react';

export default function RowList({ children }) {
  return (
    <div className="RowList">
      <h1 className="RowListHeader">
        Total rows: {Children.count(children)}
      </h1>
      {Children.map(children, child =>
        <div className="Row">
          {child}
        </div>
      )}
    </div>
  );
}
```

### Pitfall

As mentioned earlier, there is no way to get the rendered output of an inner component when manipulating `children`. This is why [it’s usually better to use one of the alternative solutions.](#alternatives)

***

### Converting children to an array[](#converting-children-to-an-array "Link for Converting children to an array ")

Call `Children.toArray(children)` to turn the `children` data structure into a regular JavaScript array. This lets you manipulate the array with built-in array methods like [`filter`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter), [`sort`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort), or [`reverse`.](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse)

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { Children } from 'react';

export default function ReversedList({ children }) {
  const result = Children.toArray(children);
  result.reverse();
  return result;
}
```

### Pitfall

As mentioned earlier, there is no way to get the rendered output of an inner component when manipulating `children`. This is why [it’s usually better to use one of the alternative solutions.](#alternatives)

***

## Alternatives[](#alternatives "Link for Alternatives ")

### Note

This section describes alternatives to the `Children` API (with capital `C`) that’s imported like this:

```
import { Children } from 'react';
```

Don’t confuse it with [using the `children` prop](/learn/passing-props-to-a-component#passing-jsx-as-children) (lowercase `c`), which is good and encouraged.

### Exposing multiple components[](#exposing-multiple-components "Link for Exposing multiple components ")

Manipulating children with the `Children` methods often leads to fragile code. When you pass children to a component in JSX, you don’t usually expect the component to manipulate or transform the individual children.

When you can, try to avoid using the `Children` methods. For example, if you want every child of `RowList` to be wrapped in `<div className="Row">`, export a `Row` component, and manually wrap every row into it like this:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { RowList, Row } from './RowList.js';

export default function App() {
  return (
    <RowList>
      <Row>
        <p>This is the first item.</p>
      </Row>
      <Row>
        <p>This is the second item.</p>
      </Row>
      <Row>
        <p>This is the third item.</p>
      </Row>
    </RowList>
  );
}
```

Unlike using `Children.map`, this approach does not wrap every child automatically. **However, this approach has a significant benefit compared to the [earlier example with `Children.map`](#transforming-children) because it works even if you keep extracting more components.** For example, it still works if you extract your own `MoreRows` component:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { RowList, Row } from './RowList.js';

export default function App() {
  return (
    <RowList>
      <Row>
        <p>This is the first item.</p>
      </Row>
      <MoreRows />
    </RowList>
  );
}

function MoreRows() {
  return (
    <>
      <Row>
        <p>This is the second item.</p>
      </Row>
      <Row>
        <p>This is the third item.</p>
      </Row>
    </>
  );
}
```

This wouldn’t work with `Children.map` because it would “see” `<MoreRows />` as a single child (and a single row).

***

### Accepting an array of objects as a prop[](#accepting-an-array-of-objects-as-a-prop "Link for Accepting an array of objects as a prop ")

You can also explicitly pass an array as a prop. For example, this `RowList` accepts a `rows` array as a prop:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { RowList, Row } from './RowList.js';

export default function App() {
  return (
    <RowList rows={[
      { id: 'first', content: <p>This is the first item.</p> },
      { id: 'second', content: <p>This is the second item.</p> },
      { id: 'third', content: <p>This is the third item.</p> }
    ]} />
  );
}
```

Since `rows` is a regular JavaScript array, the `RowList` component can use built-in array methods like [`map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) on it.

This pattern is especially useful when you want to be able to pass more information as structured data together with children. In the below example, the `TabSwitcher` component receives an array of objects as the `tabs` prop:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import TabSwitcher from './TabSwitcher.js';

export default function App() {
  return (
    <TabSwitcher tabs={[
      {
        id: 'first',
        header: 'First',
        content: <p>This is the first item.</p>
      },
      {
        id: 'second',
        header: 'Second',
        content: <p>This is the second item.</p>
      },
      {
        id: 'third',
        header: 'Third',
        content: <p>This is the third item.</p>
      }
    ]} />
  );
}
```

Unlike passing the children as JSX, this approach lets you associate some extra data like `header` with each item. Because you are working with the `tabs` directly, and it is an array, you do not need the `Children` methods.

***

### Calling a render prop to customize rendering[](#calling-a-render-prop-to-customize-rendering "Link for Calling a render prop to customize rendering ")

Instead of producing JSX for every single item, you can also pass a function that returns JSX, and call that function when necessary. In this example, the `App` component passes a `renderContent` function to the `TabSwitcher` component. The `TabSwitcher` component calls `renderContent` only for the selected tab:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import TabSwitcher from './TabSwitcher.js';

export default function App() {
  return (
    <TabSwitcher
      tabIds={['first', 'second', 'third']}
      getHeader={tabId => {
        return tabId[0].toUpperCase() + tabId.slice(1);
      }}
      renderContent={tabId => {
        return <p>This is the {tabId} item.</p>;
      }}
    />
  );
}
```

A prop like `renderContent` is called a *render prop* because it is a prop that specifies how to render a piece of the user interface. However, there is nothing special about it: it is a regular prop which happens to be a function.

Render props are functions, so you can pass information to them. For example, this `RowList` component passes the `id` and the `index` of each row to the `renderRow` render prop, which uses `index` to highlight even rows:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { RowList, Row } from './RowList.js';

export default function App() {
  return (
    <RowList
      rowIds={['first', 'second', 'third']}
      renderRow={(id, index) => {
        return (
          <Row isHighlighted={index % 2 === 0}>
            <p>This is the {id} item.</p>
          </Row>
        );
      }}
    />
  );
}
```

This is another example of how parent and child components can cooperate without manipulating the children.

***

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### I pass a custom component, but the `Children` methods don’t show its render result[](#i-pass-a-custom-component-but-the-children-methods-dont-show-its-render-result "Link for this heading")

Suppose you pass two children to `RowList` like this:

```
<RowList>

  <p>First item</p>

  <MoreRows />

</RowList>
```

If you do `Children.count(children)` inside `RowList`, you will get `2`. Even if `MoreRows` renders 10 different items, or if it returns `null`, `Children.count(children)` will still be `2`. From the `RowList`’s perspective, it only “sees” the JSX it has received. It does not “see” the internals of the `MoreRows` component.

The limitation makes it hard to extract a component. This is why [alternatives](#alternatives) are preferred to using `Children`.

[PreviousLegacy React APIs](/reference/react/legacy)

[NextcloneElement](/reference/react/cloneElement)

***

----
url: https://react.dev/reference/react/useOptimistic
----

[API Reference](/reference/react)

[Hooks](/reference/react/hooks)

# useOptimistic[](#undefined "Link for this heading")

`useOptimistic` is a React Hook that lets you optimistically update the UI.

```
const [optimisticState, setOptimistic] = useOptimistic(value, reducer?);
```

* [Reference](#reference)

  * [`useOptimistic(value, reducer?)`](#useoptimistic)
  * [`set` functions, like `setOptimistic(optimisticState)`](#setoptimistic)

* [Usage](#usage)

  * [Adding optimistic state to a component](#adding-optimistic-state-to-a-component)
  * [Using optimistic state in Action props](#using-optimistic-state-in-action-props)
  * [Adding optimistic state to Action props](#adding-optimistic-state-to-action-props)
  * [Updating props or state optimistically](#updating-props-or-state-optimistically)
  * [Updating multiple values together](#updating-multiple-values-together)
  * [Optimistically adding to a list](#optimistically-adding-to-a-list)
  * [Handling multiple `action` types](#handling-multiple-action-types)
  * [Optimistic delete with error recovery](#optimistic-delete-with-error-recovery)

* [Troubleshooting](#troubleshooting)

  * [I’m getting an error: “An optimistic state update occurred outside a Transition or Action”](#an-optimistic-state-update-occurred-outside-a-transition-or-action)
  * [I’m getting an error: “Cannot update optimistic state while rendering”](#cannot-update-optimistic-state-while-rendering)
  * [My optimistic updates show stale values](#my-optimistic-updates-show-stale-values)
  * [I don’t know if my optimistic update is pending](#i-dont-know-if-my-optimistic-update-is-pending)

***

## Reference[](#reference "Link for Reference ")

### `useOptimistic(value, reducer?)`[](#useoptimistic "Link for this heading")

Call `useOptimistic` at the top level of your component to create optimistic state for a value.

```
import { useOptimistic } from 'react';



function MyComponent({name, todos}) {

  const [optimisticAge, setOptimisticAge] = useOptimistic(28);

  const [optimisticName, setOptimisticName] = useOptimistic(name);

  const [optimisticTodos, setOptimisticTodos] = useOptimistic(todos, todoReducer);

  // ...

}
```

[See more examples below.](#usage)

#### Parameters[](#parameters "Link for Parameters ")

* `value`: The value returned when there are no pending Actions.
* **optional** `reducer(currentState, action)`: The reducer function that specifies how the optimistic state gets updated. It must be pure, should take the current state and reducer action arguments, and should return the next optimistic state.

#### Returns[](#returns "Link for Returns ")

`useOptimistic` returns an array with exactly two values:

1. `optimisticState`: The current optimistic state. It is equal to `value` unless an Action is pending, in which case it is equal to the state returned by `reducer` (or the value passed to the set function if no `reducer` was provided).
2. The [`set` function](#setoptimistic) that lets you update the optimistic state to a different value inside an Action.

***

### `set` functions, like `setOptimistic(optimisticState)`[](#setoptimistic "Link for this heading")

The `set` function returned by `useOptimistic` lets you update the state for the duration of an [Action](/reference/react/useTransition#functions-called-in-starttransition-are-called-actions). You can pass the next state directly, or a function that calculates it from the previous state:

```
const [optimisticLike, setOptimisticLike] = useOptimistic(false);

const [optimisticSubs, setOptimisticSubs] = useOptimistic(subs);



function handleClick() {

  startTransition(async () => {

    setOptimisticLike(true);

    setOptimisticSubs(a => a + 1);

    await saveChanges();

  });

}
```

#### Parameters[](#setoptimistic-parameters "Link for Parameters ")

* `optimisticState`: The value that you want the optimistic state to be during an [Action](/reference/react/useTransition#functions-called-in-starttransition-are-called-actions). If you provided a `reducer` to `useOptimistic`, this value will be passed as the second argument to your reducer. It can be a value of any type.
  * If you pass a function as `optimisticState`, it will be treated as an *updater function*. It must be pure, should take the pending state as its only argument, and should return the next optimistic state. React will put your updater function in a queue and re-render your component. During the next render, React will calculate the next state by applying the queued updaters to the previous state similar to [`useState` updaters](/reference/react/useState#setstate-parameters).

#### Returns[](#setoptimistic-returns "Link for Returns ")

`set` functions do not have a return value.

#### Caveats[](#setoptimistic-caveats "Link for Caveats ")

* The `set` function must be called inside an [Action](/reference/react/useTransition#functions-called-in-starttransition-are-called-actions). If you call the setter outside an Action, [React will show a warning](#an-optimistic-state-update-occurred-outside-a-transition-or-action) and the optimistic state will briefly render.

##### Deep Dive#### How optimistic state works[](#how-optimistic-state-works "Link for How optimistic state works ")

`useOptimistic` lets you show a temporary value while an Action is in progress:

```
const [value, setValue] = useState('a');

const [optimistic, setOptimistic] = useOptimistic(value);



startTransition(async () => {

  setOptimistic('b');

  const newValue = await saveChanges('b');

  setValue(newValue);

});
```

When the setter is called inside an Action, `useOptimistic` will trigger a re-render to show that state while the Action is in progress. Otherwise, the `value` passed to `useOptimistic` is returned.

This state is called the “optimistic” because it is used to immediately present the user with the result of performing an Action, even though the Action actually takes time to complete.

**How the update flows**

1. **Update immediately**: When `setOptimistic('b')` is called, React immediately renders with `'b'`.

2. **(Optional) await in Action**: If you await in the Action, React continues showing `'b'`.

3. **Transition scheduled**: `setValue(newValue)` schedules an update to the real state.

4. **(Optional) wait for Suspense**: If `newValue` suspends, React continues showing `'b'`.

5. **Single render commit**: Finally, the `newValue` commits for `value` and `optimistic`.

There’s no extra render to “clear” the optimistic state. The optimistic and real state converge in the same render when the Transition completes.

### Note

#### Optimistic state is temporary[](#optimistic-state-is-temporary "Link for Optimistic state is temporary ")

Optimistic state only renders while an Action is in progress, otherwise `value` is rendered.

If `saveChanges` returned `'c'`, then both `value` and `optimistic` will be `'c'`, not `'b'`.

**How the final state is determined**

The `value` argument to `useOptimistic` determines what displays after the Action finishes. How this works depends on the pattern you use:

* **Hardcoded values** like `useOptimistic(false)`: After the Action, `state` is still `false`, so the UI shows `false`. This is useful for pending states where you always start from `false`.

* **Props or state passed in** like `useOptimistic(isLiked)`: If the parent updates `isLiked` during the Action, the new value is used after the Action completes. This is how the UI reflects the result of the Action.

* **Reducer pattern** like `useOptimistic(items, fn)`: If `items` changes while the Action is pending, React re-runs your `reducer` with the new `items` to recalculate the state. This keeps your optimistic additions on top of the latest data.

**What happens when the Action fails**

If the Action throws an error, the Transition still ends, and React renders with whatever `value` currently is. Since the parent typically only updates `value` on success, a failure means `value` hasn’t changed, so the UI shows what it showed before the optimistic update. You can catch the error to show a message to the user.

***

## Usage[](#usage "Link for Usage ")

### Adding optimistic state to a component[](#adding-optimistic-state-to-a-component "Link for Adding optimistic state to a component ")

Call `useOptimistic` at the top level of your component to declare one or more optimistic states.

```
import { useOptimistic } from 'react';



function MyComponent({age, name, todos}) {

  const [optimisticAge, setOptimisticAge] = useOptimistic(age);

  const [optimisticName, setOptimisticName] = useOptimistic(name);

  const [optimisticTodos, setOptimisticTodos] = useOptimistic(todos, reducer);

  // ...
```

`useOptimistic` returns an array with exactly two items:

1. The optimistic state, initially set to the value provided.
2. The set function that lets you temporarily change the state during an [Action](/reference/react/useTransition#functions-called-in-starttransition-are-called-actions).
   * If a reducer is provided, it will run before returning the optimistic state.

To use the optimistic state, call the `set` function inside an Action.

Actions are functions called inside `startTransition`:

```
function onAgeChange(e) {

  startTransition(async () => {

    setOptimisticAge(42);

    const newAge = await postAge(42);

    setAge(newAge);

  });

}
```

React will render the optimistic state `42` first while the `age` remains the current age. The Action waits for POST, and then renders the `newAge` for both `age` and `optimisticAge`.

See [How optimistic state works](#how-optimistic-state-works) for a deep dive.

### Note

When using [Action props](/reference/react/useTransition#exposing-action-props-from-components), you can call the set function without `startTransition`:

```
async function submitAction() {

  setOptimisticName('Taylor');

  await updateName('Taylor');

}
```

This works because Action props are already called inside `startTransition`.

For an example, see: [Using optimistic state in Action props](#using-optimistic-state-in-action-props).

***

### Using optimistic state in Action props[](#using-optimistic-state-in-action-props "Link for Using optimistic state in Action props ")

In an [Action prop](/reference/react/useTransition#exposing-action-props-from-components), you can call the optimistic setter directly without `startTransition`.

This example sets optimistic state inside a `<form>` `submitAction` prop:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useOptimistic, startTransition } from 'react';
import { updateName } from './actions.js';

export default function EditName({ name, action }) {
  const [optimisticName, setOptimisticName] = useOptimistic(name);

  async function submitAction(formData) {
    const newName = formData.get('name');
    setOptimisticName(newName);

    const updatedName = await updateName(newName);
    startTransition(() => {
      action(updatedName);
    })
  }

  return (
    <form action={submitAction}>
      <p>Your name is: {optimisticName}</p>
      <p>
        <label>Change it: </label>
        <input
          type="text"
          name="name"
          disabled={name !== optimisticName}
        />
      </p>
    </form>
  );
}
```

In this example, when the user submits the form, the `optimisticName` updates immediately to show the `newName` optimistically while the server request is in progress. When the request completes, `name` and `optimisticName` are rendered with the actual `updatedName` from the response.

##### Deep Dive#### Why doesn’t this need `startTransition`?[](#why-doesnt-this-need-starttransition "Link for this heading")

By convention, props called inside `startTransition` are named with “Action”.

Since `submitAction` is named with “Action”, you know it’s already called inside `startTransition`.

See [Exposing `action` prop from components](/reference/react/useTransition#exposing-action-props-from-components) for the Action prop pattern.

***

### Adding optimistic state to Action props[](#adding-optimistic-state-to-action-props "Link for Adding optimistic state to Action props ")

When creating an [Action prop](/reference/react/useTransition#exposing-action-props-from-components), you can add `useOptimistic` to show immediate feedback.

Here’s a button that shows “Submitting…” while the `action` is pending:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useOptimistic, startTransition } from 'react';

export default function Button({ action, children }) {
  const [isPending, setIsPending] = useOptimistic(false);

  return (
    <button
      disabled={isPending}
      onClick={() => {
        startTransition(async () => {
          setIsPending(true);
          await action();
        });
      }}
    >
      {isPending ? 'Submitting...' : children}
    </button>
  );
}
```

When the button is clicked, `setIsPending(true)` uses optimistic state to immediately show “Submitting…” and disable the button. When the Action is done, `isPending` is rendered as `false` automatically.

This pattern automatically shows a pending state however `action` prop is used with `Button`:

```
// Show pending state for a state update

<Button action={() => { setState(c => c + 1) }} />



// Show pending state for a navigation

<Button action={() => { navigate('/done') }} />



// Show pending state for a POST

<Button action={async () => { await fetch(/* ... */) }} />



// Show pending state for any combination

<Button action={async () => {

  setState(c => c + 1);

  await fetch(/* ... */);

  navigate('/done');

}} />
```

The pending state will be shown until everything in the `action` prop is finished.

### Note

You can also use [`useTransition`](/reference/react/useTransition) to get pending state via `isPending`.

The difference is that `useTransition` gives you the `startTransition` function, while `useOptimistic` works with any Transition. Use whichever fits your component’s needs.

***

### Updating props or state optimistically[](#updating-props-or-state-optimistically "Link for Updating props or state optimistically ")

You can wrap props or state in `useOptimistic` to update it immediately while an Action is in progress.

In this example, `LikeButton` receives `isLiked` as a prop and immediately toggles it when clicked:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useOptimistic, startTransition } from 'react';
import { toggleLike } from './actions.js';

export default function App() {
  const [isLiked, setIsLiked] = useState(false);
  const [optimisticIsLiked, setOptimisticIsLiked] = useOptimistic(isLiked);

  function handleClick() {
    startTransition(async () => {
      const newValue = !optimisticIsLiked
      console.log('⏳ setting optimistic state: ' + newValue);

      setOptimisticIsLiked(newValue);
      const updatedValue = await toggleLike(newValue);

      startTransition(() => {
        console.log('⏳ setting real state: ' + updatedValue );
        setIsLiked(updatedValue);
      });
    });
  }

  if (optimisticIsLiked !== isLiked) {
    console.log('✅ rendering optimistic state: ' + optimisticIsLiked);
  } else {
    console.log('✅ rendering real value: ' + optimisticIsLiked);
  }


  return (
    <button onClick={handleClick}>
      {optimisticIsLiked ? '❤️ Unlike' : '🤍 Like'}
    </button>
  );
}
```

When the button is clicked, `setOptimisticIsLiked` immediately updates the displayed state to show the heart as liked. Meanwhile, `await toggleLike` runs in the background. When the `await` completes, `setIsLiked` parent updates the “real” `isLiked` state, and the optimistic state is rendered to match this new value.

### Note

This example reads from `optimisticIsLiked` to calculate the next value. This works when the base state won’t change, but if the base state might change while your Action is pending, you may want to use a state updater or the reducer.

See [Updating state based on the current state](#updating-state-based-on-current-state) for an example.

***

### Updating multiple values together[](#updating-multiple-values-together "Link for Updating multiple values together ")

When an optimistic update affects multiple related values, use a reducer to update them together. This ensures the UI stays consistent.

Here’s a follow button that updates both the follow state and follower count:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useOptimistic, startTransition } from 'react';

export default function FollowButton({ user, followAction }) {
  const [optimisticState, updateOptimistic] = useOptimistic(
    { isFollowing: user.isFollowing, followerCount: user.followerCount },
    (current, isFollowing) => ({
      isFollowing,
      followerCount: current.followerCount + (isFollowing ? 1 : -1)
    })
  );

  function handleClick() {
    const newFollowState = !optimisticState.isFollowing;
    startTransition(async () => {
      updateOptimistic(newFollowState);
      await followAction(newFollowState);
    });
  }

  return (
    <div>
      <p><strong>{user.name}</strong></p>
      <p>{optimisticState.followerCount} followers</p>
      <button onClick={handleClick}>
        {optimisticState.isFollowing ? 'Unfollow' : 'Follow'}
      </button>
    </div>
  );
}
```

The reducer receives the new `isFollowing` value and calculates both the new follow state and the updated follower count in a single update. This ensures the button text and count always stay in sync.

##### Deep Dive#### Choosing between updaters and reducers[](#choosing-between-updaters-and-reducers "Link for Choosing between updaters and reducers ")

`useOptimistic` supports two patterns for calculating state based on current state:

**Updater functions** work like [useState updaters](/reference/react/useState#updating-state-based-on-the-previous-state). Pass a function to the setter:

```
const [optimistic, setOptimistic] = useOptimistic(value);

setOptimistic(current => !current);
```

**Reducers** separate the update logic from the setter call:

```
const [optimistic, dispatch] = useOptimistic(value, (current, action) => {

  // Calculate next state based on current and action

});

dispatch(action);
```

**Use updaters** for calculations where the setter call naturally describes the update. This is similar to using `setState(prev => ...)` with `useState`.

**Use reducers** when you need to pass data to the update (like which item to add) or when handling multiple types of updates with a single hook.

**Why use a reducer?**

Reducers are essential when the base state might change while your Transition is pending. If `todos` changes while your add is pending (for example, another user added a todo), React will re-run your reducer with the new `todos` to recalculate what to show. This ensures your new todo is added to the latest list, not an outdated copy.

An updater function like `setOptimistic(prev => [...prev, newItem])` would only see the state from when the Transition started, missing any updates that happened during the async work.

***

### Optimistically adding to a list[](#optimistically-adding-to-a-list "Link for Optimistically adding to a list ")

When you need to optimistically add items to a list, use a `reducer`:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useOptimistic, startTransition } from 'react';

export default function TodoList({ todos, addTodoAction }) {
  const [optimisticTodos, addOptimisticTodo] = useOptimistic(
    todos,
    (currentTodos, newTodo) => [
      ...currentTodos,
      { id: newTodo.id, text: newTodo.text, pending: true }
    ]
  );

  function handleAddTodo(text) {
    const newTodo = { id: crypto.randomUUID(), text: text };
    startTransition(async () => {
      addOptimisticTodo(newTodo);
      await addTodoAction(newTodo);
    });
  }

  return (
    <div>
      <button onClick={() => handleAddTodo('New todo')}>Add Todo</button>
      <ul>
        {optimisticTodos.map(todo => (
          <li key={todo.id}>
            {todo.text} {todo.pending && "(Adding...)"}
          </li>
        ))}
      </ul>
    </div>
  );
}
```

The `reducer` receives the current list of todos and the new todo to add. This is important because if the `todos` prop changes while your add is pending (for example, another user added a todo), React will update your optimistic state by re-running the reducer with the updated list. This ensures your new todo is added to the latest list, not an outdated copy.

### Note

Each optimistic item includes a `pending: true` flag so you can show loading state for individual items. When the server responds and the parent updates the canonical `todos` list with the saved item, the optimistic state updates to the confirmed item without the pending flag.

***

### Handling multiple `action` types[](#handling-multiple-action-types "Link for this heading")

When you need to handle multiple types of optimistic updates (like adding and removing items), use a reducer pattern with `action` objects.

This shopping cart example shows how to handle add and remove with a single reducer:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useOptimistic, startTransition } from 'react';

export default function ShoppingCart({ cart, cartActions }) {
  const [optimisticCart, dispatch] = useOptimistic(
    cart,
    (currentCart, action) => {
      switch (action.type) {
        case 'add':
          const exists = currentCart.find(item => item.id === action.item.id);
          if (exists) {
            return currentCart.map(item =>
              item.id === action.item.id
                ? { ...item, quantity: item.quantity + 1, pending: true }
                : item
            );
          }
          return [...currentCart, { ...action.item, quantity: 1, pending: true }];
        case 'remove':
          return currentCart.filter(item => item.id !== action.id);
        case 'update_quantity':
          return currentCart.map(item =>
            item.id === action.id
              ? { ...item, quantity: action.quantity, pending: true }
              : item
          );
        default:
          return currentCart;
      }
    }
  );

  function handleAdd(item) {
    startTransition(async () => {
      dispatch({ type: 'add', item });
      await cartActions.add(item);
    });
  }

  function handleRemove(id) {
    startTransition(async () => {
      dispatch({ type: 'remove', id });
      await cartActions.remove(id);
    });
  }

  function handleUpdateQuantity(id, quantity) {
    startTransition(async () => {
      dispatch({ type: 'update_quantity', id, quantity });
      await cartActions.updateQuantity(id, quantity);
    });
  }

  const total = optimisticCart.reduce(
    (sum, item) => sum + item.price * item.quantity,
    0
  );

  return (
    <div>
      <h2>Shopping Cart</h2>
      <div style={{ marginBottom: 16 }}>
        <button onClick={() => handleAdd({
          id: 1, name: 'T-Shirt', price: 25
        })}>
          Add T-Shirt ($25)
        </button>{' '}
        <button onClick={() => handleAdd({
          id: 2, name: 'Mug', price: 15
        })}>
          Add Mug ($15)
        </button>
      </div>
      {optimisticCart.length === 0 ? (
        <p>Your cart is empty</p>
      ) : (
        <ul>
          {optimisticCart.map(item => (
            <li key={item.id}>
              {item.name} - ${item.price} ×
              {item.quantity}
              {' '}= ${item.price * item.quantity}
              <button
                onClick={() => handleRemove(item.id)}
                style={{ marginLeft: 8 }}
              >
                Remove
              </button>
              {item.pending && ' ...'}
            </li>
          ))}
        </ul>
      )}
      <p><strong>Total: ${total}</strong></p>
    </div>
  );
}
```

The reducer handles three `action` types (`add`, `remove`, `update_quantity`) and returns the new optimistic state for each. Each `action` sets a `pending: true` flag so you can show visual feedback while the [Server Function](/reference/rsc/server-functions) runs.

***

### Optimistic delete with error recovery[](#optimistic-delete-with-error-recovery "Link for Optimistic delete with error recovery ")

When deleting items optimistically, you should handle the case where the Action fails.

This example shows how to display an error message when a delete fails, and the UI automatically rolls back to show the item again.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useOptimistic, startTransition } from 'react';

export default function ItemList({ items, deleteAction }) {
  const [error, setError] = useState(null);
  const [optimisticItems, removeItem] = useOptimistic(
    items,
    (currentItems, idToRemove) =>
      currentItems.map(item =>
        item.id === idToRemove
          ? { ...item, deleting: true }
          : item
      )
  );

  function handleDelete(id) {
    setError(null);
    startTransition(async () => {
      removeItem(id);
      try {
        await deleteAction(id);
      } catch (e) {
        setError(e.message);
      }
    });
  }

  return (
    <div>
      <h2>Your Items</h2>
      <ul>
        {optimisticItems.map(item => (
          <li
            key={item.id}
            style={{
              opacity: item.deleting ? 0.5 : 1,
              textDecoration: item.deleting ? 'line-through' : 'none',
              transition: 'opacity 0.2s'
            }}
          >
            {item.name}
            <button
              onClick={() => handleDelete(item.id)}
              disabled={item.deleting}
              style={{ marginLeft: 8 }}
            >
              {item.deleting ? 'Deleting...' : 'Delete'}
            </button>
          </li>
        ))}
      </ul>
      {error && (
        <p style={{ color: 'red', padding: 8, background: '#fee' }}>
          {error}
        </p>
      )}
    </div>
  );
}
```

Try deleting ‘Deploy to production’. When the delete fails, the item automatically reappears in the list.

***

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### I’m getting an error: “An optimistic state update occurred outside a Transition or Action”[](#an-optimistic-state-update-occurred-outside-a-transition-or-action "Link for I’m getting an error: “An optimistic state update occurred outside a Transition or Action” ")

You may see this error:

Console

An optimistic state update occurred outside a Transition or Action. To fix, move the update to an Action, or wrap with `startTransition`.

The optimistic setter function must be called inside `startTransition`:

```
// 🚩 Incorrect: outside a Transition

function handleClick() {

  setOptimistic(newValue);  // Warning!

  // ...

}



// ✅ Correct: inside a Transition

function handleClick() {

  startTransition(async () => {

    setOptimistic(newValue);

    // ...

  });

}



// ✅ Also correct: inside an Action prop

function submitAction(formData) {

  setOptimistic(newValue);

  // ...

}
```

When you call the setter outside an Action, the optimistic state will briefly appear and then immediately revert back to the original value. This happens because there’s no Transition to “hold” the optimistic state while your Action runs.

### I’m getting an error: “Cannot update optimistic state while rendering”[](#cannot-update-optimistic-state-while-rendering "Link for I’m getting an error: “Cannot update optimistic state while rendering” ")

You may see this error:

Console

Cannot update optimistic state while rendering.

This error occurs when you call the optimistic setter during the render phase of a component. You can only call it from event handlers, effects, or other callbacks:

```
// 🚩 Incorrect: calling during render

function MyComponent({ items }) {

  const [isPending, setPending] = useOptimistic(false);



  // This runs during render - not allowed!

  setPending(true);



  // ...

}



// ✅ Correct: calling inside startTransition

function MyComponent({ items }) {

  const [isPending, setPending] = useOptimistic(false);



  function handleClick() {

    startTransition(() => {

      setPending(true);

      // ...

    });

  }



  // ...

}



// ✅ Also correct: calling from an Action

function MyComponent({ items }) {

  const [isPending, setPending] = useOptimistic(false);



  function action() {

    setPending(true);

    // ...

  }



  // ...

}
```

### My optimistic updates show stale values[](#my-optimistic-updates-show-stale-values "Link for My optimistic updates show stale values ")

If your optimistic state seems to be based on old data, consider using an updater function or reducer to calculate the optimistic state relative to the current state.

```
// May show stale data if state changes during Action

const [optimistic, setOptimistic] = useOptimistic(count);

setOptimistic(5);  // Always sets to 5, even if count changed



// Better: relative updates handle state changes correctly

const [optimistic, adjust] = useOptimistic(count, (current, delta) => current + delta);

adjust(1);  // Always adds 1 to whatever the current count is
```

See [Updating state based on the current state](#updating-state-based-on-current-state) for details.

### I don’t know if my optimistic update is pending[](#i-dont-know-if-my-optimistic-update-is-pending "Link for I don’t know if my optimistic update is pending ")

To know when `useOptimistic` is pending, you have three options:

1. **Check if `optimisticValue === value`**

```
const [optimistic, setOptimistic] = useOptimistic(value);

const isPending = optimistic !== value;
```

If the values are not equal, there’s a Transition in progress.

2. **Add a `useTransition`**

```
const [isPending, startTransition] = useTransition();

const [optimistic, setOptimistic] = useOptimistic(value);



//...

startTransition(() => {

  setOptimistic(state);

})
```

Since `useTransition` uses `useOptimistic` for `isPending` under the hood, this is equivalent to option 1.

3. **Add a `pending` flag in your reducer**

```
const [optimistic, addOptimistic] = useOptimistic(

  items,

  (state, newItem) => [...state, { ...newItem, isPending: true }]

);
```

Since each optimistic item has its own flag, you can show loading state for individual items.

[PrevioususeMemo](/reference/react/useMemo)

[NextuseReducer](/reference/react/useReducer)

***

----
url: https://react.dev/learn/removing-effect-dependencies
----

```
const serverUrl = 'https://localhost:1234';



function ChatRoom({ roomId }) {

  useEffect(() => {

    const connection = createConnection(serverUrl, roomId);

    connection.connect();

    return () => connection.disconnect();

  	// ...

}
```

Then, if you leave the Effect dependencies empty (`[]`), the linter will suggest the correct dependencies:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useEffect } from 'react';
import { createConnection } from './chat.js';

const serverUrl = 'https://localhost:1234';

function ChatRoom({ roomId }) {
  useEffect(() => {
    const connection = createConnection(serverUrl, roomId);
    connection.connect();
    return () => connection.disconnect();
  }, []); // <-- Fix the mistake here!
  return <h1>Welcome to the {roomId} room!</h1>;
}

export default function App() {
  const [roomId, setRoomId] = useState('general');
  return (
    <>
      <label>
        Choose the chat room:{' '}
        <select
          value={roomId}
          onChange={e => setRoomId(e.target.value)}
        >
          <option value="general">general</option>
          <option value="travel">travel</option>
          <option value="music">music</option>
        </select>
      </label>
      <hr />
      <ChatRoom roomId={roomId} />
    </>
  );
}
```

Fill them in according to what the linter says:

```
function ChatRoom({ roomId }) {

  useEffect(() => {

    const connection = createConnection(serverUrl, roomId);

    connection.connect();

    return () => connection.disconnect();

  }, [roomId]); // ✅ All dependencies declared

  // ...

}
```

[Effects “react” to reactive values.](/learn/lifecycle-of-reactive-effects#effects-react-to-reactive-values) Since `roomId` is a reactive value (it can change due to a re-render), the linter verifies that you’ve specified it as a dependency. If `roomId` receives a different value, React will re-synchronize your Effect. This ensures that the chat stays connected to the selected room and “reacts” to the dropdown:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useEffect } from 'react';
import { createConnection } from './chat.js';

const serverUrl = 'https://localhost:1234';

function ChatRoom({ roomId }) {
  useEffect(() => {
    const connection = createConnection(serverUrl, roomId);
    connection.connect();
    return () => connection.disconnect();
  }, [roomId]);
  return <h1>Welcome to the {roomId} room!</h1>;
}

export default function App() {
  const [roomId, setRoomId] = useState('general');
  return (
    <>
      <label>
        Choose the chat room:{' '}
        <select
          value={roomId}
          onChange={e => setRoomId(e.target.value)}
        >
          <option value="general">general</option>
          <option value="travel">travel</option>
          <option value="music">music</option>
        </select>
      </label>
      <hr />
      <ChatRoom roomId={roomId} />
    </>
  );
}
```

### To remove a dependency, prove that it’s not a dependency[](#to-remove-a-dependency-prove-that-its-not-a-dependency "Link for To remove a dependency, prove that it’s not a dependency ")

Notice that you can’t “choose” the dependencies of your Effect. Every reactive value used by your Effect’s code must be declared in your dependency list. The dependency list is determined by the surrounding code:

```
const serverUrl = 'https://localhost:1234';



function ChatRoom({ roomId }) { // This is a reactive value

  useEffect(() => {

    const connection = createConnection(serverUrl, roomId); // This Effect reads that reactive value

    connection.connect();

    return () => connection.disconnect();

  }, [roomId]); // ✅ So you must specify that reactive value as a dependency of your Effect

  // ...

}
```

[Reactive values](/learn/lifecycle-of-reactive-effects#all-variables-declared-in-the-component-body-are-reactive) include props and all variables and functions declared directly inside of your component. Since `roomId` is a reactive value, you can’t remove it from the dependency list. The linter wouldn’t allow it:

```
const serverUrl = 'https://localhost:1234';



function ChatRoom({ roomId }) {

  useEffect(() => {

    const connection = createConnection(serverUrl, roomId);

    connection.connect();

    return () => connection.disconnect();

  }, []); // 🔴 React Hook useEffect has a missing dependency: 'roomId'

  // ...

}
```

And the linter would be right! Since `roomId` may change over time, this would introduce a bug in your code.

**To remove a dependency, “prove” to the linter that it *doesn’t need* to be a dependency.** For example, you can move `roomId` out of your component to prove that it’s not reactive and won’t change on re-renders:

```
const serverUrl = 'https://localhost:1234';

const roomId = 'music'; // Not a reactive value anymore



function ChatRoom() {

  useEffect(() => {

    const connection = createConnection(serverUrl, roomId);

    connection.connect();

    return () => connection.disconnect();

  }, []); // ✅ All dependencies declared

  // ...

}
```

Now that `roomId` is not a reactive value (and can’t change on a re-render), it doesn’t need to be a dependency:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useEffect } from 'react';
import { createConnection } from './chat.js';

const serverUrl = 'https://localhost:1234';
const roomId = 'music';

export default function ChatRoom() {
  useEffect(() => {
    const connection = createConnection(serverUrl, roomId);
    connection.connect();
    return () => connection.disconnect();
  }, []);
  return <h1>Welcome to the {roomId} room!</h1>;
}
```

```
useEffect(() => {

  // ...

  // 🔴 Avoid suppressing the linter like this:

  // eslint-ignore-next-line react-hooks/exhaustive-deps

}, []);
```

**When dependencies don’t match the code, there is a very high risk of introducing bugs.** By suppressing the linter, you “lie” to React about the values your Effect depends on.

Instead, use the techniques below.

##### Deep Dive#### Why is suppressing the dependency linter so dangerous?[](#why-is-suppressing-the-dependency-linter-so-dangerous "Link for Why is suppressing the dependency linter so dangerous? ")

Suppressing the linter leads to very unintuitive bugs that are hard to find and fix. Here’s one example:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useEffect } from 'react';

export default function Timer() {
  const [count, setCount] = useState(0);
  const [increment, setIncrement] = useState(1);

  function onTick() {
	setCount(count + increment);
  }

  useEffect(() => {
    const id = setInterval(onTick, 1000);
    return () => clearInterval(id);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  return (
    <>
      <h1>
        Counter: {count}
        <button onClick={() => setCount(0)}>Reset</button>
      </h1>
      <hr />
      <p>
        Every second, increment by:
        <button disabled={increment === 0} onClick={() => {
          setIncrement(i => i - 1);
        }}>–</button>
        <b>{increment}</b>
        <button onClick={() => {
          setIncrement(i => i + 1);
        }}>+</button>
      </p>
    </>
  );
}
```

```
function Form() {

  const [submitted, setSubmitted] = useState(false);



  useEffect(() => {

    if (submitted) {

      // 🔴 Avoid: Event-specific logic inside an Effect

      post('/api/register');

      showNotification('Successfully registered!');

    }

  }, [submitted]);



  function handleSubmit() {

    setSubmitted(true);

  }



  // ...

}
```

Later, you want to style the notification message according to the current theme, so you read the current theme. Since `theme` is declared in the component body, it is a reactive value, so you add it as a dependency:

```
function Form() {

  const [submitted, setSubmitted] = useState(false);

  const theme = useContext(ThemeContext);



  useEffect(() => {

    if (submitted) {

      // 🔴 Avoid: Event-specific logic inside an Effect

      post('/api/register');

      showNotification('Successfully registered!', theme);

    }

  }, [submitted, theme]); // ✅ All dependencies declared



  function handleSubmit() {

    setSubmitted(true);

  }



  // ...

}
```

By doing this, you’ve introduced a bug. Imagine you submit the form first and then switch between Dark and Light themes. The `theme` will change, the Effect will re-run, and so it will display the same notification again!

**The problem here is that this shouldn’t be an Effect in the first place.** You want to send this POST request and show the notification in response to *submitting the form,* which is a particular interaction. To run some code in response to particular interaction, put that logic directly into the corresponding event handler:

```
function Form() {

  const theme = useContext(ThemeContext);



  function handleSubmit() {

    // ✅ Good: Event-specific logic is called from event handlers

    post('/api/register');

    showNotification('Successfully registered!', theme);

  }



  // ...

}
```

Now that the code is in an event handler, it’s not reactive—so it will only run when the user submits the form. Read more about [choosing between event handlers and Effects](/learn/separating-events-from-effects#reactive-values-and-reactive-logic) and [how to delete unnecessary Effects.](/learn/you-might-not-need-an-effect)

### Is your Effect doing several unrelated things?[](#is-your-effect-doing-several-unrelated-things "Link for Is your Effect doing several unrelated things? ")

The next question you should ask yourself is whether your Effect is doing several unrelated things.

Imagine you’re creating a shipping form where the user needs to choose their city and area. You fetch the list of `cities` from the server according to the selected `country` to show them in a dropdown:

```
function ShippingForm({ country }) {

  const [cities, setCities] = useState(null);

  const [city, setCity] = useState(null);



  useEffect(() => {

    let ignore = false;

    fetch(`/api/cities?country=${country}`)

      .then(response => response.json())

      .then(json => {

        if (!ignore) {

          setCities(json);

        }

      });

    return () => {

      ignore = true;

    };

  }, [country]); // ✅ All dependencies declared



  // ...
```

This is a good example of [fetching data in an Effect.](/learn/you-might-not-need-an-effect#fetching-data) You are synchronizing the `cities` state with the network according to the `country` prop. You can’t do this in an event handler because you need to fetch as soon as `ShippingForm` is displayed and whenever the `country` changes (no matter which interaction causes it).

Now let’s say you’re adding a second select box for city areas, which should fetch the `areas` for the currently selected `city`. You might start by adding a second `fetch` call for the list of areas inside the same Effect:

```
function ShippingForm({ country }) {

  const [cities, setCities] = useState(null);

  const [city, setCity] = useState(null);

  const [areas, setAreas] = useState(null);



  useEffect(() => {

    let ignore = false;

    fetch(`/api/cities?country=${country}`)

      .then(response => response.json())

      .then(json => {

        if (!ignore) {

          setCities(json);

        }

      });

    // 🔴 Avoid: A single Effect synchronizes two independent processes

    if (city) {

      fetch(`/api/areas?city=${city}`)

        .then(response => response.json())

        .then(json => {

          if (!ignore) {

            setAreas(json);

          }

        });

    }

    return () => {

      ignore = true;

    };

  }, [country, city]); // ✅ All dependencies declared



  // ...
```

However, since the Effect now uses the `city` state variable, you’ve had to add `city` to the list of dependencies. That, in turn, introduced a problem: when the user selects a different city, the Effect will re-run and call `fetchCities(country)`. As a result, you will be unnecessarily refetching the list of cities many times.

**The problem with this code is that you’re synchronizing two different unrelated things:**

1. You want to synchronize the `cities` state to the network based on the `country` prop.
2. You want to synchronize the `areas` state to the network based on the `city` state.

Split the logic into two Effects, each of which reacts to the prop that it needs to synchronize with:

```
function ShippingForm({ country }) {

  const [cities, setCities] = useState(null);

  useEffect(() => {

    let ignore = false;

    fetch(`/api/cities?country=${country}`)

      .then(response => response.json())

      .then(json => {

        if (!ignore) {

          setCities(json);

        }

      });

    return () => {

      ignore = true;

    };

  }, [country]); // ✅ All dependencies declared



  const [city, setCity] = useState(null);

  const [areas, setAreas] = useState(null);

  useEffect(() => {

    if (city) {

      let ignore = false;

      fetch(`/api/areas?city=${city}`)

        .then(response => response.json())

        .then(json => {

          if (!ignore) {

            setAreas(json);

          }

        });

      return () => {

        ignore = true;

      };

    }

  }, [city]); // ✅ All dependencies declared



  // ...
```

Now the first Effect only re-runs if the `country` changes, while the second Effect re-runs when the `city` changes. You’ve separated them by purpose: two different things are synchronized by two separate Effects. Two separate Effects have two separate dependency lists, so they won’t trigger each other unintentionally.

The final code is longer than the original, but splitting these Effects is still correct. [Each Effect should represent an independent synchronization process.](/learn/lifecycle-of-reactive-effects#each-effect-represents-a-separate-synchronization-process) In this example, deleting one Effect doesn’t break the other Effect’s logic. This means they *synchronize different things,* and it’s good to split them up. If you’re concerned about duplication, you can improve this code by [extracting repetitive logic into a custom Hook.](/learn/reusing-logic-with-custom-hooks#when-to-use-custom-hooks)

### Are you reading some state to calculate the next state?[](#are-you-reading-some-state-to-calculate-the-next-state "Link for Are you reading some state to calculate the next state? ")

This Effect updates the `messages` state variable with a newly created array every time a new message arrives:

```
function ChatRoom({ roomId }) {

  const [messages, setMessages] = useState([]);

  useEffect(() => {

    const connection = createConnection();

    connection.connect();

    connection.on('message', (receivedMessage) => {

      setMessages([...messages, receivedMessage]);

    });

    // ...
```

It uses the `messages` variable to [create a new array](/learn/updating-arrays-in-state) starting with all the existing messages and adds the new message at the end. However, since `messages` is a reactive value read by an Effect, it must be a dependency:

```
function ChatRoom({ roomId }) {

  const [messages, setMessages] = useState([]);

  useEffect(() => {

    const connection = createConnection();

    connection.connect();

    connection.on('message', (receivedMessage) => {

      setMessages([...messages, receivedMessage]);

    });

    return () => connection.disconnect();

  }, [roomId, messages]); // ✅ All dependencies declared

  // ...
```

And making `messages` a dependency introduces a problem.

Every time you receive a message, `setMessages()` causes the component to re-render with a new `messages` array that includes the received message. However, since this Effect now depends on `messages`, this will *also* re-synchronize the Effect. So every new message will make the chat re-connect. The user would not like that!

To fix the issue, don’t read `messages` inside the Effect. Instead, pass an [updater function](/reference/react/useState#updating-state-based-on-the-previous-state) to `setMessages`:

```
function ChatRoom({ roomId }) {

  const [messages, setMessages] = useState([]);

  useEffect(() => {

    const connection = createConnection();

    connection.connect();

    connection.on('message', (receivedMessage) => {

      setMessages(msgs => [...msgs, receivedMessage]);

    });

    return () => connection.disconnect();

  }, [roomId]); // ✅ All dependencies declared

  // ...
```

**Notice how your Effect does not read the `messages` variable at all now.** You only need to pass an updater function like `msgs => [...msgs, receivedMessage]`. React [puts your updater function in a queue](/learn/queueing-a-series-of-state-updates) and will provide the `msgs` argument to it during the next render. This is why the Effect itself doesn’t need to depend on `messages` anymore. As a result of this fix, receiving a chat message will no longer make the chat re-connect.

### Do you want to read a value without “reacting” to its changes?[](#do-you-want-to-read-a-value-without-reacting-to-its-changes "Link for Do you want to read a value without “reacting” to its changes? ")

Suppose that you want to play a sound when the user receives a new message unless `isMuted` is `true`:

```
function ChatRoom({ roomId }) {

  const [messages, setMessages] = useState([]);

  const [isMuted, setIsMuted] = useState(false);



  useEffect(() => {

    const connection = createConnection();

    connection.connect();

    connection.on('message', (receivedMessage) => {

      setMessages(msgs => [...msgs, receivedMessage]);

      if (!isMuted) {

        playSound();

      }

    });

    // ...
```

Since your Effect now uses `isMuted` in its code, you have to add it to the dependencies:

```
function ChatRoom({ roomId }) {

  const [messages, setMessages] = useState([]);

  const [isMuted, setIsMuted] = useState(false);



  useEffect(() => {

    const connection = createConnection();

    connection.connect();

    connection.on('message', (receivedMessage) => {

      setMessages(msgs => [...msgs, receivedMessage]);

      if (!isMuted) {

        playSound();

      }

    });

    return () => connection.disconnect();

  }, [roomId, isMuted]); // ✅ All dependencies declared

  // ...
```

The problem is that every time `isMuted` changes (for example, when the user presses the “Muted” toggle), the Effect will re-synchronize, and reconnect to the chat. This is not the desired user experience! (In this example, even disabling the linter would not work—if you do that, `isMuted` would get “stuck” with its old value.)

To solve this problem, you need to extract the logic that shouldn’t be reactive out of the Effect. You don’t want this Effect to “react” to the changes in `isMuted`. [Move this non-reactive piece of logic into an Effect Event:](/learn/separating-events-from-effects#declaring-an-effect-event)

```
import { useState, useEffect, useEffectEvent } from 'react';



function ChatRoom({ roomId }) {

  const [messages, setMessages] = useState([]);

  const [isMuted, setIsMuted] = useState(false);



  const onMessage = useEffectEvent(receivedMessage => {

    setMessages(msgs => [...msgs, receivedMessage]);

    if (!isMuted) {

      playSound();

    }

  });



  useEffect(() => {

    const connection = createConnection();

    connection.connect();

    connection.on('message', (receivedMessage) => {

      onMessage(receivedMessage);

    });

    return () => connection.disconnect();

  }, [roomId]); // ✅ All dependencies declared

  // ...
```

Effect Events let you split an Effect into reactive parts (which should “react” to reactive values like `roomId` and their changes) and non-reactive parts (which only read their latest values, like `onMessage` reads `isMuted`). **Now that you read `isMuted` inside an Effect Event, it doesn’t need to be a dependency of your Effect.** As a result, the chat won’t re-connect when you toggle the “Muted” setting on and off, solving the original issue!

#### Wrapping an event handler from the props[](#wrapping-an-event-handler-from-the-props "Link for Wrapping an event handler from the props ")

You might run into a similar problem when your component receives an event handler as a prop:

```
function ChatRoom({ roomId, onReceiveMessage }) {

  const [messages, setMessages] = useState([]);



  useEffect(() => {

    const connection = createConnection();

    connection.connect();

    connection.on('message', (receivedMessage) => {

      onReceiveMessage(receivedMessage);

    });

    return () => connection.disconnect();

  }, [roomId, onReceiveMessage]); // ✅ All dependencies declared

  // ...
```

Suppose that the parent component passes a *different* `onReceiveMessage` function on every render:

```
<ChatRoom

  roomId={roomId}

  onReceiveMessage={receivedMessage => {

    // ...

  }}

/>
```

Since `onReceiveMessage` is a dependency, it would cause the Effect to re-synchronize after every parent re-render. This would make it re-connect to the chat. To solve this, wrap the call in an Effect Event:

```
function ChatRoom({ roomId, onReceiveMessage }) {

  const [messages, setMessages] = useState([]);



  const onMessage = useEffectEvent(receivedMessage => {

    onReceiveMessage(receivedMessage);

  });



  useEffect(() => {

    const connection = createConnection();

    connection.connect();

    connection.on('message', (receivedMessage) => {

      onMessage(receivedMessage);

    });

    return () => connection.disconnect();

  }, [roomId]); // ✅ All dependencies declared

  // ...
```

Effect Events aren’t reactive, so you don’t need to specify them as dependencies. As a result, the chat will no longer re-connect even if the parent component passes a function that’s different on every re-render.

#### Separating reactive and non-reactive code[](#separating-reactive-and-non-reactive-code "Link for Separating reactive and non-reactive code ")

In this example, you want to log a visit every time `roomId` changes. You want to include the current `notificationCount` with every log, but you *don’t* want a change to `notificationCount` to trigger a log event.

The solution is again to split out the non-reactive code into an Effect Event:

```
function Chat({ roomId, notificationCount }) {

  const onVisit = useEffectEvent(visitedRoomId => {

    logVisit(visitedRoomId, notificationCount);

  });



  useEffect(() => {

    onVisit(roomId);

  }, [roomId]); // ✅ All dependencies declared

  // ...

}
```

You want your logic to be reactive with regards to `roomId`, so you read `roomId` inside of your Effect. However, you don’t want a change to `notificationCount` to log an extra visit, so you read `notificationCount` inside of the Effect Event. [Learn more about reading the latest props and state from Effects using Effect Events.](/learn/separating-events-from-effects#reading-latest-props-and-state-with-effect-events)

### Does some reactive value change unintentionally?[](#does-some-reactive-value-change-unintentionally "Link for Does some reactive value change unintentionally? ")

Sometimes, you *do* want your Effect to “react” to a certain value, but that value changes more often than you’d like—and might not reflect any actual change from the user’s perspective. For example, let’s say that you create an `options` object in the body of your component, and then read that object from inside of your Effect:

```
function ChatRoom({ roomId }) {

  // ...

  const options = {

    serverUrl: serverUrl,

    roomId: roomId

  };



  useEffect(() => {

    const connection = createConnection(options);

    connection.connect();

    // ...
```

This object is declared in the component body, so it’s a [reactive value.](/learn/lifecycle-of-reactive-effects#effects-react-to-reactive-values) When you read a reactive value like this inside an Effect, you declare it as a dependency. This ensures your Effect “reacts” to its changes:

```
  // ...

  useEffect(() => {

    const connection = createConnection(options);

    connection.connect();

    return () => connection.disconnect();

  }, [options]); // ✅ All dependencies declared

  // ...
```

It is important to declare it as a dependency! This ensures, for example, that if the `roomId` changes, your Effect will re-connect to the chat with the new `options`. However, there is also a problem with the code above. To see it, try typing into the input in the sandbox below, and watch what happens in the console:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useEffect } from 'react';
import { createConnection } from './chat.js';

const serverUrl = 'https://localhost:1234';

function ChatRoom({ roomId }) {
  const [message, setMessage] = useState('');

  // Temporarily disable the linter to demonstrate the problem
  // eslint-disable-next-line react-hooks/exhaustive-deps
  const options = {
    serverUrl: serverUrl,
    roomId: roomId
  };

  useEffect(() => {
    const connection = createConnection(options);
    connection.connect();
    return () => connection.disconnect();
  }, [options]);

  return (
    <>
      <h1>Welcome to the {roomId} room!</h1>
      <input value={message} onChange={e => setMessage(e.target.value)} />
    </>
  );
}

export default function App() {
  const [roomId, setRoomId] = useState('general');
  return (
    <>
      <label>
        Choose the chat room:{' '}
        <select
          value={roomId}
          onChange={e => setRoomId(e.target.value)}
        >
          <option value="general">general</option>
          <option value="travel">travel</option>
          <option value="music">music</option>
        </select>
      </label>
      <hr />
      <ChatRoom roomId={roomId} />
    </>
  );
}
```

In the sandbox above, the input only updates the `message` state variable. From the user’s perspective, this should not affect the chat connection. However, every time you update the `message`, your component re-renders. When your component re-renders, the code inside of it runs again from scratch.

A new `options` object is created from scratch on every re-render of the `ChatRoom` component. React sees that the `options` object is a *different object* from the `options` object created during the last render. This is why it re-synchronizes your Effect (which depends on `options`), and the chat re-connects as you type.

**This problem only affects objects and functions. In JavaScript, each newly created object and function is considered distinct from all the others. It doesn’t matter that the contents inside of them may be the same!**

```
// During the first render

const options1 = { serverUrl: 'https://localhost:1234', roomId: 'music' };



// During the next render

const options2 = { serverUrl: 'https://localhost:1234', roomId: 'music' };



// These are two different objects!

console.log(Object.is(options1, options2)); // false
```

**Object and function dependencies can make your Effect re-synchronize more often than you need.**

This is why, whenever possible, you should try to avoid objects and functions as your Effect’s dependencies. Instead, try moving them outside the component, inside the Effect, or extracting primitive values out of them.

#### Move static objects and functions outside your component[](#move-static-objects-and-functions-outside-your-component "Link for Move static objects and functions outside your component ")

If the object does not depend on any props and state, you can move that object outside your component:

```
const options = {

  serverUrl: 'https://localhost:1234',

  roomId: 'music'

};



function ChatRoom() {

  const [message, setMessage] = useState('');



  useEffect(() => {

    const connection = createConnection(options);

    connection.connect();

    return () => connection.disconnect();

  }, []); // ✅ All dependencies declared

  // ...
```

This way, you *prove* to the linter that it’s not reactive. It can’t change as a result of a re-render, so it doesn’t need to be a dependency. Now re-rendering `ChatRoom` won’t cause your Effect to re-synchronize.

This works for functions too:

```
function createOptions() {

  return {

    serverUrl: 'https://localhost:1234',

    roomId: 'music'

  };

}



function ChatRoom() {

  const [message, setMessage] = useState('');



  useEffect(() => {

    const options = createOptions();

    const connection = createConnection(options);

    connection.connect();

    return () => connection.disconnect();

  }, []); // ✅ All dependencies declared

  // ...
```

Since `createOptions` is declared outside your component, it’s not a reactive value. This is why it doesn’t need to be specified in your Effect’s dependencies, and why it won’t ever cause your Effect to re-synchronize.

#### Move dynamic objects and functions inside your Effect[](#move-dynamic-objects-and-functions-inside-your-effect "Link for Move dynamic objects and functions inside your Effect ")

If your object depends on some reactive value that may change as a result of a re-render, like a `roomId` prop, you can’t pull it *outside* your component. You can, however, move its creation *inside* of your Effect’s code:

```
const serverUrl = 'https://localhost:1234';



function ChatRoom({ roomId }) {

  const [message, setMessage] = useState('');



  useEffect(() => {

    const options = {

      serverUrl: serverUrl,

      roomId: roomId

    };

    const connection = createConnection(options);

    connection.connect();

    return () => connection.disconnect();

  }, [roomId]); // ✅ All dependencies declared

  // ...
```

Now that `options` is declared inside of your Effect, it is no longer a dependency of your Effect. Instead, the only reactive value used by your Effect is `roomId`. Since `roomId` is not an object or function, you can be sure that it won’t be *unintentionally* different. In JavaScript, numbers and strings are compared by their content:

```
// During the first render

const roomId1 = 'music';



// During the next render

const roomId2 = 'music';



// These two strings are the same!

console.log(Object.is(roomId1, roomId2)); // true
```

Thanks to this fix, the chat no longer re-connects if you edit the input:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useEffect } from 'react';
import { createConnection } from './chat.js';

const serverUrl = 'https://localhost:1234';

function ChatRoom({ roomId }) {
  const [message, setMessage] = useState('');

  useEffect(() => {
    const options = {
      serverUrl: serverUrl,
      roomId: roomId
    };
    const connection = createConnection(options);
    connection.connect();
    return () => connection.disconnect();
  }, [roomId]);

  return (
    <>
      <h1>Welcome to the {roomId} room!</h1>
      <input value={message} onChange={e => setMessage(e.target.value)} />
    </>
  );
}

export default function App() {
  const [roomId, setRoomId] = useState('general');
  return (
    <>
      <label>
        Choose the chat room:{' '}
        <select
          value={roomId}
          onChange={e => setRoomId(e.target.value)}
        >
          <option value="general">general</option>
          <option value="travel">travel</option>
          <option value="music">music</option>
        </select>
      </label>
      <hr />
      <ChatRoom roomId={roomId} />
    </>
  );
}
```

However, it *does* re-connect when you change the `roomId` dropdown, as you would expect.

This works for functions, too:

```
const serverUrl = 'https://localhost:1234';



function ChatRoom({ roomId }) {

  const [message, setMessage] = useState('');



  useEffect(() => {

    function createOptions() {

      return {

        serverUrl: serverUrl,

        roomId: roomId

      };

    }



    const options = createOptions();

    const connection = createConnection(options);

    connection.connect();

    return () => connection.disconnect();

  }, [roomId]); // ✅ All dependencies declared

  // ...
```

You can write your own functions to group pieces of logic inside your Effect. As long as you also declare them *inside* your Effect, they’re not reactive values, and so they don’t need to be dependencies of your Effect.

#### Read primitive values from objects[](#read-primitive-values-from-objects "Link for Read primitive values from objects ")

Sometimes, you may receive an object from props:

```
function ChatRoom({ options }) {

  const [message, setMessage] = useState('');



  useEffect(() => {

    const connection = createConnection(options);

    connection.connect();

    return () => connection.disconnect();

  }, [options]); // ✅ All dependencies declared

  // ...
```

The risk here is that the parent component will create the object during rendering:

```
<ChatRoom

  roomId={roomId}

  options={{

    serverUrl: serverUrl,

    roomId: roomId

  }}

/>
```

This would cause your Effect to re-connect every time the parent component re-renders. To fix this, read information from the object *outside* the Effect, and avoid having object and function dependencies:

```
function ChatRoom({ options }) {

  const [message, setMessage] = useState('');



  const { roomId, serverUrl } = options;

  useEffect(() => {

    const connection = createConnection({

      roomId: roomId,

      serverUrl: serverUrl

    });

    connection.connect();

    return () => connection.disconnect();

  }, [roomId, serverUrl]); // ✅ All dependencies declared

  // ...
```

The logic gets a little repetitive (you read some values from an object outside an Effect, and then create an object with the same values inside the Effect). But it makes it very explicit what information your Effect *actually* depends on. If an object is re-created unintentionally by the parent component, the chat would not re-connect. However, if `options.roomId` or `options.serverUrl` really are different, the chat would re-connect.

#### Calculate primitive values from functions[](#calculate-primitive-values-from-functions "Link for Calculate primitive values from functions ")

The same approach can work for functions. For example, suppose the parent component passes a function:

```
<ChatRoom

  roomId={roomId}

  getOptions={() => {

    return {

      serverUrl: serverUrl,

      roomId: roomId

    };

  }}

/>
```

To avoid making it a dependency (and causing it to re-connect on re-renders), call it outside the Effect. This gives you the `roomId` and `serverUrl` values that aren’t objects, and that you can read from inside your Effect:

```
function ChatRoom({ getOptions }) {

  const [message, setMessage] = useState('');



  const { roomId, serverUrl } = getOptions();

  useEffect(() => {

    const connection = createConnection({

      roomId: roomId,

      serverUrl: serverUrl

    });

    connection.connect();

    return () => connection.disconnect();

  }, [roomId, serverUrl]); // ✅ All dependencies declared

  // ...
```

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useEffect } from 'react';

export default function Timer() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    console.log('✅ Creating an interval');
    const id = setInterval(() => {
      console.log('⏰ Interval tick');
      setCount(count + 1);
    }, 1000);
    return () => {
      console.log('❌ Clearing an interval');
      clearInterval(id);
    };
  }, [count]);

  return <h1>Counter: {count}</h1>
}
```

[PreviousSeparating Events from Effects](/learn/separating-events-from-effects)

[NextReusing Logic with Custom Hooks](/learn/reusing-logic-with-custom-hooks)

***

----
url: https://legacy.reactjs.org/blog/2015/03/30/community-roundup-26.html
----

March 30, 2015 by [Vjeux](https://twitter.com/vjeux)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

We open sourced React Native last week and the community reception blew away all our expectations! So many of you tried it, made cool stuff with it, raised many issues and even submitted pull requests to fix them! The entire team wants to say thank you!

> [#reactnative](https://twitter.com/hashtag/reactnative?src=hash) is like when you get a new expansion pack, and everybody is running around clueless about which NPC to talk to for the quests
>
> — Ryan Florence (@ryanflorence) [March 28, 2015](https://twitter.com/ryanflorence/status/581810423554543616)

## [](#when-is-react-native-android-coming)When is React Native Android coming?

**Give us 6 months**. At Facebook, we strive to only open-source projects that we are using in production. While the Android backend for React Native is starting to work (see video below at 37min), it hasn’t been shipped to any users yet. There’s a lot of work that goes into open-sourcing a project, and we want to do it right so that you have a great experience when using it.

## [](#ray-wenderlich---property-finder)Ray Wenderlich - Property Finder

If you are getting started with React Native, you should absolutely [use this tutorial](http://www.raywenderlich.com/99473/introducing-react-native-building-apps-javascript) from Colin Eberhardt. It goes through all the steps to make a reasonably complete app.

[](http://www.raywenderlich.com/99473/introducing-react-native-building-apps-javascript)

Colin also [blogged about his experience using React Native](http://blog.scottlogic.com/2015/03/26/react-native-retrospective.html) for a few weeks and gives his thoughts on why you would or wouldn’t use it.

## [](#the-changelog)The Changelog

Spencer Ahrens and I had the great pleasure to talk about React Native on [The Changelog](https://thechangelog.com/149/) podcast. It was really fun to chat for an hour, I hope that you’ll enjoy listening to it. :)

## [](#hacker-news)Hacker News

Less than 24 hours after React Native was open sourced, Simarpreet Singh built an [Hacker News reader app from scratch](https://github.com/iSimar/HackerNews-React-Native). It’s unbelievable how fast he was able to pull it off!

[](https://github.com/iSimar/HackerNews-React-Native)

## [](#parse--react)Parse + React

There’s a huge ecosystem of JavaScript modules on npm and React Native was designed to work well with the ones that don’t have DOM dependencies. Parse is a great example; you can `npm install parse` on your React Native project and it’ll work as is. :) We still have [a](https://github.com/facebook/react-native/issues/406) [few](https://github.com/facebook/react-native/issues/370) [issues](https://github.com/facebook/react-native/issues/316) to solve; please create an issue if your favorite library doesn’t work out of the box.

[](http://blog.parse.com/2015/03/25/parse-and-react-shared-chemistry/)

## [](#tcomb-form-native)tcomb-form-native

Giulio Canti is the author of the [tcomb-form library](https://github.com/gcanti/tcomb-form) for React. He already [ported it to React Native](https://github.com/gcanti/tcomb-form-native) and it looks great!

[](https://github.com/gcanti/tcomb-form-native)

## [](#facebook-login-with-react-native)Facebook Login with React Native

One of the reason we built React Native is to be able to use all the libraries in the native ecosystem. Brent Vatne leads the way and explains [how to use Facebook Login with React Native](http://brentvatne.ca/facebook-login-with-react-native/).

## [](#modus-create)Modus Create

Jay Garcia spent a lot of time during the beta working on a NES music player with React Native. He wrote a blog post to share his experience and explains some code snippets.

[](http://moduscreate.com/react-native-has-landed/)

## [](#react-native-with-babel-and-webpack)React Native with Babel and webpack

React Native ships with a custom packager and custom ES6 transforms instead of using what the open source community settled on such as [webpack](https://webpack.js.org/) and [Babel](https://babeljs.io/). The main reason for this is performance – we couldn’t get those tools to have sub-second reload time on a large codebase.

Roman Liutikov found a way to [use webpack and Babel to run on React Native](https://github.com/roman01la/react-native-babel)! In the future, we want to work with those projects to provide cleaner extension mechanisms.

## [](#a-dynamic-crazy-native-mobile-futurepowered-by-javascript)A Dynamic, Crazy, Native Mobile Future—Powered by JavaScript

Clay Allsopp wrote a post about [all the crazy things you could do with a JavaScript engine that renders native views](https://medium.com/@clayallsopp/a-dynamic-crazy-native-mobile-future-powered-by-javascript-70f2d56b1987). What about native embeds, seamless native browser, native search engine or even app generation…

## [](#random-tweet)Random Tweet

We’ve spent a lot of efforts getting the onboarding as easy as possible and we’re really happy that people noticed. We still have a lot of work to do on documentation, stay tuned!

> Wow. Getting started with React Native might have been the smoothest experience I’ve ever had with a new developer product.
>
> — Andreas Eldh (@eldh) [March 26, 2015](https://twitter.com/eldh/status/581186172094980096)

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2015-03-30-community-roundup-26.md)

----
url: https://legacy.reactjs.org/docs/concurrent-mode-intro.html
----

> Caution:
>
> This page is **somewhat outdated** and only exists for historical purposes.
>
> React 18 was released with support for concurrency. However, **there is no “mode” anymore,** and the new behavior is fully opt-in and only enabled [when you use the new features](https://reactjs.org/blog/2022/03/29/react-v18.html#gradually-adopting-concurrent-features).
>
> **For up-to-date high-level information, refer to:**
>
> * [React 18 Announcement](https://reactjs.org/blog/2022/03/29/react-v18.html)
> * [Upgrading to React 18](https://reactjs.org/blog/2022/03/08/react-18-upgrade-guide.html)
> * [React Conf 2021 Videos](https://reactjs.org/blog/2021/12/17/react-conf-2021-recap.html)
>
> **For details about concurrent APIs in React 18, refer to:**
>
> * [`React.Suspense`](https://reactjs.org/docs/react-api.html#reactsuspense) reference
> * [`React.startTransition`](https://reactjs.org/docs/react-api.html#starttransition) reference
> * [`React.useTransition`](https://reactjs.org/docs/hooks-reference.html#usetransition) reference
> * [`React.useDeferredValue`](https://reactjs.org/docs/hooks-reference.html#usedeferredvalue) reference
>
> The rest of this page includes content that’s stale, broken, or incorrect.

This page provides a theoretical overview of Concurrent Mode. **For a more practical introduction, you might want to check out the next sections:**

* [Suspense for Data Fetching](/docs/concurrent-mode-suspense.html) describes a new mechanism for fetching data in React components.
* [Concurrent UI Patterns](/docs/concurrent-mode-patterns.html) shows some UI patterns made possible by Concurrent Mode and Suspense.
* [Adopting Concurrent Mode](/docs/concurrent-mode-adoption.html) explains how you can try Concurrent Mode in your project.
* [Concurrent Mode API Reference](/docs/concurrent-mode-reference.html) documents the new APIs available in experimental builds.

## [](#what-is-concurrent-mode)What Is Concurrent Mode?

> Caution:
>
> This explanation is outdated. The strategy of a separate “mode” was abandoned in React 18. Instead, concurrent rendering is only enabled when you use concurrent features.

Concurrent Mode is a set of new features that help React apps stay responsive and gracefully adjust to the user’s device capabilities and network speed.

These features are still experimental and are subject to change. They are not yet a part of a stable React release, but you can try them in an experimental build.

## [](#blocking-vs-interruptible-rendering)Blocking vs Interruptible Rendering

**To explain Concurrent Mode, we’ll use version control as a metaphor.** If you work on a team, you probably use a version control system like Git and work on branches. When a branch is ready, you can merge your work into main so that other people can pull it.

Before version control existed, the development workflow was very different. There was no concept of branches. If you wanted to edit some files, you had to tell everyone not to touch those files until you’ve finished your work. You couldn’t even start working on them concurrently with that person — you were literally *blocked* by them.

This illustrates how UI libraries, including React, typically work today. Once they start rendering an update, including creating new DOM nodes and running the code inside components, they can’t interrupt this work. We’ll call this approach “blocking rendering”.

In Concurrent Mode, rendering is not blocking. It is interruptible. This improves the user experience. It also unlocks new features that weren’t possible before. Before we look at concrete examples in the [next](/docs/concurrent-mode-suspense.html) [chapters](/docs/concurrent-mode-patterns.html), we’ll do a high-level overview of new features.

### [](#interruptible-rendering)Interruptible Rendering

Consider a filterable product list. Have you ever typed into a list filter and felt that it stutters on every key press? Some of the work to update the product list might be unavoidable, such as creating new DOM nodes or the browser performing layout. However, *when* and *how* we perform that work plays a big role.

A common way to work around the stutter is to “debounce” the input. When debouncing, we only update the list *after* the user stops typing. However, it can be frustrating that the UI doesn’t update while we’re typing. As an alternative, we could “throttle” the input, and update the list with a certain maximum frequency. But then on lower-powered devices we’d still end up with stutter. Both debouncing and throttling create a suboptimal user experience.

The reason for the stutter is simple: once rendering begins, it can’t be interrupted. So the browser can’t update the text input right after the key press. No matter how good a UI library (such as React) might look on a benchmark, if it uses blocking rendering, a certain amount of work in your components will always cause stutter. And, often, there is no easy fix.

**Concurrent Mode fixes this fundamental limitation by making rendering interruptible.** This means when the user presses another key, React doesn’t need to block the browser from updating the text input. Instead, it can let the browser paint an update to the input, and then continue rendering the updated list *in memory*. When the rendering is finished, React updates the DOM, and changes are reflected on the screen.

Conceptually, you can think of this as React preparing every update “on a branch”. Just like you can abandon work in branches or switch between them, React in Concurrent Mode can interrupt an ongoing update to do something more important, and then come back to what it was doing earlier. This technique might also remind you of [double buffering](https://wiki.osdev.org/Double_Buffering) in video games.

Concurrent Mode techniques reduce the need for debouncing and throttling in UI. Because rendering is interruptible, React doesn’t need to artificially *delay* work to avoid stutter. It can start rendering right away, but interrupt this work when needed to keep the app responsive.

### [](#intentional-loading-sequences)Intentional Loading Sequences

We’ve said before that Concurrent Mode is like React working “on a branch”. Branches are useful not only for short-term fixes, but also for long-running features. Sometimes you might work on a feature, but it could take weeks before it’s in a “good enough state” to merge into main. This side of our version control metaphor applies to rendering too.

Imagine we’re navigating between two screens in an app. Sometimes, we might not have enough code and data loaded to show a “good enough” loading state to the user on the new screen. Transitioning to an empty screen or a large spinner can be a jarring experience. However, it’s also common that the necessary code and data doesn’t take too long to fetch. **Wouldn’t it be nicer if React could stay on the old screen for a little longer, and “skip” the “bad loading state” before showing the new screen?**

While this is possible today, it can be difficult to orchestrate. In Concurrent Mode, this feature is built-in. React starts preparing the new screen in memory first — or, as our metaphor goes, “on a different branch”. So React can wait before updating the DOM so that more content can load. In Concurrent Mode, we can tell React to keep showing the old screen, fully interactive, with an inline loading indicator. And when the new screen is ready, React can take us to it.

### [](#concurrency)Concurrency

Let’s recap the two examples above and see how Concurrent Mode unifies them. **In Concurrent Mode, React can work on several state updates *concurrently*** — just like branches let different team members work independently:

* For CPU-bound updates (such as creating DOM nodes and running component code), concurrency means that a more urgent update can “interrupt” rendering that has already started.
* For IO-bound updates (such as fetching code or data from the network), concurrency means that React can start rendering in memory even before all the data arrives, and skip showing jarring empty loading states.

Importantly, the way you *use* React is the same. Concepts like components, props, and state fundamentally work the same way. When you want to update the screen, you set the state.

React uses a heuristic to decide how “urgent” an update is, and lets you adjust it with a few lines of code so that you can achieve the desired user experience for every interaction.

## [](#putting-research-into-production)Putting Research into Production

There is a common theme around Concurrent Mode features. **Its mission is to help integrate the findings from the Human-Computer Interaction research into real UIs.**

For example, research shows that displaying too many intermediate loading states when transitioning between screens makes a transition feel *slower*. This is why Concurrent Mode shows new loading states on a fixed “schedule” to avoid jarring and too frequent updates.

Similarly, we know from research that interactions like hover and text input need to be handled within a very short period of time, while clicks and page transitions can wait a little longer without feeling laggy. The different “priorities” that Concurrent Mode uses internally roughly correspond to the interaction categories in the human perception research.

Teams with a strong focus on user experience sometimes solve similar problems with one-off solutions. However, those solutions rarely survive for a long time, as they’re hard to maintain. With Concurrent Mode, our goal is to bake the UI research findings into the abstraction itself, and provide idiomatic ways to use them. As a UI library, React is well-positioned to do that.

## [](#next-steps)Next Steps

Now you know what Concurrent Mode is all about!

On the next pages, you’ll learn more details about specific topics:

* [Suspense for Data Fetching](/docs/concurrent-mode-suspense.html) describes a new mechanism for fetching data in React components.
* [Concurrent UI Patterns](/docs/concurrent-mode-patterns.html) shows some UI patterns made possible by Concurrent Mode and Suspense.
* [Adopting Concurrent Mode](/docs/concurrent-mode-adoption.html) explains how you can try Concurrent Mode in your project.
* [Concurrent Mode API Reference](/docs/concurrent-mode-reference.html) documents the new APIs available in experimental builds.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/concurrent-mode-intro.md)

----
url: https://react.dev/reference/rules/rules-of-hooks
----

[API Reference](/reference/react)

[Overview](/reference/rules)

# Rules of Hooks[](#undefined "Link for this heading")

Hooks are defined using JavaScript functions, but they represent a special type of reusable UI logic with restrictions on where they can be called.

* [Only call Hooks at the top level](#only-call-hooks-at-the-top-level)
* [Only call Hooks from React functions](#only-call-hooks-from-react-functions)

***

## Only call Hooks at the top level[](#only-call-hooks-at-the-top-level "Link for Only call Hooks at the top level ")

Functions whose names start with `use` are called [*Hooks*](/reference/react) in React.

**Don’t call Hooks inside loops, conditions, nested functions, or `try`/`catch`/`finally` blocks.** Instead, always use Hooks at the top level of your React function, before any early returns. You can only call Hooks while React is rendering a function component:

* ✅ Call them at the top level in the body of a [function component](/learn/your-first-component).
* ✅ Call them at the top level in the body of a [custom Hook](/learn/reusing-logic-with-custom-hooks).

```
function Counter() {

  // ✅ Good: top-level in a function component

  const [count, setCount] = useState(0);

  // ...

}



function useWindowWidth() {

  // ✅ Good: top-level in a custom Hook

  const [width, setWidth] = useState(window.innerWidth);

  // ...

}
```

It’s **not** supported to call Hooks (functions starting with `use`) in any other cases, for example:

* 🔴 Do not call Hooks inside conditions or loops.
* 🔴 Do not call Hooks after a conditional `return` statement.
* 🔴 Do not call Hooks in event handlers.
* 🔴 Do not call Hooks in class components.
* 🔴 Do not call Hooks inside functions passed to `useMemo`, `useReducer`, or `useEffect`.
* 🔴 Do not call Hooks inside `try`/`catch`/`finally` blocks.

If you break these rules, you might see this error.

```
function Bad({ cond }) {

  if (cond) {

    // 🔴 Bad: inside a condition (to fix, move it outside!)

    const theme = useContext(ThemeContext);

  }

  // ...

}



function Bad() {

  for (let i = 0; i < 10; i++) {

    // 🔴 Bad: inside a loop (to fix, move it outside!)

    const theme = useContext(ThemeContext);

  }

  // ...

}



function Bad({ cond }) {

  if (cond) {

    return;

  }

  // 🔴 Bad: after a conditional return (to fix, move it before the return!)

  const theme = useContext(ThemeContext);

  // ...

}



function Bad() {

  function handleClick() {

    // 🔴 Bad: inside an event handler (to fix, move it outside!)

    const theme = useContext(ThemeContext);

  }

  // ...

}



function Bad() {

  const style = useMemo(() => {

    // 🔴 Bad: inside useMemo (to fix, move it outside!)

    const theme = useContext(ThemeContext);

    return createStyle(theme);

  });

  // ...

}



class Bad extends React.Component {

  render() {

    // 🔴 Bad: inside a class component (to fix, write a function component instead of a class!)

    useEffect(() => {})

    // ...

  }

}



function Bad() {

  try {

    // 🔴 Bad: inside try/catch/finally block (to fix, move it outside!)

    const [x, setX] = useState(0);

  } catch {

    const [x, setX] = useState(1);

  }

}
```

You can use the [`eslint-plugin-react-hooks` plugin](https://www.npmjs.com/package/eslint-plugin-react-hooks) to catch these mistakes.

### Note

[Custom Hooks](/learn/reusing-logic-with-custom-hooks) *may* call other Hooks (that’s their whole purpose). This works because custom Hooks are also supposed to only be called while a function component is rendering.

***

## Only call Hooks from React functions[](#only-call-hooks-from-react-functions "Link for Only call Hooks from React functions ")

Don’t call Hooks from regular JavaScript functions. Instead, you can:

✅ Call Hooks from React function components. ✅ Call Hooks from [custom Hooks](/learn/reusing-logic-with-custom-hooks#extracting-your-own-custom-hook-from-a-component).

By following this rule, you ensure that all stateful logic in a component is clearly visible from its source code.

```
function FriendList() {

  const [onlineStatus, setOnlineStatus] = useOnlineStatus(); // ✅

}



function setOnlineStatus() { // ❌ Not a component or custom Hook!

  const [onlineStatus, setOnlineStatus] = useOnlineStatus();

}
```

[PreviousReact calls Components and Hooks](/reference/rules/react-calls-components-and-hooks)

***

----
url: https://react.dev/learn/state-a-components-memory
----

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { sculptureList } from './data.js';

export default function Gallery() {
  let index = 0;

  function handleClick() {
    index = index + 1;
  }

  let sculpture = sculptureList[index];
  return (
    <>
      <button onClick={handleClick}>
        Next
      </button>
      <h2>
        <i>{sculpture.name} </i>
        by {sculpture.artist}
      </h2>
      <h3>
        ({index + 1} of {sculptureList.length})
      </h3>
      <img
        src={sculpture.url}
        alt={sculpture.alt}
      />
      <p>
        {sculpture.description}
      </p>
    </>
  );
}
```

```
import { useState } from 'react';
```

Then, replace this line:

```
let index = 0;
```

with

```
const [index, setIndex] = useState(0);
```

`index` is a state variable and `setIndex` is the setter function.

> The `[` and `]` syntax here is called [array destructuring](https://javascript.info/destructuring-assignment) and it lets you read values from an array. The array returned by `useState` always has exactly two items.

This is how they work together in `handleClick`:

```
function handleClick() {

  setIndex(index + 1);

}
```

Now clicking the “Next” button switches the current sculpture:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';
import { sculptureList } from './data.js';

export default function Gallery() {
  const [index, setIndex] = useState(0);

  function handleClick() {
    setIndex(index + 1);
  }

  let sculpture = sculptureList[index];
  return (
    <>
      <button onClick={handleClick}>
        Next
      </button>
      <h2>
        <i>{sculpture.name} </i>
        by {sculpture.artist}
      </h2>
      <h3>
        ({index + 1} of {sculptureList.length})
      </h3>
      <img
        src={sculpture.url}
        alt={sculpture.alt}
      />
      <p>
        {sculpture.description}
      </p>
    </>
  );
}
```

```
const [index, setIndex] = useState(0);
```

```
const [index, setIndex] = useState(0);
```

1. **Your component renders the first time.** Because you passed `0` to `useState` as the initial value for `index`, it will return `[0, setIndex]`. React remembers `0` is the latest state value.
2. **You update the state.** When a user clicks the button, it calls `setIndex(index + 1)`. `index` is `0`, so it’s `setIndex(1)`. This tells React to remember `index` is `1` now and triggers another render.
3. **Your component’s second render.** React still sees `useState(0)`, but because React *remembers* that you set `index` to `1`, it returns `[1, setIndex]` instead.
4. And so on!

## Giving a component multiple state variables[](#giving-a-component-multiple-state-variables "Link for Giving a component multiple state variables ")

You can have as many state variables of as many types as you like in one component. This component has two state variables, a number `index` and a boolean `showMore` that’s toggled when you click “Show details”:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';
import { sculptureList } from './data.js';

export default function Gallery() {
  const [index, setIndex] = useState(0);
  const [showMore, setShowMore] = useState(false);

  function handleNextClick() {
    setIndex(index + 1);
  }

  function handleMoreClick() {
    setShowMore(!showMore);
  }

  let sculpture = sculptureList[index];
  return (
    <>
      <button onClick={handleNextClick}>
        Next
      </button>
      <h2>
        <i>{sculpture.name} </i>
        by {sculpture.artist}
      </h2>
      <h3>
        ({index + 1} of {sculptureList.length})
      </h3>
      <button onClick={handleMoreClick}>
        {showMore ? 'Hide' : 'Show'} details
      </button>
      {showMore && <p>{sculpture.description}</p>}
      <img
        src={sculpture.url}
        alt={sculpture.alt}
      />
    </>
  );
}
```

It is a good idea to have multiple state variables if their state is unrelated, like `index` and `showMore` in this example. But if you find that you often change two state variables together, it might be easier to combine them into one. For example, if you have a form with many fields, it’s more convenient to have a single state variable that holds an object than state variable per field. Read [Choosing the State Structure](/learn/choosing-the-state-structure) for more tips.

##### Deep Dive#### How does React know which state to return?[](#how-does-react-know-which-state-to-return "Link for How does React know which state to return? ")

You might have noticed that the `useState` call does not receive any information about *which* state variable it refers to. There is no “identifier” that is passed to `useState`, so how does it know which of the state variables to return? Does it rely on some magic like parsing your functions? The answer is no.

Instead, to enable their concise syntax, Hooks **rely on a stable call order on every render of the same component.** This works well in practice because if you follow the rule above (“only call Hooks at the top level”), Hooks will always be called in the same order. Additionally, a [linter plugin](https://www.npmjs.com/package/eslint-plugin-react-hooks) catches most mistakes.

Internally, React holds an array of state pairs for every component. It also maintains the current pair index, which is set to `0` before rendering. Each time you call `useState`, React gives you the next state pair and increments the index. You can read more about this mechanism in [React Hooks: Not Magic, Just Arrays.](https://medium.com/@ryardley/react-hooks-not-magic-just-arrays-cd4f1857236e)

This example **doesn’t use React** but it gives you an idea of how `useState` works internally:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
let componentHooks = [];
let currentHookIndex = 0;

// How useState works inside React (simplified).
function useState(initialState) {
  let pair = componentHooks[currentHookIndex];
  if (pair) {
    // This is not the first render,
    // so the state pair already exists.
    // Return it and prepare for next Hook call.
    currentHookIndex++;
    return pair;
  }

  // This is the first time we're rendering,
  // so create a state pair and store it.
  pair = [initialState, setState];

  function setState(nextState) {
    // When the user requests a state change,
    // put the new value into the pair.
    pair[0] = nextState;
    updateDOM();
  }

  // Store the pair for future renders
  // and prepare for the next Hook call.
  componentHooks[currentHookIndex] = pair;
  currentHookIndex++;
  return pair;
}

function Gallery() {
  // Each useState() call will get the next pair.
  const [index, setIndex] = useState(0);
  const [showMore, setShowMore] = useState(false);

  function handleNextClick() {
    setIndex(index + 1);
  }

  function handleMoreClick() {
    setShowMore(!showMore);
  }

  let sculpture = sculptureList[index];
  // This example doesn't use React, so
  // return an output object instead of JSX.
  return {
    onNextClick: handleNextClick,
    onMoreClick: handleMoreClick,
    header: `${sculpture.name} by ${sculpture.artist}`,
    counter: `${index + 1} of ${sculptureList.length}`,
    more: `${showMore ? 'Hide' : 'Show'} details`,
    description: showMore ? sculpture.description : null,
    imageSrc: sculpture.url,
    imageAlt: sculpture.alt
  };
}

function updateDOM() {
  // Reset the current Hook index
  // before rendering the component.
  currentHookIndex = 0;
  let output = Gallery();

  // Update the DOM to match the output.
  // This is the part React does for you.
  nextButton.onclick = output.onNextClick;
  header.textContent = output.header;
  moreButton.onclick = output.onMoreClick;
  moreButton.textContent = output.more;
  image.src = output.imageSrc;
  image.alt = output.imageAlt;
  if (output.description !== null) {
    description.textContent = output.description;
    description.style.display = '';
  } else {
    description.style.display = 'none';
  }
}

let nextButton = document.getElementById('nextButton');
let header = document.getElementById('header');
let moreButton = document.getElementById('moreButton');
let description = document.getElementById('description');
let image = document.getElementById('image');
let sculptureList = [{
  name: 'Homenaje a la Neurocirugía',
  artist: 'Marta Colvin Andrade',
  description: 'Although Colvin is predominantly known for abstract themes that allude to pre-Hispanic symbols, this gigantic sculpture, an homage to neurosurgery, is one of her most recognizable public art pieces.',
  url: 'https://react.dev/images/docs/scientists/Mx7dA2Y.jpg',
  alt: 'A bronze statue of two crossed hands delicately holding a human brain in their fingertips.'
}, {
  name: 'Floralis Genérica',
  artist: 'Eduardo Catalano',
  description: 'This enormous (75 ft. or 23m) silver flower is located in Buenos Aires. It is designed to move, closing its petals in the evening or when strong winds blow and opening them in the morning.',
  url: 'https://react.dev/images/docs/scientists/ZF6s192m.jpg',
  alt: 'A gigantic metallic flower sculpture with reflective mirror-like petals and strong stamens.'
}, {
  name: 'Eternal Presence',
  artist: 'John Woodrow Wilson',
  description: 'Wilson was known for his preoccupation with equality, social justice, as well as the essential and spiritual qualities of humankind. This massive (7ft. or 2,13m) bronze represents what he described as "a symbolic Black presence infused with a sense of universal humanity."',
  url: 'https://react.dev/images/docs/scientists/aTtVpES.jpg',
  alt: 'The sculpture depicting a human head seems ever-present and solemn. It radiates calm and serenity.'
}, {
  name: 'Moai',
  artist: 'Unknown Artist',
  description: 'Located on the Easter Island, there are 1,000 moai, or extant monumental statues, created by the early Rapa Nui people, which some believe represented deified ancestors.',
  url: 'https://react.dev/images/docs/scientists/RCwLEoQm.jpg',
  alt: 'Three monumental stone busts with the heads that are disproportionately large with somber faces.'
}, {
  name: 'Blue Nana',
  artist: 'Niki de Saint Phalle',
  description: 'The Nanas are triumphant creatures, symbols of femininity and maternity. Initially, Saint Phalle used fabric and found objects for the Nanas, and later on introduced polyester to achieve a more vibrant effect.',
  url: 'https://react.dev/images/docs/scientists/Sd1AgUOm.jpg',
  alt: 'A large mosaic sculpture of a whimsical dancing female figure in a colorful costume emanating joy.'
}, {
  name: 'Ultimate Form',
  artist: 'Barbara Hepworth',
  description: 'This abstract bronze sculpture is a part of The Family of Man series located at Yorkshire Sculpture Park. Hepworth chose not to create literal representations of the world but developed abstract forms inspired by people and landscapes.',
  url: 'https://react.dev/images/docs/scientists/2heNQDcm.jpg',
  alt: 'A tall sculpture made of three elements stacked on each other reminding of a human figure.'
}, {
  name: 'Cavaliere',
  artist: 'Lamidi Olonade Fakeye',
  description: "Descended from four generations of woodcarvers, Fakeye's work blended traditional and contemporary Yoruba themes.",
  url: 'https://react.dev/images/docs/scientists/wIdGuZwm.png',
  alt: 'An intricate wood sculpture of a warrior with a focused face on a horse adorned with patterns.'
}, {
  name: 'Big Bellies',
  artist: 'Alina Szapocznikow',
  description: "Szapocznikow is known for her sculptures of the fragmented body as a metaphor for the fragility and impermanence of youth and beauty. This sculpture depicts two very realistic large bellies stacked on top of each other, each around five feet (1,5m) tall.",
  url: 'https://react.dev/images/docs/scientists/AlHTAdDm.jpg',
  alt: 'The sculpture reminds a cascade of folds, quite different from bellies in classical sculptures.'
}, {
  name: 'Terracotta Army',
  artist: 'Unknown Artist',
  description: 'The Terracotta Army is a collection of terracotta sculptures depicting the armies of Qin Shi Huang, the first Emperor of China. The army consisted of more than 8,000 soldiers, 130 chariots with 520 horses, and 150 cavalry horses.',
  url: 'https://react.dev/images/docs/scientists/HMFmH6m.jpg',
  alt: '12 terracotta sculptures of solemn warriors, each with a unique facial expression and armor.'
}, {
  name: 'Lunar Landscape',
  artist: 'Louise Nevelson',
  description: 'Nevelson was known for scavenging objects from New York City debris, which she would later assemble into monumental constructions. In this one, she used disparate parts like a bedpost, juggling pin, and seat fragment, nailing and gluing them into boxes that reflect the influence of Cubism’s geometric abstraction of space and form.',
  url: 'https://react.dev/images/docs/scientists/rN7hY6om.jpg',
  alt: 'A black matte sculpture where the individual elements are initially indistinguishable.'
}, {
  name: 'Aureole',
  artist: 'Ranjani Shettar',
  description: 'Shettar merges the traditional and the modern, the natural and the industrial. Her art focuses on the relationship between man and nature. Her work was described as compelling both abstractly and figuratively, gravity defying, and a "fine synthesis of unlikely materials."',
  url: 'https://react.dev/images/docs/scientists/okTpbHhm.jpg',
  alt: 'A pale wire-like sculpture mounted on concrete wall and descending on the floor. It appears light.'
}, {
  name: 'Hippos',
  artist: 'Taipei Zoo',
  description: 'The Taipei Zoo commissioned a Hippo Square featuring submerged hippos at play.',
  url: 'https://react.dev/images/docs/scientists/6o5Vuyu.jpg',
  alt: 'A group of bronze hippo sculptures emerging from the sett sidewalk as if they were swimming.'
}];

// Make UI match the initial state.
updateDOM();
```

You don’t have to understand it to use React, but you might find this a helpful mental model.

## State is isolated and private[](#state-is-isolated-and-private "Link for State is isolated and private ")

State is local to a component instance on the screen. In other words, **if you render the same component twice, each copy will have completely isolated state!** Changing one of them will not affect the other.

In this example, the `Gallery` component from earlier is rendered twice with no changes to its logic. Try clicking the buttons inside each of the galleries. Notice that their state is independent:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import Gallery from './Gallery.js';

export default function Page() {
  return (
    <div className="Page">
      <Gallery />
      <Gallery />
    </div>
  );
}
```

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';
import { sculptureList } from './data.js';

export default function Gallery() {
  const [index, setIndex] = useState(0);
  const [showMore, setShowMore] = useState(false);

  function handleNextClick() {
    setIndex(index + 1);
  }

  function handleMoreClick() {
    setShowMore(!showMore);
  }

  let sculpture = sculptureList[index];
  return (
    <>
      <button onClick={handleNextClick}>
        Next
      </button>
      <h2>
        <i>{sculpture.name} </i>
        by {sculpture.artist}
      </h2>
      <h3>
        ({index + 1} of {sculptureList.length})
      </h3>
      <button onClick={handleMoreClick}>
        {showMore ? 'Hide' : 'Show'} details
      </button>
      {showMore && <p>{sculpture.description}</p>}
      <img
        src={sculpture.url}
        alt={sculpture.alt}
      />
    </>
  );
}
```

[PreviousResponding to Events](/learn/responding-to-events)

[NextRender and Commit](/learn/render-and-commit)

***

----
url: https://18.react.dev/reference/react/useMemo
----

[API Reference](/reference/react)

[Hooks](/reference/react/hooks)

# useMemo[](#undefined "Link for this heading")

`useMemo` is a React Hook that lets you cache the result of a calculation between re-renders.

```
const cachedValue = useMemo(calculateValue, dependencies)
```

***

## Reference[](#reference "Link for Reference ")

### `useMemo(calculateValue, dependencies)`[](#usememo "Link for this heading")

Call `useMemo` at the top level of your component to cache a calculation between re-renders:

```
import { useMemo } from 'react';



function TodoList({ todos, tab }) {

  const visibleTodos = useMemo(

    () => filterTodos(todos, tab),

    [todos, tab]

  );

  // ...

}
```

***

## Usage[](#usage "Link for Usage ")

### Skipping expensive recalculations[](#skipping-expensive-recalculations "Link for Skipping expensive recalculations ")

To cache a calculation between re-renders, wrap it in a `useMemo` call at the top level of your component:

```
import { useMemo } from 'react';



function TodoList({ todos, tab, theme }) {

  const visibleTodos = useMemo(() => filterTodos(todos, tab), [todos, tab]);

  // ...

}
```

```
function TodoList({ todos, tab, theme }) {

  const visibleTodos = filterTodos(todos, tab);

  // ...

}
```

Usually, this isn’t a problem because most calculations are very fast. However, if you’re filtering or transforming a large array, or doing some expensive computation, you might want to skip doing it again if data hasn’t changed. If both `todos` and `tab` are the same as they were during the last render, wrapping the calculation in `useMemo` like earlier lets you reuse `visibleTodos` you’ve already calculated before.

This type of caching is called *[memoization.](https://en.wikipedia.org/wiki/Memoization)*

### Note

**You should only rely on `useMemo` as a performance optimization.** If your code doesn’t work without it, find the underlying problem and fix it first. Then you may add `useMemo` to improve performance.

##### Deep Dive#### How to tell if a calculation is expensive?[](#how-to-tell-if-a-calculation-is-expensive "Link for How to tell if a calculation is expensive? ")

In general, unless you’re creating or looping over thousands of objects, it’s probably not expensive. If you want to get more confidence, you can add a console log to measure the time spent in a piece of code:

```
console.time('filter array');

const visibleTodos = filterTodos(todos, tab);

console.timeEnd('filter array');
```

Perform the interaction you’re measuring (for example, typing into the input). You will then see logs like `filter array: 0.15ms` in your console. If the overall logged time adds up to a significant amount (say, `1ms` or more), it might make sense to memoize that calculation. As an experiment, you can then wrap the calculation in `useMemo` to verify whether the total logged time has decreased for that interaction or not:

```
console.time('filter array');

const visibleTodos = useMemo(() => {

  return filterTodos(todos, tab); // Skipped if todos and tab haven't changed

}, [todos, tab]);

console.timeEnd('filter array');
```

```
import { useMemo } from 'react';
import { filterTodos } from './utils.js'

export default function TodoList({ todos, theme, tab }) {
  const visibleTodos = useMemo(
    () => filterTodos(todos, tab),
    [todos, tab]
  );
  return (
    <div className={theme}>
      <p><b>Note: <code>filterTodos</code> is artificially slowed down!</b></p>
      <ul>
        {visibleTodos.map(todo => (
          <li key={todo.id}>
            {todo.completed ?
              <s>{todo.text}</s> :
              todo.text
            }
          </li>
        ))}
      </ul>
    </div>
  );
}
```

***

### Skipping re-rendering of components[](#skipping-re-rendering-of-components "Link for Skipping re-rendering of components ")

In some cases, `useMemo` can also help you optimize performance of re-rendering child components. To illustrate this, let’s say this `TodoList` component passes the `visibleTodos` as a prop to the child `List` component:

```
export default function TodoList({ todos, tab, theme }) {

  // ...

  return (

    <div className={theme}>

      <List items={visibleTodos} />

    </div>

  );

}
```

You’ve noticed that toggling the `theme` prop freezes the app for a moment, but if you remove `<List />` from your JSX, it feels fast. This tells you that it’s worth trying to optimize the `List` component.

**By default, when a component re-renders, React re-renders all of its children recursively.** This is why, when `TodoList` re-renders with a different `theme`, the `List` component *also* re-renders. This is fine for components that don’t require much calculation to re-render. But if you’ve verified that a re-render is slow, you can tell `List` to skip re-rendering when its props are the same as on last render by wrapping it in [`memo`:](/reference/react/memo)

```
import { memo } from 'react';



const List = memo(function List({ items }) {

  // ...

});
```

**With this change, `List` will skip re-rendering if all of its props are the *same* as on the last render.** This is where caching the calculation becomes important! Imagine that you calculated `visibleTodos` without `useMemo`:

```
export default function TodoList({ todos, tab, theme }) {

  // Every time the theme changes, this will be a different array...

  const visibleTodos = filterTodos(todos, tab);

  return (

    <div className={theme}>

      {/* ... so List's props will never be the same, and it will re-render every time */}

      <List items={visibleTodos} />

    </div>

  );

}
```

**In the above example, the `filterTodos` function always creates a *different* array,** similar to how the `{}` object literal always creates a new object. Normally, this wouldn’t be a problem, but it means that `List` props will never be the same, and your [`memo`](/reference/react/memo) optimization won’t work. This is where `useMemo` comes in handy:

```
export default function TodoList({ todos, tab, theme }) {

  // Tell React to cache your calculation between re-renders...

  const visibleTodos = useMemo(

    () => filterTodos(todos, tab),

    [todos, tab] // ...so as long as these dependencies don't change...

  );

  return (

    <div className={theme}>

      {/* ...List will receive the same props and can skip re-rendering */}

      <List items={visibleTodos} />

    </div>

  );

}
```

**By wrapping the `visibleTodos` calculation in `useMemo`, you ensure that it has the *same* value between the re-renders** (until dependencies change). You don’t *have to* wrap a calculation in `useMemo` unless you do it for some specific reason. In this example, the reason is that you pass it to a component wrapped in [`memo`,](/reference/react/memo) and this lets it skip re-rendering. There are a few other reasons to add `useMemo` which are described further on this page.

##### Deep Dive#### Memoizing individual JSX nodes[](#memoizing-individual-jsx-nodes "Link for Memoizing individual JSX nodes ")

Instead of wrapping `List` in [`memo`](/reference/react/memo), you could wrap the `<List />` JSX node itself in `useMemo`:

```
export default function TodoList({ todos, tab, theme }) {

  const visibleTodos = useMemo(() => filterTodos(todos, tab), [todos, tab]);

  const children = useMemo(() => <List items={visibleTodos} />, [visibleTodos]);

  return (

    <div className={theme}>

      {children}

    </div>

  );

}
```

```
import { useMemo } from 'react';
import List from './List.js';
import { filterTodos } from './utils.js'

export default function TodoList({ todos, theme, tab }) {
  const visibleTodos = useMemo(
    () => filterTodos(todos, tab),
    [todos, tab]
  );
  return (
    <div className={theme}>
      <p><b>Note: <code>List</code> is artificially slowed down!</b></p>
      <List items={visibleTodos} />
    </div>
  );
}
```

***

### Preventing an Effect from firing too often[](#preventing-an-effect-from-firing-too-often "Link for Preventing an Effect from firing too often ")

Sometimes, you might want to use a value inside an [Effect:](/learn/synchronizing-with-effects)

```
function ChatRoom({ roomId }) {

  const [message, setMessage] = useState('');



  const options = {

    serverUrl: 'https://localhost:1234',

    roomId: roomId

  }



  useEffect(() => {

    const connection = createConnection(options);

    connection.connect();

    // ...
```

This creates a problem. [Every reactive value must be declared as a dependency of your Effect.](/learn/lifecycle-of-reactive-effects#react-verifies-that-you-specified-every-reactive-value-as-a-dependency) However, if you declare `options` as a dependency, it will cause your Effect to constantly reconnect to the chat room:

```
  useEffect(() => {

    const connection = createConnection(options);

    connection.connect();

    return () => connection.disconnect();

  }, [options]); // 🔴 Problem: This dependency changes on every render

  // ...
```

To solve this, you can wrap the object you need to call from an Effect in `useMemo`:

```
function ChatRoom({ roomId }) {

  const [message, setMessage] = useState('');



  const options = useMemo(() => {

    return {

      serverUrl: 'https://localhost:1234',

      roomId: roomId

    };

  }, [roomId]); // ✅ Only changes when roomId changes



  useEffect(() => {

    const options = createOptions();

    const connection = createConnection(options);

    connection.connect();

    return () => connection.disconnect();

  }, [options]); // ✅ Only changes when createOptions changes

  // ...
```

This ensures that the `options` object is the same between re-renders if `useMemo` returns the cached object.

However, since `useMemo` is performance optimization, not a semantic guarantee, React may throw away the cached value if [there is a specific reason to do that](#caveats). This will also cause the effect to re-fire, **so it’s even better to remove the need for a function dependency** by moving your object *inside* the Effect:

```
function ChatRoom({ roomId }) {

  const [message, setMessage] = useState('');



  useEffect(() => {

    const options = { // ✅ No need for useMemo or object dependencies!

      serverUrl: 'https://localhost:1234',

      roomId: roomId

    }

    

    const connection = createConnection(options);

    connection.connect();

    return () => connection.disconnect();

  }, [roomId]); // ✅ Only changes when roomId changes

  // ...
```

Now your code is simpler and doesn’t need `useMemo`. [Learn more about removing Effect dependencies.](/learn/removing-effect-dependencies#move-dynamic-objects-and-functions-inside-your-effect)

### Memoizing a dependency of another Hook[](#memoizing-a-dependency-of-another-hook "Link for Memoizing a dependency of another Hook ")

Suppose you have a calculation that depends on an object created directly in the component body:

```
function Dropdown({ allItems, text }) {

  const searchOptions = { matchMode: 'whole-word', text };



  const visibleItems = useMemo(() => {

    return searchItems(allItems, searchOptions);

  }, [allItems, searchOptions]); // 🚩 Caution: Dependency on an object created in the component body

  // ...
```

Depending on an object like this defeats the point of memoization. When a component re-renders, all of the code directly inside the component body runs again. **The lines of code creating the `searchOptions` object will also run on every re-render.** Since `searchOptions` is a dependency of your `useMemo` call, and it’s different every time, React knows the dependencies are different, and recalculate `searchItems` every time.

To fix this, you could memoize the `searchOptions` object *itself* before passing it as a dependency:

```
function Dropdown({ allItems, text }) {

  const searchOptions = useMemo(() => {

    return { matchMode: 'whole-word', text };

  }, [text]); // ✅ Only changes when text changes



  const visibleItems = useMemo(() => {

    return searchItems(allItems, searchOptions);

  }, [allItems, searchOptions]); // ✅ Only changes when allItems or searchOptions changes

  // ...
```

In the example above, if the `text` did not change, the `searchOptions` object also won’t change. However, an even better fix is to move the `searchOptions` object declaration *inside* of the `useMemo` calculation function:

```
function Dropdown({ allItems, text }) {

  const visibleItems = useMemo(() => {

    const searchOptions = { matchMode: 'whole-word', text };

    return searchItems(allItems, searchOptions);

  }, [allItems, text]); // ✅ Only changes when allItems or text changes

  // ...
```

Now your calculation depends on `text` directly (which is a string and can’t “accidentally” become different).

***

### Memoizing a function[](#memoizing-a-function "Link for Memoizing a function ")

Suppose the `Form` component is wrapped in [`memo`.](/reference/react/memo) You want to pass a function to it as a prop:

```
export default function ProductPage({ productId, referrer }) {

  function handleSubmit(orderDetails) {

    post('/product/' + productId + '/buy', {

      referrer,

      orderDetails

    });

  }



  return <Form onSubmit={handleSubmit} />;

}
```

Just as `{}` creates a different object, function declarations like `function() {}` and expressions like `() => {}` produce a *different* function on every re-render. By itself, creating a new function is not a problem. This is not something to avoid! However, if the `Form` component is memoized, presumably you want to skip re-rendering it when no props have changed. A prop that is *always* different would defeat the point of memoization.

To memoize a function with `useMemo`, your calculation function would have to return another function:

```
export default function Page({ productId, referrer }) {

  const handleSubmit = useMemo(() => {

    return (orderDetails) => {

      post('/product/' + productId + '/buy', {

        referrer,

        orderDetails

      });

    };

  }, [productId, referrer]);



  return <Form onSubmit={handleSubmit} />;

}
```

This looks clunky! **Memoizing functions is common enough that React has a built-in Hook specifically for that. Wrap your functions into [`useCallback`](/reference/react/useCallback) instead of `useMemo`** to avoid having to write an extra nested function:

```
export default function Page({ productId, referrer }) {

  const handleSubmit = useCallback((orderDetails) => {

    post('/product/' + productId + '/buy', {

      referrer,

      orderDetails

    });

  }, [productId, referrer]);



  return <Form onSubmit={handleSubmit} />;

}
```

The two examples above are completely equivalent. The only benefit to `useCallback` is that it lets you avoid writing an extra nested function inside. It doesn’t do anything else. [Read more about `useCallback`.](/reference/react/useCallback)

***

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### My calculation runs twice on every re-render[](#my-calculation-runs-twice-on-every-re-render "Link for My calculation runs twice on every re-render ")

In [Strict Mode](/reference/react/StrictMode), React will call some of your functions twice instead of once:

```
function TodoList({ todos, tab }) {

  // This component function will run twice for every render.



  const visibleTodos = useMemo(() => {

    // This calculation will run twice if any of the dependencies change.

    return filterTodos(todos, tab);

  }, [todos, tab]);



  // ...
```

This is expected and shouldn’t break your code.

This **development-only** behavior helps you [keep components pure.](/learn/keeping-components-pure) React uses the result of one of the calls, and ignores the result of the other call. As long as your component and calculation functions are pure, this shouldn’t affect your logic. However, if they are accidentally impure, this helps you notice and fix the mistake.

For example, this impure calculation function mutates an array you received as a prop:

```
  const visibleTodos = useMemo(() => {

    // 🚩 Mistake: mutating a prop

    todos.push({ id: 'last', text: 'Go for a walk!' });

    const filtered = filterTodos(todos, tab);

    return filtered;

  }, [todos, tab]);
```

React calls your function twice, so you’d notice the todo is added twice. Your calculation shouldn’t change any existing objects, but it’s okay to change any *new* objects you created during the calculation. For example, if the `filterTodos` function always returns a *different* array, you can mutate *that* array instead:

```
  const visibleTodos = useMemo(() => {

    const filtered = filterTodos(todos, tab);

    // ✅ Correct: mutating an object you created during the calculation

    filtered.push({ id: 'last', text: 'Go for a walk!' });

    return filtered;

  }, [todos, tab]);
```

Read [keeping components pure](/learn/keeping-components-pure) to learn more about purity.

Also, check out the guides on [updating objects](/learn/updating-objects-in-state) and [updating arrays](/learn/updating-arrays-in-state) without mutation.

***

### My `useMemo` call is supposed to return an object, but returns undefined[](#my-usememo-call-is-supposed-to-return-an-object-but-returns-undefined "Link for this heading")

This code doesn’t work:

```
  // 🔴 You can't return an object from an arrow function with () => {

  const searchOptions = useMemo(() => {

    matchMode: 'whole-word',

    text: text

  }, [text]);
```

In JavaScript, `() => {` starts the arrow function body, so the `{` brace is not a part of your object. This is why it doesn’t return an object, and leads to mistakes. You could fix it by adding parentheses like `({` and `})`:

```
  // This works, but is easy for someone to break again

  const searchOptions = useMemo(() => ({

    matchMode: 'whole-word',

    text: text

  }), [text]);
```

However, this is still confusing and too easy for someone to break by removing the parentheses.

To avoid this mistake, write a `return` statement explicitly:

```
  // ✅ This works and is explicit

  const searchOptions = useMemo(() => {

    return {

      matchMode: 'whole-word',

      text: text

    };

  }, [text]);
```

***

### Every time my component renders, the calculation in `useMemo` re-runs[](#every-time-my-component-renders-the-calculation-in-usememo-re-runs "Link for this heading")

Make sure you’ve specified the dependency array as a second argument!

If you forget the dependency array, `useMemo` will re-run the calculation every time:

```
function TodoList({ todos, tab }) {

  // 🔴 Recalculates every time: no dependency array

  const visibleTodos = useMemo(() => filterTodos(todos, tab));

  // ...
```

This is the corrected version passing the dependency array as a second argument:

```
function TodoList({ todos, tab }) {

  // ✅ Does not recalculate unnecessarily

  const visibleTodos = useMemo(() => filterTodos(todos, tab), [todos, tab]);

  // ...
```

If this doesn’t help, then the problem is that at least one of your dependencies is different from the previous render. You can debug this problem by manually logging your dependencies to the console:

```
  const visibleTodos = useMemo(() => filterTodos(todos, tab), [todos, tab]);

  console.log([todos, tab]);
```

You can then right-click on the arrays from different re-renders in the console and select “Store as a global variable” for both of them. Assuming the first one got saved as `temp1` and the second one got saved as `temp2`, you can then use the browser console to check whether each dependency in both arrays is the same:

```
Object.is(temp1[0], temp2[0]); // Is the first dependency the same between the arrays?

Object.is(temp1[1], temp2[1]); // Is the second dependency the same between the arrays?

Object.is(temp1[2], temp2[2]); // ... and so on for every dependency ...
```

When you find which dependency breaks memoization, either find a way to remove it, or [memoize it as well.](#memoizing-a-dependency-of-another-hook)

***

### I need to call `useMemo` for each list item in a loop, but it’s not allowed[](#i-need-to-call-usememo-for-each-list-item-in-a-loop-but-its-not-allowed "Link for this heading")

Suppose the `Chart` component is wrapped in [`memo`](/reference/react/memo). You want to skip re-rendering every `Chart` in the list when the `ReportList` component re-renders. However, you can’t call `useMemo` in a loop:

```
function ReportList({ items }) {

  return (

    <article>

      {items.map(item => {

        // 🔴 You can't call useMemo in a loop like this:

        const data = useMemo(() => calculateReport(item), [item]);

        return (

          <figure key={item.id}>

            <Chart data={data} />

          </figure>

        );

      })}

    </article>

  );

}
```

Instead, extract a component for each item and memoize data for individual items:

```
function ReportList({ items }) {

  return (

    <article>

      {items.map(item =>

        <Report key={item.id} item={item} />

      )}

    </article>

  );

}



function Report({ item }) {

  // ✅ Call useMemo at the top level:

  const data = useMemo(() => calculateReport(item), [item]);

  return (

    <figure>

      <Chart data={data} />

    </figure>

  );

}
```

Alternatively, you could remove `useMemo` and instead wrap `Report` itself in [`memo`.](/reference/react/memo) If the `item` prop does not change, `Report` will skip re-rendering, so `Chart` will skip re-rendering too:

```
function ReportList({ items }) {

  // ...

}



const Report = memo(function Report({ item }) {

  const data = calculateReport(item);

  return (

    <figure>

      <Chart data={data} />

    </figure>

  );

});
```

[PrevioususeLayoutEffect](/reference/react/useLayoutEffect)

[NextuseOptimistic](/reference/react/useOptimistic)

***

----
url: https://18.react.dev/learn/keeping-components-pure
----

```
function double(number) {

  return 2 * number;

}
```

In the above example, `double` is a **pure function.** If you pass it `3`, it will return `6`. Always.

React is designed around this concept. **React assumes that every component you write is a pure function.** This means that React components you write must always return the same JSX given the same inputs:

```
function Recipe({ drinkers }) {
  return (
    <ol>    
      <li>Boil {drinkers} cups of water.</li>
      <li>Add {drinkers} spoons of tea and {0.5 * drinkers} spoons of spice.</li>
      <li>Add {0.5 * drinkers} cups of milk to boil and sugar to taste.</li>
    </ol>
  );
}

export default function App() {
  return (
    <section>
      <h1>Spiced Chai Recipe</h1>
      <h2>For two</h2>
      <Recipe drinkers={2} />
      <h2>For a gathering</h2>
      <Recipe drinkers={4} />
    </section>
  );
}
```

```
let guest = 0;

function Cup() {
  // Bad: changing a preexisting variable!
  guest = guest + 1;
  return <h2>Tea cup for guest #{guest}</h2>;
}

export default function TeaSet() {
  return (
    <>
      <Cup />
      <Cup />
      <Cup />
    </>
  );
}
```

This component is reading and writing a `guest` variable declared outside of it. This means that **calling this component multiple times will produce different JSX!** And what’s more, if *other* components read `guest`, they will produce different JSX, too, depending on when they were rendered! That’s not predictable.

Going back to our formula y = 2x, now even if x = 2, we cannot trust that y = 4. Our tests could fail, our users would be baffled, planes would fall out of the sky—you can see how this would lead to confusing bugs!

You can fix this component by [passing `guest` as a prop instead](/learn/passing-props-to-a-component):

```
function Cup({ guest }) {
  return <h2>Tea cup for guest #{guest}</h2>;
}

export default function TeaSet() {
  return (
    <>
      <Cup guest={1} />
      <Cup guest={2} />
      <Cup guest={3} />
    </>
  );
}
```

```
function Cup({ guest }) {
  return <h2>Tea cup for guest #{guest}</h2>;
}

export default function TeaGathering() {
  let cups = [];
  for (let i = 1; i <= 12; i++) {
    cups.push(<Cup key={i} guest={i} />);
  }
  return cups;
}
```

```
export default function Clock({ time }) {
  let hours = time.getHours();
  if (hours >= 0 && hours <= 6) {
    document.getElementById('time').className = 'night';
  } else {
    document.getElementById('time').className = 'day';
  }
  return (
    <h1 id="time">
      {time.toLocaleTimeString()}
    </h1>
  );
}
```

[PreviousRendering Lists](/learn/rendering-lists)

[NextYour UI as a Tree](/learn/understanding-your-ui-as-a-tree)

***

----
url: https://18.react.dev/learn/start-a-new-react-project
----

[Learn React](/learn)

[Installation](/learn/installation)

# Start a New React Project[](#undefined "Link for this heading")

If you want to build a new app or a new website fully with React, we recommend picking one of the React-powered frameworks popular in the community.

You can use React without a framework, however we’ve found that most apps and sites eventually build solutions to common problems such as code-splitting, routing, data fetching, and generating HTML. These problems are common to all UI libraries, not just React.

By starting with a framework, you can get started with React quickly, and avoid essentially building your own framework later.

##### Deep Dive#### Can I use React without a framework?[](#can-i-use-react-without-a-framework "Link for Can I use React without a framework? ")

You can definitely use React without a framework—that’s how you’d [use React for a part of your page.](/learn/add-react-to-an-existing-project#using-react-for-a-part-of-your-existing-page) **However, if you’re building a new app or a site fully with React, we recommend using a framework.**

Here’s why.

Even if you don’t need routing or data fetching at first, you’ll likely want to add some libraries for them. As your JavaScript bundle grows with every new feature, you might have to figure out how to split code for every route individually. As your data fetching needs get more complex, you are likely to encounter server-client network waterfalls that make your app feel very slow. As your audience includes more users with poor network conditions and low-end devices, you might need to generate HTML from your components to display content early—either on the server, or during the build time. Changing your setup to run some of your code on the server or during the build can be very tricky.

**These problems are not React-specific. This is why Svelte has SvelteKit, Vue has Nuxt, and so on.** To solve these problems on your own, you’ll need to integrate your bundler with your router and with your data fetching library. It’s not hard to get an initial setup working, but there are a lot of subtleties involved in making an app that loads quickly even as it grows over time. You’ll want to send down the minimal amount of app code but do so in a single client–server roundtrip, in parallel with any data required for the page. You’ll likely want the page to be interactive before your JavaScript code even runs, to support progressive enhancement. You may want to generate a folder of fully static HTML files for your marketing pages that can be hosted anywhere and still work with JavaScript disabled. Building these capabilities yourself takes real work.

**React frameworks on this page solve problems like these by default, with no extra work from your side.** They let you start very lean and then scale your app with your needs. Each React framework has a community, so finding answers to questions and upgrading tooling is easier. Frameworks also give structure to your code, helping you and others retain context and skills between different projects. Conversely, with a custom setup it’s easier to get stuck on unsupported dependency versions, and you’ll essentially end up creating your own framework—albeit one with no community or upgrade path (and if it’s anything like the ones we’ve made in the past, more haphazardly designed).

If your app has unusual constraints not served well by these frameworks, or you prefer to solve these problems yourself, you can roll your own custom setup with React. Grab `react` and `react-dom` from npm, set up your custom build process with a bundler like [Vite](https://vitejs.dev/) or [Parcel](https://parceljs.org/), and add other tools as you need them for routing, static generation or server-side rendering, and more.

## Production-grade React frameworks[](#production-grade-react-frameworks "Link for Production-grade React frameworks ")

These frameworks support all the features you need to deploy and scale your app in production and are working towards supporting our [full-stack architecture vision](#which-features-make-up-the-react-teams-full-stack-architecture-vision). All of the frameworks we recommend are open source with active communities for support, and can be deployed to your own server or a hosting provider. If you’re a framework author interested in being included on this list, [please let us know](https://github.com/reactjs/react.dev/issues/new?assignees=\&labels=type%3A+framework\&projects=\&template=3-framework.yml\&title=%5BFramework%5D%3A+).

### Next.js[](#nextjs-pages-router "Link for Next.js ")

**[Next.js’ Pages Router](https://nextjs.org/) is a full-stack React framework.** It’s versatile and lets you create React apps of any size—from a mostly static blog to a complex dynamic application. To create a new Next.js project, run in your terminal:

Terminal

npx create-next-app\@latest

If you’re new to Next.js, check out the [learn Next.js course.](https://nextjs.org/learn)

Next.js is maintained by [Vercel](https://vercel.com/). You can [deploy a Next.js app](https://nextjs.org/docs/app/building-your-application/deploying) to any Node.js or serverless hosting, or to your own server. Next.js also supports a [static export](https://nextjs.org/docs/pages/building-your-application/deploying/static-exports) which doesn’t require a server.

### Remix[](#remix "Link for Remix ")

**[Remix](https://remix.run/) is a full-stack React framework with nested routing.** It lets you break your app into nested parts that can load data in parallel and refresh in response to the user actions. To create a new Remix project, run:

Terminal

npx create-remix

If you’re new to Remix, check out the Remix [blog tutorial](https://remix.run/docs/en/main/tutorials/blog) (short) and [app tutorial](https://remix.run/docs/en/main/tutorials/jokes) (long).

Remix is maintained by [Shopify](https://www.shopify.com/). When you create a Remix project, you need to [pick your deployment target](https://remix.run/docs/en/main/guides/deployment). You can deploy a Remix app to any Node.js or serverless hosting by using or writing an [adapter](https://remix.run/docs/en/main/other-api/adapter).

### Gatsby[](#gatsby "Link for Gatsby ")

**[Gatsby](https://www.gatsbyjs.com/) is a React framework for fast CMS-backed websites.** Its rich plugin ecosystem and its GraphQL data layer simplify integrating content, APIs, and services into one website. To create a new Gatsby project, run:

Terminal

npx create-gatsby

If you’re new to Gatsby, check out the [Gatsby tutorial.](https://www.gatsbyjs.com/docs/tutorial/)

Gatsby is maintained by [Netlify](https://www.netlify.com/). You can [deploy a fully static Gatsby site](https://www.gatsbyjs.com/docs/how-to/previews-deploys-hosting) to any static hosting. If you opt into using server-only features, make sure your hosting provider supports them for Gatsby.

### Expo (for native apps)[](#expo "Link for Expo (for native apps) ")

**[Expo](https://expo.dev/) is a React framework that lets you create universal Android, iOS, and web apps with truly native UIs.** It provides an SDK for [React Native](https://reactnative.dev/) that makes the native parts easier to use. To create a new Expo project, run:

Terminal

npx create-expo-app

If you’re new to Expo, check out the [Expo tutorial](https://docs.expo.dev/tutorial/introduction/).

Expo is maintained by [Expo (the company)](https://expo.dev/about). Building apps with Expo is free, and you can submit them to the Google and Apple app stores without restrictions. Expo additionally provides opt-in paid cloud services.

## Bleeding-edge React frameworks[](#bleeding-edge-react-frameworks "Link for Bleeding-edge React frameworks ")

As we’ve explored how to continue improving React, we realized that integrating React more closely with frameworks (specifically, with routing, bundling, and server technologies) is our biggest opportunity to help React users build better apps. The Next.js team has agreed to collaborate with us in researching, developing, integrating, and testing framework-agnostic bleeding-edge React features like [React Server Components.](/blog/2023/03/22/react-labs-what-we-have-been-working-on-march-2023#react-server-components)

These features are getting closer to being production-ready every day, and we’ve been in talks with other bundler and framework developers about integrating them. Our hope is that in a year or two, all frameworks listed on this page will have full support for these features. (If you’re a framework author interested in partnering with us to experiment with these features, please let us know!)

### Next.js (App Router)[](#nextjs-app-router "Link for Next.js (App Router) ")

**[Next.js’s App Router](https://nextjs.org/docs) is a redesign of the Next.js APIs aiming to fulfill the React team’s full-stack architecture vision.** It lets you fetch data in asynchronous components that run on the server or even during the build.

Next.js is maintained by [Vercel](https://vercel.com/). You can [deploy a Next.js app](https://nextjs.org/docs/app/building-your-application/deploying) to any Node.js or serverless hosting, or to your own server. Next.js also supports [static export](https://nextjs.org/docs/app/building-your-application/deploying/static-exports) which doesn’t require a server.

##### Deep Dive#### Which features make up the React team’s full-stack architecture vision?[](#which-features-make-up-the-react-teams-full-stack-architecture-vision "Link for Which features make up the React team’s full-stack architecture vision? ")

Next.js’s App Router bundler fully implements the official [React Server Components specification](https://github.com/reactjs/rfcs/blob/main/text/0188-server-components.md). This lets you mix build-time, server-only, and interactive components in a single React tree.

For example, you can write a server-only React component as an `async` function that reads from a database or from a file. Then you can pass data down from it to your interactive components:

```
// This component runs *only* on the server (or during the build).

async function Talks({ confId }) {

  // 1. You're on the server, so you can talk to your data layer. API endpoint not required.

  const talks = await db.Talks.findAll({ confId });



  // 2. Add any amount of rendering logic. It won't make your JavaScript bundle larger.

  const videos = talks.map(talk => talk.video);



  // 3. Pass the data down to the components that will run in the browser.

  return <SearchableVideoList videos={videos} />;

}
```

Next.js’s App Router also integrates [data fetching with Suspense](/blog/2022/03/29/react-v18#suspense-in-data-frameworks). This lets you specify a loading state (like a skeleton placeholder) for different parts of your user interface directly in your React tree:

```
<Suspense fallback={<TalksLoading />}>

  <Talks confId={conf.id} />

</Suspense>
```

Server Components and Suspense are React features rather than Next.js features. However, adopting them at the framework level requires buy-in and non-trivial implementation work. At the moment, the Next.js App Router is the most complete implementation. The React team is working with bundler developers to make these features easier to implement in the next generation of frameworks.

[PreviousInstallation](/learn/installation)

[NextAdd React to an Existing Project](/learn/add-react-to-an-existing-project)

***

----
url: https://legacy.reactjs.org/docs/state-and-lifecycle.html
----

> These docs are old and won’t be updated. Go to [react.dev](https://react.dev/) for the new React docs.
>
> These new documentation pages teach modern React and include live examples:
>
> * [State: A Component’s Memory](https://react.dev/learn/state-a-components-memory)
> * [Synchronizing with Effects](https://react.dev/learn/synchronizing-with-effects)

This page introduces the concept of state and lifecycle in a React component. You can find a [detailed component API reference here](/docs/react-component.html).

Consider the ticking clock example from [one of the previous sections](/docs/rendering-elements.html#updating-the-rendered-element). In [Rendering Elements](/docs/rendering-elements.html#rendering-an-element-into-the-dom), we have only learned one way to update the UI. We call `root.render()` to change the rendered output:

```
const root = ReactDOM.createRoot(document.getElementById('root'));
  
function tick() {
  const element = (
    <div>
      <h1>Hello, world!</h1>
      <h2>It is {new Date().toLocaleTimeString()}.</h2>
    </div>
  );
  root.render(element);}

setInterval(tick, 1000);
```

[**Try it on CodePen**](https://codepen.io/gaearon/pen/gwoJZk?editors=0010)

In this section, we will learn how to make the `Clock` component truly reusable and encapsulated. It will set up its own timer and update itself every second.

We can start by encapsulating how the clock looks:

```
const root = ReactDOM.createRoot(document.getElementById('root'));

function Clock(props) {
  return (
    <div>      <h1>Hello, world!</h1>      <h2>It is {props.date.toLocaleTimeString()}.</h2>    </div>  );
}

function tick() {
  root.render(<Clock date={new Date()} />);}

setInterval(tick, 1000);
```

[**Try it on CodePen**](https://codepen.io/gaearon/pen/dpdoYR?editors=0010)

However, it misses a crucial requirement: the fact that the `Clock` sets up a timer and updates the UI every second should be an implementation detail of the `Clock`.

Ideally we want to write this once and have the `Clock` update itself:

```
root.render(<Clock />);
```

To implement this, we need to add “state” to the `Clock` component.

State is similar to props, but it is private and fully controlled by the component.

## [](#converting-a-function-to-a-class)Converting a Function to a Class

You can convert a function component like `Clock` to a class in five steps:

1. Create an [ES6 class](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Classes), with the same name, that extends `React.Component`.
2. Add a single empty method to it called `render()`.
3. Move the body of the function into the `render()` method.
4. Replace `props` with `this.props` in the `render()` body.
5. Delete the remaining empty function declaration.

```
class Clock extends React.Component {
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.props.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}
```

[**Try it on CodePen**](https://codepen.io/gaearon/pen/zKRGpo?editors=0010)

`Clock` is now defined as a class rather than a function.

The `render` method will be called each time an update happens, but as long as we render `<Clock />` into the same DOM node, only a single instance of the `Clock` class will be used. This lets us use additional features such as local state and lifecycle methods.

## [](#adding-local-state-to-a-class)Adding Local State to a Class

We will move the `date` from props to state in three steps:

1. Replace `this.props.date` with `this.state.date` in the `render()` method:

```
class Clock extends React.Component {
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>      </div>
    );
  }
}
```

2. Add a [class constructor](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Classes#Constructor) that assigns the initial `this.state`:

```
class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};  }

  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}
```

Note how we pass `props` to the base constructor:

```
  constructor(props) {
    super(props);    this.state = {date: new Date()};
  }
```

Class components should always call the base constructor with `props`.

3. Remove the `date` prop from the `<Clock />` element:

```
root.render(<Clock />);
```

We will later add the timer code back to the component itself.

The result looks like this:

```
class Clock extends React.Component {
  constructor(props) {    super(props);    this.state = {date: new Date()};  }
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>      </div>
    );
  }
}

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Clock />);
```

[**Try it on CodePen**](https://codepen.io/gaearon/pen/KgQpJd?editors=0010)

Next, we’ll make the `Clock` set up its own timer and update itself every second.

## [](#adding-lifecycle-methods-to-a-class)Adding Lifecycle Methods to a Class

In applications with many components, it’s very important to free up resources taken by the components when they are destroyed.

We want to [set up a timer](https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setInterval) whenever the `Clock` is rendered to the DOM for the first time. This is called “mounting” in React.

We also want to [clear that timer](https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/clearInterval) whenever the DOM produced by the `Clock` is removed. This is called “unmounting” in React.

We can declare special methods on the component class to run some code when a component mounts and unmounts:

```
class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }

  componentDidMount() {  }
  componentWillUnmount() {  }
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}
```

These methods are called “lifecycle methods”.

The `componentDidMount()` method runs after the component output has been rendered to the DOM. This is a good place to set up a timer:

```
  componentDidMount() {
    this.timerID = setInterval(      () => this.tick(),      1000    );  }
```

Note how we save the timer ID right on `this` (`this.timerID`).

While `this.props` is set up by React itself and `this.state` has a special meaning, you are free to add additional fields to the class manually if you need to store something that doesn’t participate in the data flow (like a timer ID).

We will tear down the timer in the `componentWillUnmount()` lifecycle method:

```
  componentWillUnmount() {
    clearInterval(this.timerID);  }
```

Finally, we will implement a method called `tick()` that the `Clock` component will run every second.

It will use `this.setState()` to schedule updates to the component local state:

```
class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }

  componentDidMount() {
    this.timerID = setInterval(
      () => this.tick(),
      1000
    );
  }

  componentWillUnmount() {
    clearInterval(this.timerID);
  }

  tick() {    this.setState({      date: new Date()    });  }
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Clock />);
```

[**Try it on CodePen**](https://codepen.io/gaearon/pen/amqdNA?editors=0010)

Now the clock ticks every second.

Let’s quickly recap what’s going on and the order in which the methods are called:

1. When `<Clock />` is passed to `root.render()`, React calls the constructor of the `Clock` component. Since `Clock` needs to display the current time, it initializes `this.state` with an object including the current time. We will later update this state.
2. React then calls the `Clock` component’s `render()` method. This is how React learns what should be displayed on the screen. React then updates the DOM to match the `Clock`’s render output.
3. When the `Clock` output is inserted in the DOM, React calls the `componentDidMount()` lifecycle method. Inside it, the `Clock` component asks the browser to set up a timer to call the component’s `tick()` method once a second.
4. Every second the browser calls the `tick()` method. Inside it, the `Clock` component schedules a UI update by calling `setState()` with an object containing the current time. Thanks to the `setState()` call, React knows the state has changed, and calls the `render()` method again to learn what should be on the screen. This time, `this.state.date` in the `render()` method will be different, and so the render output will include the updated time. React updates the DOM accordingly.
5. If the `Clock` component is ever removed from the DOM, React calls the `componentWillUnmount()` lifecycle method so the timer is stopped.

## [](#using-state-correctly)Using State Correctly

There are three things you should know about `setState()`.

### [](#do-not-modify-state-directly)Do Not Modify State Directly

For example, this will not re-render a component:

```
// Wrong
this.state.comment = 'Hello';
```

Instead, use `setState()`:

```
// Correct
this.setState({comment: 'Hello'});
```

The only place where you can assign `this.state` is the constructor.

### [](#state-updates-may-be-asynchronous)State Updates May Be Asynchronous

React may batch multiple `setState()` calls into a single update for performance.

Because `this.props` and `this.state` may be updated asynchronously, you should not rely on their values for calculating the next state.

For example, this code may fail to update the counter:

```
// Wrong
this.setState({
  counter: this.state.counter + this.props.increment,
});
```

To fix it, use a second form of `setState()` that accepts a function rather than an object. That function will receive the previous state as the first argument, and the props at the time the update is applied as the second argument:

```
// Correct
this.setState((state, props) => ({
  counter: state.counter + props.increment
}));
```

We used an [arrow function](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions) above, but it also works with regular functions:

```
// Correct
this.setState(function(state, props) {
  return {
    counter: state.counter + props.increment
  };
});
```

### [](#state-updates-are-merged)State Updates are Merged

When you call `setState()`, React merges the object you provide into the current state.

For example, your state may contain several independent variables:

```
  constructor(props) {
    super(props);
    this.state = {
      posts: [],      comments: []    };
  }
```

Then you can update them independently with separate `setState()` calls:

```
  componentDidMount() {
    fetchPosts().then(response => {
      this.setState({
        posts: response.posts      });
    });

    fetchComments().then(response => {
      this.setState({
        comments: response.comments      });
    });
  }
```

The merging is shallow, so `this.setState({comments})` leaves `this.state.posts` intact, but completely replaces `this.state.comments`.

## [](#the-data-flows-down)The Data Flows Down

Neither parent nor child components can know if a certain component is stateful or stateless, and they shouldn’t care whether it is defined as a function or a class.

This is why state is often called local or encapsulated. It is not accessible to any component other than the one that owns and sets it.

A component may choose to pass its state down as props to its child components:

```
<FormattedDate date={this.state.date} />
```

The `FormattedDate` component would receive the `date` in its props and wouldn’t know whether it came from the `Clock`’s state, from the `Clock`’s props, or was typed by hand:

```
function FormattedDate(props) {
  return <h2>It is {props.date.toLocaleTimeString()}.</h2>;
}
```

[**Try it on CodePen**](https://codepen.io/gaearon/pen/zKRqNB?editors=0010)

This is commonly called a “top-down” or “unidirectional” data flow. Any state is always owned by some specific component, and any data or UI derived from that state can only affect components “below” them in the tree.

If you imagine a component tree as a waterfall of props, each component’s state is like an additional water source that joins it at an arbitrary point but also flows down.

To show that all components are truly isolated, we can create an `App` component that renders three `<Clock>`s:

```
function App() {
  return (
    <div>
      <Clock />      <Clock />      <Clock />    </div>
  );
}
```

[**Try it on CodePen**](https://codepen.io/gaearon/pen/vXdGmd?editors=0010)

Each `Clock` sets up its own timer and updates independently.

In React apps, whether a component is stateful or stateless is considered an implementation detail of the component that may change over time. You can use stateless components inside stateful components, and vice versa.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/state-and-lifecycle.md)

* Previous article

  [Components and Props](/docs/components-and-props.html)

* Next article

  [Handling Events](/docs/handling-events.html)

----
url: https://18.react.dev/reference/react-dom/components/progress
----

[API Reference](/reference/react)

[Components](/reference/react-dom/components)

# \<progress>[](#undefined "Link for this heading")

The [built-in browser `<progress>` component](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/progress) lets you render a progress indicator.

```
<progress value={0.5} />
```

* [Reference](#reference)
  * [`<progress>`](#progress)
* [Usage](#usage)
  * [Controlling a progress indicator](#controlling-a-progress-indicator)

***

## Reference[](#reference "Link for Reference ")

### `<progress>`[](#progress "Link for this heading")

To display a progress indicator, render the [built-in browser `<progress>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/progress) component.

```
<progress value={0.5} />
```

[See more examples below.](#usage)

#### Props[](#props "Link for Props ")

`<progress>` supports all [common element props.](/reference/react-dom/components/common#props)

Additionally, `<progress>` supports these props:

* [`max`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/progress#max): A number. Specifies the maximum `value`. Defaults to `1`.
* [`value`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/progress#value): A number between `0` and `max`, or `null` for indeterminate progress. Specifies how much was done.

***

## Usage[](#usage "Link for Usage ")

### Controlling a progress indicator[](#controlling-a-progress-indicator "Link for Controlling a progress indicator ")

To display a progress indicator, render a `<progress>` component. You can pass a number `value` between `0` and the `max` value you specify. If you don’t pass a `max` value, it will assumed to be `1` by default.

If the operation is not ongoing, pass `value={null}` to put the progress indicator into an indeterminate state.

```
export default function App() {
  return (
    <>
      <progress value={0} />
      <progress value={0.5} />
      <progress value={0.7} />
      <progress value={75} max={100} />
      <progress value={1} />
      <progress value={null} />
    </>
  );
}
```

[Previous\<option>](/reference/react-dom/components/option)

[Next\<select>](/reference/react-dom/components/select)

***

----
url: https://legacy.reactjs.org/blog/2015/12/04/react-js-conf-2016-diversity-scholarship.html
----

December 04, 2015 by [Paul O’Shannessy](https://twitter.com/zpao)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

I am thrilled to announced that we will be organizing another diversity scholarship program for the upcoming React.js Conf! The tech industry is suffering from a lack of diversity, but it’s important to us that we have a thriving community that is made up of people with a variety of experiences and viewpoints.

When we ran this program last year, we had *over 200* people apply for only 10 tickets. There were so many people that we wanted to bring in but we couldn’t. The results were still awesome, and we had bright individuals from around the world attending who would have otherwise been unable to. These attendees took part in discussions at the conference and brought perspectives that we might not have otherwise seen there.

This year we’re excited to bring back the scholarship, but we’ve set aside **40 tickets** because we really believe that it’s important to do our best to make sure we have an even more diverse audience.

This is something I’m personally really excited to be a part of. I know the rest of the team is as well. We’re really proud to have everyone at Facebook providing support and funding for this.

The details of the scholarship are provided below (or you can [go directly to the application](http://goo.gl/forms/PEmKj8oUp4)). I encourage you to apply! If you don’t feel like you are eligible yourself, you can still help – send this along to friends, family, coworkers, acquaintances, or anybody who might be interested. And even if you haven’t spoken before, please consider [submitting a proposal for a talk](http://conf.reactjs.com/) (either 30 minutes or just 5 minutes) - we’re hoping to have a very diverse group of speakers in addition to attendees.

***

Facebook is excited to announce that we are now accepting applications for the React.js Conf Diversity Scholarship!

Beginning today, those studying or working in computer science or a related field can apply for a partial scholarship to attend the React.js Conf in San Francisco, CA on February 22 & 23, 2016.

React opens a world of new possibilities such as server-side rendering, real-time updates, different rendering targets like SVG and canvas. React Native makes is easy to use the same concepts and technologies to build native mobile experiences on iOS and Android. Join us at React.js Conf to shape the future of client-side applications! For more information about the React.js conference, please see [the website](http://conf.reactjs.com/).

At Facebook, we believe that anyone anywhere can make a positive impact by developing products to make the world more open and connected to the people and things they care about. Given the current realities of the tech industry and the lack of representation of communities we seek to serve, applicants currently under-represented in Computer Science and related fields are strongly encouraged to apply. Facebook will make determinations on scholarship recipients in its sole discretion. Facebook complies with all equal opportunity laws.

To apply for the scholarship, please visit the application page: **<http://goo.gl/forms/PEmKj8oUp4>**

## [](#award-includes)Award Includes

* Paid registration fee for the React.js Conf February 22 & 23 in downtown San Francisco, CA
* Paid lodging expenses for February 21, 22, 23

## [](#important-dates)Important Dates

* Sunday December 13th 2015 - 11:59 PST: Applications for the React.js Conf Scholarship must be submitted in full
* Wednesday, December 16th, 2015: Award recipients will be notified by email of their acceptance
* Monday & Tuesday, February 22 & 23, 2016: React.js Conf

## [](#eligibility)Eligibility

* Must currently be studying or working in Computer Science or a related field
* International applicants are welcome, but you will be responsible for securing your own visa to attend the conference
* You must be able to provide your own transportation to San Francisco
* You must be available to attend the full duration of React.js Conf on February 22 & 23 in San Francisco, CA

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2015-12-04-react-js-conf-2016-diversity-scholarship.md)

----
url: https://react.dev/learn/escape-hatches
----

```
const ref = useRef(0);
```

Like state, refs are retained by React between re-renders. However, setting state re-renders a component. Changing a ref does not! You can access the current value of that ref through the `ref.current` property.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useRef } from 'react';

export default function Counter() {
  let ref = useRef(0);

  function handleClick() {
    ref.current = ref.current + 1;
    alert('You clicked ' + ref.current + ' times!');
  }

  return (
    <button onClick={handleClick}>
      Click me!
    </button>
  );
}
```

A ref is like a secret pocket of your component that React doesn’t track. For example, you can use refs to store [timeout IDs](https://developer.mozilla.org/en-US/docs/Web/API/setTimeout#return_value), [DOM elements](https://developer.mozilla.org/en-US/docs/Web/API/Element), and other objects that don’t impact the component’s rendering output.

## Ready to learn this topic?

Read **[Referencing Values with Refs](/learn/referencing-values-with-refs)** to learn how to use refs to remember information.

[Read More](/learn/referencing-values-with-refs)

***

## Manipulating the DOM with refs[](#manipulating-the-dom-with-refs "Link for Manipulating the DOM with refs ")

React automatically updates the DOM to match your render output, so your components won’t often need to manipulate it. However, sometimes you might need access to the DOM elements managed by React—for example, to focus a node, scroll to it, or measure its size and position. There is no built-in way to do those things in React, so you will need a ref to the DOM node. For example, clicking the button will focus the input using a ref:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useRef } from 'react';

export default function Form() {
  const inputRef = useRef(null);

  function handleClick() {
    inputRef.current.focus();
  }

  return (
    <>
      <input ref={inputRef} />
      <button onClick={handleClick}>
        Focus the input
      </button>
    </>
  );
}
```

## Ready to learn this topic?

Read **[Manipulating the DOM with Refs](/learn/manipulating-the-dom-with-refs)** to learn how to access DOM elements managed by React.

[Read More](/learn/manipulating-the-dom-with-refs)

***

## Synchronizing with Effects[](#synchronizing-with-effects "Link for Synchronizing with Effects ")

Some components need to synchronize with external systems. For example, you might want to control a non-React component based on the React state, set up a server connection, or send an analytics log when a component appears on the screen. Unlike event handlers, which let you handle particular events, *Effects* let you run some code after rendering. Use them to synchronize your component with a system outside of React.

Press Play/Pause a few times and see how the video player stays synchronized to the `isPlaying` prop value:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useRef, useEffect } from 'react';

function VideoPlayer({ src, isPlaying }) {
  const ref = useRef(null);

  useEffect(() => {
    if (isPlaying) {
      ref.current.play();
    } else {
      ref.current.pause();
    }
  }, [isPlaying]);

  return <video ref={ref} src={src} loop playsInline />;
}

export default function App() {
  const [isPlaying, setIsPlaying] = useState(false);
  return (
    <>
      <button onClick={() => setIsPlaying(!isPlaying)}>
        {isPlaying ? 'Pause' : 'Play'}
      </button>
      <VideoPlayer
        isPlaying={isPlaying}
        src="https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4"
      />
    </>
  );
}
```

Many Effects also “clean up” after themselves. For example, an Effect that sets up a connection to a chat server should return a *cleanup function* that tells React how to disconnect your component from that server:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useEffect } from 'react';
import { createConnection } from './chat.js';

export default function ChatRoom() {
  useEffect(() => {
    const connection = createConnection();
    connection.connect();
    return () => connection.disconnect();
  }, []);
  return <h1>Welcome to the chat!</h1>;
}
```

In development, React will immediately run and clean up your Effect one extra time. This is why you see `"✅ Connecting..."` printed twice. This ensures that you don’t forget to implement the cleanup function.

## Ready to learn this topic?

Read **[Synchronizing with Effects](/learn/synchronizing-with-effects)** to learn how to synchronize components with external systems.

[Read More](/learn/synchronizing-with-effects)

***

## You Might Not Need An Effect[](#you-might-not-need-an-effect "Link for You Might Not Need An Effect ")

Effects are an escape hatch from the React paradigm. They let you “step outside” of React and synchronize your components with some external system. If there is no external system involved (for example, if you want to update a component’s state when some props or state change), you shouldn’t need an Effect. Removing unnecessary Effects will make your code easier to follow, faster to run, and less error-prone.

There are two common cases in which you don’t need Effects:

* **You don’t need Effects to transform data for rendering.**
* **You don’t need Effects to handle user events.**

For example, you don’t need an Effect to adjust some state based on other state:

```
function Form() {

  const [firstName, setFirstName] = useState('Taylor');

  const [lastName, setLastName] = useState('Swift');



  // 🔴 Avoid: redundant state and unnecessary Effect

  const [fullName, setFullName] = useState('');

  useEffect(() => {

    setFullName(firstName + ' ' + lastName);

  }, [firstName, lastName]);

  // ...

}
```

Instead, calculate as much as you can while rendering:

```
function Form() {

  const [firstName, setFirstName] = useState('Taylor');

  const [lastName, setLastName] = useState('Swift');

  // ✅ Good: calculated during rendering

  const fullName = firstName + ' ' + lastName;

  // ...

}
```

However, you *do* need Effects to synchronize with external systems.

## Ready to learn this topic?

Read **[You Might Not Need an Effect](/learn/you-might-not-need-an-effect)** to learn how to remove unnecessary Effects.

[Read More](/learn/you-might-not-need-an-effect)

***

## Lifecycle of reactive effects[](#lifecycle-of-reactive-effects "Link for Lifecycle of reactive effects ")

Effects have a different lifecycle from components. Components may mount, update, or unmount. An Effect can only do two things: to start synchronizing something, and later to stop synchronizing it. This cycle can happen multiple times if your Effect depends on props and state that change over time.

This Effect depends on the value of the `roomId` prop. Props are *reactive values,* which means they can change on a re-render. Notice that the Effect *re-synchronizes* (and re-connects to the server) if `roomId` changes:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useEffect } from 'react';
import { createConnection } from './chat.js';

const serverUrl = 'https://localhost:1234';

function ChatRoom({ roomId }) {
  useEffect(() => {
    const connection = createConnection(serverUrl, roomId);
    connection.connect();
    return () => connection.disconnect();
  }, [roomId]);

  return <h1>Welcome to the {roomId} room!</h1>;
}

export default function App() {
  const [roomId, setRoomId] = useState('general');
  return (
    <>
      <label>
        Choose the chat room:{' '}
        <select
          value={roomId}
          onChange={e => setRoomId(e.target.value)}
        >
          <option value="general">general</option>
          <option value="travel">travel</option>
          <option value="music">music</option>
        </select>
      </label>
      <hr />
      <ChatRoom roomId={roomId} />
    </>
  );
}
```

React provides a linter rule to check that you’ve specified your Effect’s dependencies correctly. If you forget to specify `roomId` in the list of dependencies in the above example, the linter will find that bug automatically.

## Ready to learn this topic?

Read **[Lifecycle of Reactive Events](/learn/lifecycle-of-reactive-effects)** to learn how an Effect’s lifecycle is different from a component’s.

[Read More](/learn/lifecycle-of-reactive-effects)

***

## Separating events from Effects[](#separating-events-from-effects "Link for Separating events from Effects ")

Event handlers only re-run when you perform the same interaction again. Unlike event handlers, Effects re-synchronize if any of the values they read, like props or state, are different than during last render. Sometimes, you want a mix of both behaviors: an Effect that re-runs in response to some values but not others.

All code inside Effects is *reactive.* It will run again if some reactive value it reads has changed due to a re-render. For example, this Effect will re-connect to the chat if either `roomId` or `theme` have changed:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useEffect } from 'react';
import { createConnection, sendMessage } from './chat.js';
import { showNotification } from './notifications.js';

const serverUrl = 'https://localhost:1234';

function ChatRoom({ roomId, theme }) {
  useEffect(() => {
    const connection = createConnection(serverUrl, roomId);
    connection.on('connected', () => {
      showNotification('Connected!', theme);
    });
    connection.connect();
    return () => connection.disconnect();
  }, [roomId, theme]);

  return <h1>Welcome to the {roomId} room!</h1>
}

export default function App() {
  const [roomId, setRoomId] = useState('general');
  const [isDark, setIsDark] = useState(false);
  return (
    <>
      <label>
        Choose the chat room:{' '}
        <select
          value={roomId}
          onChange={e => setRoomId(e.target.value)}
        >
          <option value="general">general</option>
          <option value="travel">travel</option>
          <option value="music">music</option>
        </select>
      </label>
      <label>
        <input
          type="checkbox"
          checked={isDark}
          onChange={e => setIsDark(e.target.checked)}
        />
        Use dark theme
      </label>
      <hr />
      <ChatRoom
        roomId={roomId}
        theme={isDark ? 'dark' : 'light'}
      />
    </>
  );
}
```

This is not ideal. You want to re-connect to the chat only if the `roomId` has changed. Switching the `theme` shouldn’t re-connect to the chat! Move the code reading `theme` out of your Effect into an *Effect Event*:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useEffect } from 'react';
import { useEffectEvent } from 'react';
import { createConnection, sendMessage } from './chat.js';
import { showNotification } from './notifications.js';

const serverUrl = 'https://localhost:1234';

function ChatRoom({ roomId, theme }) {
  const onConnected = useEffectEvent(() => {
    showNotification('Connected!', theme);
  });

  useEffect(() => {
    const connection = createConnection(serverUrl, roomId);
    connection.on('connected', () => {
      onConnected();
    });
    connection.connect();
    return () => connection.disconnect();
  }, [roomId]);

  return <h1>Welcome to the {roomId} room!</h1>
}

export default function App() {
  const [roomId, setRoomId] = useState('general');
  const [isDark, setIsDark] = useState(false);
  return (
    <>
      <label>
        Choose the chat room:{' '}
        <select
          value={roomId}
          onChange={e => setRoomId(e.target.value)}
        >
          <option value="general">general</option>
          <option value="travel">travel</option>
          <option value="music">music</option>
        </select>
      </label>
      <label>
        <input
          type="checkbox"
          checked={isDark}
          onChange={e => setIsDark(e.target.checked)}
        />
        Use dark theme
      </label>
      <hr />
      <ChatRoom
        roomId={roomId}
        theme={isDark ? 'dark' : 'light'}
      />
    </>
  );
}
```

Code inside Effect Events isn’t reactive, so changing the `theme` no longer makes your Effect re-connect.

## Ready to learn this topic?

Read **[Separating Events from Effects](/learn/separating-events-from-effects)** to learn how to prevent some values from re-triggering Effects.

[Read More](/learn/separating-events-from-effects)

***

## Removing Effect dependencies[](#removing-effect-dependencies "Link for Removing Effect dependencies ")

When you write an Effect, the linter will verify that you’ve included every reactive value (like props and state) that the Effect reads in the list of your Effect’s dependencies. This ensures that your Effect remains synchronized with the latest props and state of your component. Unnecessary dependencies may cause your Effect to run too often, or even create an infinite loop. The way you remove them depends on the case.

For example, this Effect depends on the `options` object which gets re-created every time you edit the input:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useEffect } from 'react';
import { createConnection } from './chat.js';

const serverUrl = 'https://localhost:1234';

function ChatRoom({ roomId }) {
  const [message, setMessage] = useState('');

  const options = {
    serverUrl: serverUrl,
    roomId: roomId
  };

  useEffect(() => {
    const connection = createConnection(options);
    connection.connect();
    return () => connection.disconnect();
  }, [options]);

  return (
    <>
      <h1>Welcome to the {roomId} room!</h1>
      <input value={message} onChange={e => setMessage(e.target.value)} />
    </>
  );
}

export default function App() {
  const [roomId, setRoomId] = useState('general');
  return (
    <>
      <label>
        Choose the chat room:{' '}
        <select
          value={roomId}
          onChange={e => setRoomId(e.target.value)}
        >
          <option value="general">general</option>
          <option value="travel">travel</option>
          <option value="music">music</option>
        </select>
      </label>
      <hr />
      <ChatRoom roomId={roomId} />
    </>
  );
}
```

You don’t want the chat to re-connect every time you start typing a message in that chat. To fix this problem, move creation of the `options` object inside the Effect so that the Effect only depends on the `roomId` string:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useEffect } from 'react';
import { createConnection } from './chat.js';

const serverUrl = 'https://localhost:1234';

function ChatRoom({ roomId }) {
  const [message, setMessage] = useState('');

  useEffect(() => {
    const options = {
      serverUrl: serverUrl,
      roomId: roomId
    };
    const connection = createConnection(options);
    connection.connect();
    return () => connection.disconnect();
  }, [roomId]);

  return (
    <>
      <h1>Welcome to the {roomId} room!</h1>
      <input value={message} onChange={e => setMessage(e.target.value)} />
    </>
  );
}

export default function App() {
  const [roomId, setRoomId] = useState('general');
  return (
    <>
      <label>
        Choose the chat room:{' '}
        <select
          value={roomId}
          onChange={e => setRoomId(e.target.value)}
        >
          <option value="general">general</option>
          <option value="travel">travel</option>
          <option value="music">music</option>
        </select>
      </label>
      <hr />
      <ChatRoom roomId={roomId} />
    </>
  );
}
```

Notice that you didn’t start by editing the dependency list to remove the `options` dependency. That would be wrong. Instead, you changed the surrounding code so that the dependency became *unnecessary.* Think of the dependency list as a list of all the reactive values used by your Effect’s code. You don’t intentionally choose what to put on that list. The list describes your code. To change the dependency list, change the code.

## Ready to learn this topic?

Read **[Removing Effect Dependencies](/learn/removing-effect-dependencies)** to learn how to make your Effect re-run less often.

[Read More](/learn/removing-effect-dependencies)

***

## Reusing logic with custom Hooks[](#reusing-logic-with-custom-hooks "Link for Reusing logic with custom Hooks ")

React comes with built-in Hooks like `useState`, `useContext`, and `useEffect`. Sometimes, you’ll wish that there was a Hook for some more specific purpose: for example, to fetch data, to keep track of whether the user is online, or to connect to a chat room. To do this, you can create your own Hooks for your application’s needs.

In this example, the `usePointerPosition` custom Hook tracks the cursor position, while `useDelayedValue` custom Hook returns a value that’s “lagging behind” the value you passed by a certain number of milliseconds. Move the cursor over the sandbox preview area to see a moving trail of dots following the cursor:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { usePointerPosition } from './usePointerPosition.js';
import { useDelayedValue } from './useDelayedValue.js';

export default function Canvas() {
  const pos1 = usePointerPosition();
  const pos2 = useDelayedValue(pos1, 100);
  const pos3 = useDelayedValue(pos2, 200);
  const pos4 = useDelayedValue(pos3, 100);
  const pos5 = useDelayedValue(pos4, 50);
  return (
    <>
      <Dot position={pos1} opacity={1} />
      <Dot position={pos2} opacity={0.8} />
      <Dot position={pos3} opacity={0.6} />
      <Dot position={pos4} opacity={0.4} />
      <Dot position={pos5} opacity={0.2} />
    </>
  );
}

function Dot({ position, opacity }) {
  return (
    <div style={{
      position: 'absolute',
      backgroundColor: 'pink',
      borderRadius: '50%',
      opacity,
      transform: `translate(${position.x}px, ${position.y}px)`,
      pointerEvents: 'none',
      left: -20,
      top: -20,
      width: 40,
      height: 40,
    }} />
  );
}
```

You can create custom Hooks, compose them together, pass data between them, and reuse them between components. As your app grows, you will write fewer Effects by hand because you’ll be able to reuse custom Hooks you already wrote. There are also many excellent custom Hooks maintained by the React community.

## Ready to learn this topic?

Read **[Reusing Logic with Custom Hooks](/learn/reusing-logic-with-custom-hooks)** to learn how to share logic between components.

[Read More](/learn/reusing-logic-with-custom-hooks)

***

## What’s next?[](#whats-next "Link for What’s next? ")

Head over to [Referencing Values with Refs](/learn/referencing-values-with-refs) to start reading this chapter page by page!

[PreviousScaling Up with Reducer and Context](/learn/scaling-up-with-reducer-and-context)

[NextReferencing Values with Refs](/learn/referencing-values-with-refs)

***

----
url: https://18.react.dev/learn/your-first-component
----

```
<article>

  <h1>My First Component</h1>

  <ol>

    <li>Components: UI Building Blocks</li>

    <li>Defining a Component</li>

    <li>Using a Component</li>

  </ol>

</article>
```

This markup represents this article `<article>`, its heading `<h1>`, and an (abbreviated) table of contents as an ordered list `<ol>`. Markup like this, combined with CSS for style, and JavaScript for interactivity, lies behind every sidebar, avatar, modal, dropdown—every piece of UI you see on the Web.

React lets you combine your markup, CSS, and JavaScript into custom “components”, **reusable UI elements for your app.** The table of contents code you saw above could be turned into a `<TableOfContents />` component you could render on every page. Under the hood, it still uses the same HTML tags like `<article>`, `<h1>`, etc.

Just like with HTML tags, you can compose, order and nest components to design whole pages. For example, the documentation page you’re reading is made out of React components:

```
<PageLayout>

  <NavigationHeader>

    <SearchBar />

    <Link to="/docs">Docs</Link>

  </NavigationHeader>

  <Sidebar />

  <PageContent>

    <TableOfContents />

    <DocumentationText />

  </PageContent>

</PageLayout>
```

As your project grows, you will notice that many of your designs can be composed by reusing components you already wrote, speeding up your development. Our table of contents above could be added to any screen with `<TableOfContents />`! You can even jumpstart your project with the thousands of components shared by the React open source community like [Chakra UI](https://chakra-ui.com/) and [Material UI.](https://material-ui.com/)

## Defining a component[](#defining-a-component "Link for Defining a component ")

Traditionally when creating web pages, web developers marked up their content and then added interaction by sprinkling on some JavaScript. This worked great when interaction was a nice-to-have on the web. Now it is expected for many sites and all apps. React puts interactivity first while still using the same technology: **a React component is a JavaScript function that you can *sprinkle with markup*.** Here’s what that looks like (you can edit the example below):

```
export default function Profile() {
  return (
    <img
      src="https://i.imgur.com/MK3eW3Am.jpg"
      alt="Katherine Johnson"
    />
  )
}
```

```
return <img src="https://i.imgur.com/MK3eW3As.jpg" alt="Katherine Johnson" />;
```

But if your markup isn’t all on the same line as the `return` keyword, you must wrap it in a pair of parentheses:

```
return (

  <div>

    <img src="https://i.imgur.com/MK3eW3As.jpg" alt="Katherine Johnson" />

  </div>

);
```

### Pitfall

Without parentheses, any code on the lines after `return` [will be ignored](https://stackoverflow.com/questions/2846283/what-are-the-rules-for-javascripts-automatic-semicolon-insertion-asi)!

## Using a component[](#using-a-component "Link for Using a component ")

Now that you’ve defined your `Profile` component, you can nest it inside other components. For example, you can export a `Gallery` component that uses multiple `Profile` components:

```
function Profile() {
  return (
    <img
      src="https://i.imgur.com/MK3eW3As.jpg"
      alt="Katherine Johnson"
    />
  );
}

export default function Gallery() {
  return (
    <section>
      <h1>Amazing scientists</h1>
      <Profile />
      <Profile />
      <Profile />
    </section>
  );
}
```

### What the browser sees[](#what-the-browser-sees "Link for What the browser sees ")

Notice the difference in casing:

* `<section>` is lowercase, so React knows we refer to an HTML tag.
* `<Profile />` starts with a capital `P`, so React knows that we want to use our component called `Profile`.

And `Profile` contains even more HTML: `<img />`. In the end, this is what the browser sees:

```
<section>

  <h1>Amazing scientists</h1>

  <img src="https://i.imgur.com/MK3eW3As.jpg" alt="Katherine Johnson" />

  <img src="https://i.imgur.com/MK3eW3As.jpg" alt="Katherine Johnson" />

  <img src="https://i.imgur.com/MK3eW3As.jpg" alt="Katherine Johnson" />

</section>
```

### Nesting and organizing components[](#nesting-and-organizing-components "Link for Nesting and organizing components ")

Components are regular JavaScript functions, so you can keep multiple components in the same file. This is convenient when components are relatively small or tightly related to each other. If this file gets crowded, you can always move `Profile` to a separate file. You will learn how to do this shortly on the [page about imports.](/learn/importing-and-exporting-components)

Because the `Profile` components are rendered inside `Gallery`—even several times!—we can say that `Gallery` is a **parent component,** rendering each `Profile` as a “child”. This is part of the magic of React: you can define a component once, and then use it in as many places and as many times as you like.

### Pitfall

Components can render other components, but **you must never nest their definitions:**

```
export default function Gallery() {

  // 🔴 Never define a component inside another component!

  function Profile() {

    // ...

  }

  // ...

}
```

The snippet above is [very slow and causes bugs.](/learn/preserving-and-resetting-state#different-components-at-the-same-position-reset-state) Instead, define every component at the top level:

```
export default function Gallery() {

  // ...

}



// ✅ Declare components at the top level

function Profile() {

  // ...

}
```

When a child component needs some data from a parent, [pass it by props](/learn/passing-props-to-a-component) instead of nesting definitions.

##### Deep Dive#### Components all the way down[](#components-all-the-way-down "Link for Components all the way down ")

Your React application begins at a “root” component. Usually, it is created automatically when you start a new project. For example, if you use [CodeSandbox](https://codesandbox.io/) or if you use the framework [Next.js](https://nextjs.org/), the root component is defined in `pages/index.js`. In these examples, you’ve been exporting root components.

Most React apps use components all the way down. This means that you won’t only use components for reusable pieces like buttons, but also for larger pieces like sidebars, lists, and ultimately, complete pages! Components are a handy way to organize UI code and markup, even if some of them are only used once.

[React-based frameworks](/learn/start-a-new-react-project) take this a step further. Instead of using an empty HTML file and letting React “take over” managing the page with JavaScript, they *also* generate the HTML automatically from your React components. This allows your app to show some content before the JavaScript code loads.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?parameters=N4IgZglgNgpgziAXKOAnAxgeggOwCYwAeAdAFYLIjoD2OALjPUiBALYAO1qdABAEowAhujoAaHsB4BlOqggiAstQI8AvjzCpqrHgB0QqISP0BuXTjaduEnukOCGfatV7rN2vQaN0AtHm2Y6FAQjHSm5pZcvPrEmHB0AJ6wcMTocHDhOBEcUTwAguzsGlo6MZgF7JnmNDjxPFouPAC8tvaOznQAFP7oAK6socQA5jB0AKKwA_QAQgkAknid-g1hIACUa2Y4K8SG-DCoSzg8PAA8MnKKyjAAfOYnJ6cVPJh3x2eYF_J0SgRvmyBRCw4NNcIJUAkkGBBFA4DBVED2MIANaCEZkOC0JCgGoMJiIEDAe6eHCCAb6RCeewiYgEABu-lExP0dIOcAgtApngADMRedzGcyQKxBLgufo4hhsPsSORBe99HA7BB2HQMkgJMSToq6ODVpTlt4fEq5Kq4Dx4nr5Q9PAAjXrQPDirzCXwmlVqnj2x3Wh76BjxZ3Ut3Ks08AO8Hw-Rh0prkfysX3akAwUgwYwaw2u42hz2p9OrYkIoUEdiMAg4dAhdWUonvZPB50APQAjAAOPl8pNUo0J5vtzsCwFanvZ91m5sAVkH-iLTIVIHpABEYGX9pXq1zgKpzKpAcDQaSIVCYXCESB2L1bcEsLgCCQABZ0VhQbFUWh4ujMU4AQiXAHkAGEABUAE0AAUxh4J8XzeU4YKgHgoEEHAhiafRGH0OCHyEPA3keAZdVsB9wThOh0JAABVYCADEfDbLDiVOQjBB4UkBgoukQgAdysVZbA_UIKO4iA8DoB8mnpeQYB8ESxIfcRcAgOgIBhHMYRgJoWy7EB8LOFS6FgG4l2oPopjoU5MAMozzEsnDBDw2zbWUBI9NOPAIDpHhRIolYsMsjy6TgzBnLwVzbMwBCbn3CAQTBY9EGhWF4SBNAsAqDE31xUJmDAXpKxU2geHArRIFgTo1k1d5DDoXpUGOI4bVONghhHE40oop86HYOBEEwbBiBaurUgCKA5kAsA6VtJcyHYVqQDangYXI_Q8mRYIoF6HgABkYFYEVZ3rF49M2XdzBiuKj0hRLTxSkA0riRJklSdIssE_EQAAKiqk5nMIY0IAAL1wIZKWc1ACFQHw_q2HcshwUKEh-jQPx8aFWGgBJKTgFC4GNA4IDALYThFVAhlwSkACZuXYQhiZ4JE8A81DKW5WHzHMB8W2R0nyZwHw6GodhWfpsBUfZQGYCpynafZ-GH0pnnwT5gWhZF4kxfoAHJapmm6bO-WAGYlbJ3BVeFng2Y18Wgalnh21lg3OYAFhNlXBYtq33k1t1bcpFsADZHZwOHOcnN2zY99XvZtnX7ed4PQ5wB8A4j_mo8t0XY7tlsZf1kOOcra5kZ97Wc-ISm9rl8xekQusTkZ5mhh8XBghwGTLW4XXE8LlqbBwiAhiff22xbWW1HOoFYsPcFrqSs9zwYDhkIYZg7CEBgfGDHxBEKEBVCAA\&query=file%3D%252Fsrc%252FApp.js%26utm_medium%3Dsandpack\&environment=create-react-app "Open in CodeSandbox")

```
function Profile() {
  return (
    <img
      src="https://i.imgur.com/lICfvbD.jpg"
      alt="Aklilu Lemma"
    />
  );
}
```

Try to fix it yourself before looking at the solution!

[PreviousDescribing the UI](/learn/describing-the-ui)

[NextImporting and Exporting Components](/learn/importing-and-exporting-components)

***

----
url: https://18.react.dev/learn/describing-the-ui
----

```
function Profile() {
  return (
    <img
      src="https://i.imgur.com/MK3eW3As.jpg"
      alt="Katherine Johnson"
    />
  );
}

export default function Gallery() {
  return (
    <section>
      <h1>Amazing scientists</h1>
      <Profile />
      <Profile />
      <Profile />
    </section>
  );
}
```

## Ready to learn this topic?

Read **[Your First Component](/learn/your-first-component)** to learn how to declare and use React components.

[Read More](/learn/your-first-component)

***

## Importing and exporting components[](#importing-and-exporting-components "Link for Importing and exporting components ")

You can declare many components in one file, but large files can get difficult to navigate. To solve this, you can *export* a component into its own file, and then *import* that component from another file:

```
import Profile from './Profile.js';

export default function Gallery() {
  return (
    <section>
      <h1>Amazing scientists</h1>
      <Profile />
      <Profile />
      <Profile />
    </section>
  );
}
```

## Ready to learn this topic?

Read **[Importing and Exporting Components](/learn/importing-and-exporting-components)** to learn how to split components into their own files.

[Read More](/learn/importing-and-exporting-components)

***

## Writing markup with JSX[](#writing-markup-with-jsx "Link for Writing markup with JSX ")

Each React component is a JavaScript function that may contain some markup that React renders into the browser. React components use a syntax extension called JSX to represent that markup. JSX looks a lot like HTML, but it is a bit stricter and can display dynamic information.

If we paste existing HTML markup into a React component, it won’t always work:

```
export default function TodoList() {
  return (
    // This doesn't quite work!
    <h1>Hedy Lamarr's Todos</h1>
    <img
      src="https://i.imgur.com/yXOvdOSs.jpg"
      alt="Hedy Lamarr"
      class="photo"
    >
    <ul>
      <li>Invent new traffic lights
      <li>Rehearse a movie scene
      <li>Improve spectrum technology
    </ul>
```

If you have existing HTML like this, you can fix it using a [converter](https://transform.tools/html-to-jsx):

```
export default function TodoList() {
  return (
    <>
      <h1>Hedy Lamarr's Todos</h1>
      <img
        src="https://i.imgur.com/yXOvdOSs.jpg"
        alt="Hedy Lamarr"
        className="photo"
      />
      <ul>
        <li>Invent new traffic lights</li>
        <li>Rehearse a movie scene</li>
        <li>Improve spectrum technology</li>
      </ul>
    </>
  );
}
```

## Ready to learn this topic?

Read **[Writing Markup with JSX](/learn/writing-markup-with-jsx)** to learn how to write valid JSX.

[Read More](/learn/writing-markup-with-jsx)

***

## JavaScript in JSX with curly braces[](#javascript-in-jsx-with-curly-braces "Link for JavaScript in JSX with curly braces ")

JSX lets you write HTML-like markup inside a JavaScript file, keeping rendering logic and content in the same place. Sometimes you will want to add a little JavaScript logic or reference a dynamic property inside that markup. In this situation, you can use curly braces in your JSX to “open a window” to JavaScript:

```
const person = {
  name: 'Gregorio Y. Zara',
  theme: {
    backgroundColor: 'black',
    color: 'pink'
  }
};

export default function TodoList() {
  return (
    <div style={person.theme}>
      <h1>{person.name}'s Todos</h1>
      <img
        className="avatar"
        src="https://i.imgur.com/7vQD0fPs.jpg"
        alt="Gregorio Y. Zara"
      />
      <ul>
        <li>Improve the videophone</li>
        <li>Prepare aeronautics lectures</li>
        <li>Work on the alcohol-fuelled engine</li>
      </ul>
    </div>
  );
}
```

## Ready to learn this topic?

Read **[JavaScript in JSX with Curly Braces](/learn/javascript-in-jsx-with-curly-braces)** to learn how to access JavaScript data from JSX.

[Read More](/learn/javascript-in-jsx-with-curly-braces)

***

## Passing props to a component[](#passing-props-to-a-component "Link for Passing props to a component ")

React components use *props* to communicate with each other. Every parent component can pass some information to its child components by giving them props. Props might remind you of HTML attributes, but you can pass any JavaScript value through them, including objects, arrays, functions, and even JSX!

```
import { getImageUrl } from './utils.js'

export default function Profile() {
  return (
    <Card>
      <Avatar
        size={100}
        person={{
          name: 'Katsuko Saruhashi',
          imageId: 'YfeOqp2'
        }}
      />
    </Card>
  );
}

function Avatar({ person, size }) {
  return (
    <img
      className="avatar"
      src={getImageUrl(person)}
      alt={person.name}
      width={size}
      height={size}
    />
  );
}

function Card({ children }) {
  return (
    <div className="card">
      {children}
    </div>
  );
}
```

## Ready to learn this topic?

Read **[Passing Props to a Component](/learn/passing-props-to-a-component)** to learn how to pass and read props.

[Read More](/learn/passing-props-to-a-component)

***

## Conditional rendering[](#conditional-rendering "Link for Conditional rendering ")

Your components will often need to display different things depending on different conditions. In React, you can conditionally render JSX using JavaScript syntax like `if` statements, `&&`, and `? :` operators.

In this example, the JavaScript `&&` operator is used to conditionally render a checkmark:

```
function Item({ name, isPacked }) {
  return (
    <li className="item">
      {name} {isPacked && '✅'}
    </li>
  );
}

export default function PackingList() {
  return (
    <section>
      <h1>Sally Ride's Packing List</h1>
      <ul>
        <Item
          isPacked={true}
          name="Space suit"
        />
        <Item
          isPacked={true}
          name="Helmet with a golden leaf"
        />
        <Item
          isPacked={false}
          name="Photo of Tam"
        />
      </ul>
    </section>
  );
}
```

## Ready to learn this topic?

Read **[Conditional Rendering](/learn/conditional-rendering)** to learn the different ways to render content conditionally.

[Read More](/learn/conditional-rendering)

***

## Rendering lists[](#rendering-lists "Link for Rendering lists ")

You will often want to display multiple similar components from a collection of data. You can use JavaScript’s `filter()` and `map()` with React to filter and transform your array of data into an array of components.

For each array item, you will need to specify a `key`. Usually, you will want to use an ID from the database as a `key`. Keys let React keep track of each item’s place in the list even if the list changes.

```
import { people } from './data.js';
import { getImageUrl } from './utils.js';

export default function List() {
  const listItems = people.map(person =>
    <li key={person.id}>
      <img
        src={getImageUrl(person)}
        alt={person.name}
      />
      <p>
        <b>{person.name}:</b>
        {' ' + person.profession + ' '}
        known for {person.accomplishment}
      </p>
    </li>
  );
  return (
    <article>
      <h1>Scientists</h1>
      <ul>{listItems}</ul>
    </article>
  );
}
```

## Ready to learn this topic?

Read **[Rendering Lists](/learn/rendering-lists)** to learn how to render a list of components, and how to choose a key.

[Read More](/learn/rendering-lists)

***

## Keeping components pure[](#keeping-components-pure "Link for Keeping components pure ")

Some JavaScript functions are *pure.* A pure function:

* **Minds its own business.** It does not change any objects or variables that existed before it was called.
* **Same inputs, same output.** Given the same inputs, a pure function should always return the same result.

By strictly only writing your components as pure functions, you can avoid an entire class of baffling bugs and unpredictable behavior as your codebase grows. Here is an example of an impure component:

```
let guest = 0;

function Cup() {
  // Bad: changing a preexisting variable!
  guest = guest + 1;
  return <h2>Tea cup for guest #{guest}</h2>;
}

export default function TeaSet() {
  return (
    <>
      <Cup />
      <Cup />
      <Cup />
    </>
  );
}
```

You can make this component pure by passing a prop instead of modifying a preexisting variable:

```
function Cup({ guest }) {
  return <h2>Tea cup for guest #{guest}</h2>;
}

export default function TeaSet() {
  return (
    <>
      <Cup guest={1} />
      <Cup guest={2} />
      <Cup guest={3} />
    </>
  );
}
```

## Ready to learn this topic?

Read **[Keeping Components Pure](/learn/keeping-components-pure)** to learn how to write components as pure, predictable functions.

[Read More](/learn/keeping-components-pure)

***

***

## What’s next?[](#whats-next "Link for What’s next? ")

Head over to [Your First Component](/learn/your-first-component) to start reading this chapter page by page!

Or, if you’re already familiar with these topics, why not read about [Adding Interactivity](/learn/adding-interactivity)?

[NextYour First Component](/learn/your-first-component)

***

----
url: https://18.react.dev/community/meetups
----

* [Montreal, QC - React Native](https://www.meetup.com/fr-FR/React-Native-MTL/)
* [Vancouver, BC](https://www.meetup.com/ReactJS-Vancouver-Meetup/)
* [Ottawa, ON](https://www.meetup.com/Ottawa-ReactJS-Meetup/)
* [Saskatoon, SK](https://www.meetup.com/saskatoon-react-meetup/)
* [Toronto, ON](https://www.meetup.com/Toronto-React-Native/events/)

## Colombia[](#colombia "Link for Colombia ")

* [Medellin](https://www.meetup.com/React-Medellin/)

* [React Native London](https://guild.host/RNLDN)

* [Ahmedabad](https://www.meetup.com/react-ahmedabad/)
* [Bangalore (React)](https://www.meetup.com/ReactJS-Bangalore/)
* [Bangalore (React Native)](https://www.meetup.com/React-Native-Bangalore-Meetup)
* [Chennai](https://www.linkedin.com/company/chennaireact)
* [Delhi NCR](https://www.meetup.com/React-Delhi-NCR/)
* [Mumbai](https://reactmumbai.dev)
* [Pune](https://www.meetup.com/ReactJS-and-Friends/)

* [Edinburgh](https://www.meetup.com/React-Scotland/)

## Spain[](#spain "Link for Spain ")

* [Barcelona](https://www.meetup.com/ReactJS-Barcelona/)

***

----
url: https://react.dev/learn/understanding-your-ui-as-a-tree
----

Trees are a relationship model between items. The UI is often represented using tree structures. For example, browsers use tree structures to model HTML ([DOM](https://developer.mozilla.org/docs/Web/API/Document_Object_Model/Introduction)) and CSS ([CSSOM](https://developer.mozilla.org/docs/Web/API/CSS_Object_Model)). Mobile platforms also use trees to represent their view hierarchy.

React creates a UI tree from your components. In this example, the UI tree is then used to render to the DOM.

Like browsers and mobile platforms, React also uses tree structures to manage and model the relationship between components in a React app. These trees are useful tools to understand how data flows through a React app and how to optimize rendering and app size.

## The Render Tree[](#the-render-tree "Link for The Render Tree ")

A major feature of components is the ability to compose components of other components. As we [nest components](/learn/your-first-component#nesting-and-organizing-components), we have the concept of parent and child components, where each parent component may itself be a child of another component.

When we render a React app, we can model this relationship in a tree, known as the render tree.

Here is a React app that renders inspirational quotes.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import FancyText from './FancyText';
import InspirationGenerator from './InspirationGenerator';
import Copyright from './Copyright';

export default function App() {
  return (
    <>
      <FancyText title text="Get Inspired App" />
      <InspirationGenerator>
        <Copyright year={2004} />
      </InspirationGenerator>
    </>
  );
}
```

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import FancyText from './FancyText';
import InspirationGenerator from './InspirationGenerator';
import Copyright from './Copyright';

export default function App() {
  return (
    <>
      <FancyText title text="Get Inspired App" />
      <InspirationGenerator>
        <Copyright year={2004} />
      </InspirationGenerator>
    </>
  );
}
```

***

----
url: https://react.dev/reference/react-dom/client/createRoot
----

[API Reference](/reference/react)

[Client APIs](/reference/react-dom/client)

# createRoot[](#undefined "Link for this heading")

`createRoot` lets you create a root to display React components inside a browser DOM node.

```
const root = createRoot(domNode, options?)
```

  * [Error logging in production](#error-logging-in-production)

* [Troubleshooting](#troubleshooting)

  * [I’ve created a root, but nothing is displayed](#ive-created-a-root-but-nothing-is-displayed)
  * [I’m getting an error: “You passed a second argument to root.render”](#im-getting-an-error-you-passed-a-second-argument-to-root-render)
  * [I’m getting an error: “Target container is not a DOM element”](#im-getting-an-error-target-container-is-not-a-dom-element)
  * [I’m getting an error: “Functions are not valid as a React child.”](#im-getting-an-error-functions-are-not-valid-as-a-react-child)
  * [My server-rendered HTML gets re-created from scratch](#my-server-rendered-html-gets-re-created-from-scratch)

***

## Reference[](#reference "Link for Reference ")

### `createRoot(domNode, options?)`[](#createroot "Link for this heading")

Call `createRoot` to create a React root for displaying content inside a browser DOM element.

```
import { createRoot } from 'react-dom/client';



const domNode = document.getElementById('root');

const root = createRoot(domNode);
```

React will create a root for the `domNode`, and take over managing the DOM inside it. After you’ve created a root, you need to call [`root.render`](#root-render) to display a React component inside of it:

```
root.render(<App />);
```

An app fully built with React will usually only have one `createRoot` call for its root component. A page that uses “sprinkles” of React for parts of the page may have as many separate roots as needed.

[See more examples below.](#usage)

#### Parameters[](#parameters "Link for Parameters ")

* `domNode`: A [DOM element.](https://developer.mozilla.org/en-US/docs/Web/API/Element) React will create a root for this DOM element and allow you to call functions on the root, such as `render` to display rendered React content.

* **optional** `options`: An object with options for this React root.

  * **optional** `onCaughtError`: Callback called when React catches an error in an Error Boundary. Called with the `error` caught by the Error Boundary, and an `errorInfo` object containing the `componentStack`.
  * **optional** `onUncaughtError`: Callback called when an error is thrown and not caught by an Error Boundary. Called with the `error` that was thrown, and an `errorInfo` object containing the `componentStack`.

***

### `root.render(reactNode)`[](#root-render "Link for this heading")

Call `root.render` to display a piece of [JSX](/learn/writing-markup-with-jsx) (“React node”) into the React root’s browser DOM node.

```
root.render(<App />);
```

* Although rendering is synchronous once it starts, `root.render(...)` is not. This means code after `root.render()` may run before any effects (`useLayoutEffect`, `useEffect`) of that specific render are fired. This is usually fine and rarely needs adjustment. In rare cases where effect timing matters, you can wrap `root.render(...)` in [`flushSync`](https://react.dev/reference/react-dom/flushSync) to ensure the initial render runs fully synchronously.

  ```
  const root = createRoot(document.getElementById('root'));

  root.render(<App />);

  // 🚩 The HTML will not include the rendered <App /> yet:

  console.log(document.body.innerHTML);
  ```

***

### `root.unmount()`[](#root-unmount "Link for this heading")

Call `root.unmount` to destroy a rendered tree inside a React root.

```
root.unmount();
```

***

## Usage[](#usage "Link for Usage ")

### Rendering an app fully built with React[](#rendering-an-app-fully-built-with-react "Link for Rendering an app fully built with React ")

If your app is fully built with React, create a single root for your entire app.

```
import { createRoot } from 'react-dom/client';



const root = createRoot(document.getElementById('root'));

root.render(<App />);
```

Usually, you only need to run this code once at startup. It will:

1. Find the browser DOM node defined in your HTML.
2. Display the React component for your app inside.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { createRoot } from 'react-dom/client';
import App from './App.js';
import './styles.css';

const root = createRoot(document.getElementById('root'));
root.render(<App />);
```

**If your app is fully built with React, you shouldn’t need to create any more roots, or to call [`root.render`](#root-render) again.**

From this point on, React will manage the DOM of your entire app. To add more components, [nest them inside the `App` component.](/learn/importing-and-exporting-components) When you need to update the UI, each of your components can do this by [using state.](/reference/react/useState) When you need to display extra content like a modal or a tooltip outside the DOM node, [render it with a portal.](/reference/react-dom/createPortal)

### Note

When your HTML is empty, the user sees a blank page until the app’s JavaScript code loads and runs:

```
<div id="root"></div>
```

This can feel very slow! To solve this, you can generate the initial HTML from your components [on the server or during the build.](/reference/react-dom/server) Then your visitors can read text, see images, and click links before any of the JavaScript code loads. We recommend [using a framework](/learn/creating-a-react-app#full-stack-frameworks) that does this optimization out of the box. Depending on when it runs, this is called *server-side rendering (SSR)* or *static site generation (SSG).*

### Pitfall

**Apps using server rendering or static generation must call [`hydrateRoot`](/reference/react-dom/client/hydrateRoot) instead of `createRoot`.** React will then *hydrate* (reuse) the DOM nodes from your HTML instead of destroying and re-creating them.

***

### Rendering a page partially built with React[](#rendering-a-page-partially-built-with-react "Link for Rendering a page partially built with React ")

If your page [isn’t fully built with React](/learn/add-react-to-an-existing-project#using-react-for-a-part-of-your-existing-page), you can call `createRoot` multiple times to create a root for each top-level piece of UI managed by React. You can display different content in each root by calling [`root.render`.](#root-render)

Here, two different React components are rendered into two DOM nodes defined in the `index.html` file:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import './styles.css';
import { createRoot } from 'react-dom/client';
import { Comments, Navigation } from './Components.js';

const navDomNode = document.getElementById('navigation');
const navRoot = createRoot(navDomNode);
navRoot.render(<Navigation />);

const commentDomNode = document.getElementById('comments');
const commentRoot = createRoot(commentDomNode);
commentRoot.render(<Comments />);
```

You could also create a new DOM node with [`document.createElement()`](https://developer.mozilla.org/en-US/docs/Web/API/Document/createElement) and add it to the document manually.

```
const domNode = document.createElement('div');

const root = createRoot(domNode);

root.render(<Comment />);

document.body.appendChild(domNode); // You can add it anywhere in the document
```

To remove the React tree from the DOM node and clean up all the resources used by it, call [`root.unmount`.](#root-unmount)

```
root.unmount();
```

This is mostly useful if your React components are inside an app written in a different framework.

***

### Updating a root component[](#updating-a-root-component "Link for Updating a root component ")

You can call `render` more than once on the same root. As long as the component tree structure matches up with what was previously rendered, React will [preserve the state.](/learn/preserving-and-resetting-state) Notice how you can type in the input, which means that the updates from repeated `render` calls every second in this example are not destructive:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { createRoot } from 'react-dom/client';
import './styles.css';
import App from './App.js';

const root = createRoot(document.getElementById('root'));

let i = 0;
setInterval(() => {
  root.render(<App counter={i} />);
  i++;
}, 1000);
```

It is uncommon to call `render` multiple times. Usually, your components will [update state](/reference/react/useState) instead.

### Error logging in production[](#error-logging-in-production "Link for Error logging in production ")

By default, React will log all errors to the console. To implement your own error reporting, you can provide the optional error handler root options `onUncaughtError`, `onCaughtError` and `onRecoverableError`:

```
import { createRoot } from "react-dom/client";

import { reportCaughtError } from "./reportError";



const container = document.getElementById("root");

const root = createRoot(container, {

  onCaughtError: (error, errorInfo) => {

    if (error.message !== "Known error") {

      reportCaughtError({

        error,

        componentStack: errorInfo.componentStack,

      });

    }

  },

});
```

The onCaughtError option is a function called with two arguments:

1. The error that was thrown.
2. An errorInfo object that contains the componentStack of the error.

Together with `onUncaughtError` and `onRecoverableError`, you can can implement your own error reporting system:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { createRoot } from "react-dom/client";
import App from "./App.js";
import {
  onCaughtErrorProd,
  onRecoverableErrorProd,
  onUncaughtErrorProd,
} from "./reportError";

const container = document.getElementById("root");
const root = createRoot(container, {
  // Keep in mind to remove these options in development to leverage
  // React's default handlers or implement your own overlay for development.
  // The handlers are only specfied unconditionally here for demonstration purposes.
  onCaughtError: onCaughtErrorProd,
  onRecoverableError: onRecoverableErrorProd,
  onUncaughtError: onUncaughtErrorProd,
});
root.render(<App />);
```

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### I’ve created a root, but nothing is displayed[](#ive-created-a-root-but-nothing-is-displayed "Link for I’ve created a root, but nothing is displayed ")

Make sure you haven’t forgotten to actually *render* your app into the root:

```
import { createRoot } from 'react-dom/client';

import App from './App.js';



const root = createRoot(document.getElementById('root'));

root.render(<App />);
```

Until you do that, nothing is displayed.

***

### I’m getting an error: “You passed a second argument to root.render”[](#im-getting-an-error-you-passed-a-second-argument-to-root-render "Link for I’m getting an error: “You passed a second argument to root.render” ")

A common mistake is to pass the options for `createRoot` to `root.render(...)`:

Console

Warning: You passed a second argument to root.render(…) but it only accepts one argument.

To fix, pass the root options to `createRoot(...)`, not `root.render(...)`:

```
// 🚩 Wrong: root.render only takes one argument.

root.render(App, {onUncaughtError});



// ✅ Correct: pass options to createRoot.

const root = createRoot(container, {onUncaughtError});

root.render(<App />);
```

***

### I’m getting an error: “Target container is not a DOM element”[](#im-getting-an-error-target-container-is-not-a-dom-element "Link for I’m getting an error: “Target container is not a DOM element” ")

This error means that whatever you’re passing to `createRoot` is not a DOM node.

If you’re not sure what’s happening, try logging it:

```
const domNode = document.getElementById('root');

console.log(domNode); // ???

const root = createRoot(domNode);

root.render(<App />);
```

For example, if `domNode` is `null`, it means that [`getElementById`](https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementById) returned `null`. This will happen if there is no node in the document with the given ID at the time of your call. There may be a few reasons for it:

1. The ID you’re looking for might differ from the ID you used in the HTML file. Check for typos!
2. Your bundle’s `<script>` tag cannot “see” any DOM nodes that appear *after* it in the HTML.

Another common way to get this error is to write `createRoot(<App />)` instead of `createRoot(domNode)`.

***

### I’m getting an error: “Functions are not valid as a React child.”[](#im-getting-an-error-functions-are-not-valid-as-a-react-child "Link for I’m getting an error: “Functions are not valid as a React child.” ")

This error means that whatever you’re passing to `root.render` is not a React component.

This may happen if you call `root.render` with `Component` instead of `<Component />`:

```
// 🚩 Wrong: App is a function, not a Component.

root.render(App);



// ✅ Correct: <App /> is a component.

root.render(<App />);
```

Or if you pass a function to `root.render`, instead of the result of calling it:

```
// 🚩 Wrong: createApp is a function, not a component.

root.render(createApp);



// ✅ Correct: call createApp to return a component.

root.render(createApp());
```

***

### My server-rendered HTML gets re-created from scratch[](#my-server-rendered-html-gets-re-created-from-scratch "Link for My server-rendered HTML gets re-created from scratch ")

If your app is server-rendered and includes the initial HTML generated by React, you might notice that creating a root and calling `root.render` deletes all that HTML, and then re-creates all the DOM nodes from scratch. This can be slower, resets focus and scroll positions, and may lose other user input.

Server-rendered apps must use [`hydrateRoot`](/reference/react-dom/client/hydrateRoot) instead of `createRoot`:

```
import { hydrateRoot } from 'react-dom/client';

import App from './App.js';



hydrateRoot(

  document.getElementById('root'),

  <App />

);
```

Note that its API is different. In particular, usually there will be no further `root.render` call.

[PreviousClient APIs](/reference/react-dom/client)

[NexthydrateRoot](/reference/react-dom/client/hydrateRoot)

***

----
url: https://18.react.dev/reference/react-dom/hooks/useFormStatus
----

[API Reference](/reference/react)

[Hooks](/reference/react-dom/hooks)

# useFormStatus[](#undefined "Link for this heading")

### Canary

The `useFormStatus` Hook is currently only available in React’s Canary and experimental channels. Learn more about [React’s release channels here](/community/versioning-policy#all-release-channels).

`useFormStatus` is a Hook that gives you status information of the last form submission.

```
const { pending, data, method, action } = useFormStatus();
```

***

## Reference[](#reference "Link for Reference ")

### `useFormStatus()`[](#use-form-status "Link for this heading")

The `useFormStatus` Hook provides status information of the last form submission.

```
import { useFormStatus } from "react-dom";

import action from './actions';



function Submit() {

  const status = useFormStatus();

  return <button disabled={status.pending}>Submit</button>

}



export default function App() {

  return (

    <form action={action}>

      <Submit />

    </form>

  );

}
```

***

## Usage[](#usage "Link for Usage ")

### Display a pending state during form submission[](#display-a-pending-state-during-form-submission "Link for Display a pending state during form submission ")

To display a pending state while a form is submitting, you can call the `useFormStatus` Hook in a component rendered in a `<form>` and read the `pending` property returned.

Here, we use the `pending` property to indicate the form is submitting.

```
import { useFormStatus } from "react-dom";
import { submitForm } from "./actions.js";

function Submit() {
  const { pending } = useFormStatus();
  return (
    <button type="submit" disabled={pending}>
      {pending ? "Submitting..." : "Submit"}
    </button>
  );
}

function Form({ action }) {
  return (
    <form action={action}>
      <Submit />
    </form>
  );
}

export default function App() {
  return <Form action={submitForm} />;
}
```

### Pitfall

##### `useFormStatus` will not return status information for a `<form>` rendered in the same component.[](#useformstatus-will-not-return-status-information-for-a-form-rendered-in-the-same-component "Link for this heading")

The `useFormStatus` Hook only returns status information for a parent `<form>` and not for any `<form>` rendered in the same component calling the Hook, or child components.

```
function Form() {

  // 🚩 `pending` will never be true

  // useFormStatus does not track the form rendered in this component

  const { pending } = useFormStatus();

  return <form action={submit}></form>;

}
```

Instead call `useFormStatus` from inside a component that is located inside `<form>`.

```
function Submit() {

  // ✅ `pending` will be derived from the form that wraps the Submit component

  const { pending } = useFormStatus(); 

  return <button disabled={pending}>...</button>;

}



function Form() {

  // This is the <form> `useFormStatus` tracks

  return (

    <form action={submit}>

      <Submit />

    </form>

  );

}
```

### Read the form data being submitted[](#read-form-data-being-submitted "Link for Read the form data being submitted ")

You can use the `data` property of the status information returned from `useFormStatus` to display what data is being submitted by the user.

Here, we have a form where users can request a username. We can use `useFormStatus` to display a temporary status message confirming what username they have requested.

```
import {useState, useMemo, useRef} from 'react';
import {useFormStatus} from 'react-dom';

export default function UsernameForm() {
  const {pending, data} = useFormStatus();

  return (
    <div>
      <h3>Request a Username: </h3>
      <input type="text" name="username" disabled={pending}/>
      <button type="submit" disabled={pending}>
        Submit
      </button>
      <br />
      <p>{data ? `Requesting ${data?.get("username")}...`: ''}</p>
    </div>
  );
}
```

***

***

----
url: https://legacy.reactjs.org/blog/2013/08/19/use-react-and-jsx-in-python-applications.html
----

August 19, 2013 by [Kunal Mehta](https://github.com/kmeht)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

Today we’re happy to announce the initial release of [PyReact](https://github.com/facebook/react-python), which makes it easier to use React and JSX in your Python applications. It’s designed to provide an API to transform your JSX files into JavaScript, as well as provide access to the latest React source files.

## [](#usage)Usage

Transform your JSX files via the provided `jsx` module:

```
from react import jsx

# For multiple paths, use the JSXTransformer class.
transformer = jsx.JSXTransformer()
for jsx_path, js_path in my_paths:
    transformer.transform(jsx_path, js_path)

# For a single file, you can use a shortcut method.
jsx.transform('path/to/input/file.jsx', 'path/to/output/file.js')
```

For full paths to React files, use the `source` module:

```
from react import source

# path_for raises IOError if the file doesn't exist.
react_js = source.path_for('react.min.js')
```

## [](#django)Django

PyReact includes a JSX compiler for [django-pipeline](https://github.com/cyberdelia/django-pipeline). Add it to your project’s pipeline settings like this:

```
PIPELINE_COMPILERS = (
  'react.utils.pipeline.JSXCompiler',
)
```

## [](#installation)Installation

PyReact is hosted on PyPI, and can be installed with `pip`:

```
$ pip install PyReact
```

Alternatively, add it into your `requirements` file:

```
PyReact==0.1.1
```

**Dependencies**: PyReact uses [PyExecJS](https://github.com/doloopwhile/PyExecJS) to execute the bundled React code, which requires that a JS runtime environment is installed on your machine. We don’t explicitly set a dependency on a runtime environment; Mac OS X comes bundled with one. If you’re on a different platform, we recommend [PyV8](https://code.google.com/p/pyv8/).

For the initial release, we’ve only tested on Python 2.7. Look out for support for Python 3 in the future, and if you see anything that can be improved, we welcome your [contributions](https://github.com/facebook/react-python/blob/master/CONTRIBUTING.md)!

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2013-08-19-use-react-and-jsx-in-python-applications.md)

----
url: https://react.dev/reference/react/lazy
----

[API Reference](/reference/react)

[APIs](/reference/react/apis)

# lazy[](#undefined "Link for this heading")

`lazy` lets you defer loading component’s code until it is rendered for the first time.

```
const SomeComponent = lazy(load)
```

***

## Reference[](#reference "Link for Reference ")

### `lazy(load)`[](#lazy "Link for this heading")

Call `lazy` outside your components to declare a lazy-loaded React component:

```
import { lazy } from 'react';



const MarkdownPreview = lazy(() => import('./MarkdownPreview.js'));
```

[See more examples below.](#usage)

#### Parameters[](#parameters "Link for Parameters ")

* `load`: A function that returns a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) or another *thenable* (a Promise-like object with a `then` method). React will not call `load` until the first time you attempt to render the returned component. After React first calls `load`, it will wait for it to resolve, and then render the resolved value’s `.default` as a React component. Both the returned Promise and the Promise’s resolved value will be cached, so React will not call `load` more than once. If the Promise rejects, React will `throw` the rejection reason for the nearest Error Boundary to handle.

#### Returns[](#returns "Link for Returns ")

`lazy` returns a React component you can render in your tree. While the code for the lazy component is still loading, attempting to render it will *suspend.* Use [`<Suspense>`](/reference/react/Suspense) to display a loading indicator while it’s loading.

***

### `load` function[](#load "Link for this heading")

#### Parameters[](#load-parameters "Link for Parameters ")

`load` receives no parameters.

#### Returns[](#load-returns "Link for Returns ")

You need to return a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) or some other *thenable* (a Promise-like object with a `then` method). It needs to eventually resolve to an object whose `.default` property is a valid React component type, such as a function, [`memo`](/reference/react/memo), or a [`forwardRef`](/reference/react/forwardRef) component.

***

## Usage[](#usage "Link for Usage ")

### Lazy-loading components with Suspense[](#suspense-for-code-splitting "Link for Lazy-loading components with Suspense ")

Usually, you import components with the static [`import`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import) declaration:

```
import MarkdownPreview from './MarkdownPreview.js';
```

To defer loading this component’s code until it’s rendered for the first time, replace this import with:

```
import { lazy } from 'react';



const MarkdownPreview = lazy(() => import('./MarkdownPreview.js'));
```

This code relies on [dynamic `import()`,](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import) which might require support from your bundler or framework. Using this pattern requires that the lazy component you’re importing was exported as the `default` export.

Now that your component’s code loads on demand, you also need to specify what should be displayed while it is loading. You can do this by wrapping the lazy component or any of its parents into a [`<Suspense>`](/reference/react/Suspense) boundary:

```
<Suspense fallback={<Loading />}>

  <h2>Preview</h2>

  <MarkdownPreview />

</Suspense>
```

In this example, the code for `MarkdownPreview` won’t be loaded until you attempt to render it. If `MarkdownPreview` hasn’t loaded yet, `Loading` will be shown in its place. Try ticking the checkbox:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, Suspense, lazy } from 'react';
import Loading from './Loading.js';

const MarkdownPreview = lazy(() => delayForDemo(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>
      )}
    </>
  );
}

// Add a fixed delay so you can see the loading state
function delayForDemo(promise) {
  return new Promise(resolve => {
    setTimeout(resolve, 2000);
  }).then(() => promise);
}
```

This demo loads with an artificial delay. The next time you untick and tick the checkbox, `Preview` will be cached, so there will be no loading state. To see the loading state again, click “Reset” on the sandbox.

[Learn more about managing loading states with Suspense.](/reference/react/Suspense)

***

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### My `lazy` component’s state gets reset unexpectedly[](#my-lazy-components-state-gets-reset-unexpectedly "Link for this heading")

Do not declare `lazy` components *inside* other components:

```
import { lazy } from 'react';



function Editor() {

  // 🔴 Bad: This will cause all state to be reset on re-renders

  const MarkdownPreview = lazy(() => import('./MarkdownPreview.js'));

  // ...

}
```

Instead, always declare them at the top level of your module:

```
import { lazy } from 'react';



// ✅ Good: Declare lazy components outside of your components

const MarkdownPreview = lazy(() => import('./MarkdownPreview.js'));



function Editor() {

  // ...

}
```

[PreviouscreateContext](/reference/react/createContext)

[Nextmemo](/reference/react/memo)

***

----
url: https://react.dev/reference/react-dom/prefetchDNS
----

[API Reference](/reference/react)

[APIs](/reference/react-dom)

# prefetchDNS[](#undefined "Link for this heading")

`prefetchDNS` lets you eagerly look up the IP of a server that you expect to load resources from.

```
prefetchDNS("https://example.com");
```

* [Reference](#reference)
  * [`prefetchDNS(href)`](#prefetchdns)

* [Usage](#usage)

  * [Prefetching DNS when rendering](#prefetching-dns-when-rendering)
  * [Prefetching DNS in an event handler](#prefetching-dns-in-an-event-handler)

***

## Reference[](#reference "Link for Reference ")

### `prefetchDNS(href)`[](#prefetchdns "Link for this heading")

To look up a host, call the `prefetchDNS` function from `react-dom`.

```
import { prefetchDNS } from 'react-dom';



function AppRoot() {

  prefetchDNS("https://example.com");

  // ...

}
```

***

## Usage[](#usage "Link for Usage ")

### Prefetching DNS when rendering[](#prefetching-dns-when-rendering "Link for Prefetching DNS when rendering ")

Call `prefetchDNS` when rendering a component if you know that its children will load external resources from that host.

```
import { prefetchDNS } from 'react-dom';



function AppRoot() {

  prefetchDNS("https://example.com");

  return ...;

}
```

### Prefetching DNS in an event handler[](#prefetching-dns-in-an-event-handler "Link for Prefetching DNS in an event handler ")

Call `prefetchDNS` in an event handler before transitioning to a page or state where external resources will be needed. This gets the process started earlier than if you call it during the rendering of the new page or state.

```
import { prefetchDNS } from 'react-dom';



function CallToAction() {

  const onClick = () => {

    prefetchDNS('http://example.com');

    startWizard();

  }

  return (

    <button onClick={onClick}>Start Wizard</button>

  );

}
```

[Previouspreconnect](/reference/react-dom/preconnect)

[Nextpreinit](/reference/react-dom/preinit)

***

----
url: https://react.dev/reference/eslint-plugin-react-hooks/lints/component-hook-factories
----

[API Reference](/reference/react)

[Lints](/reference/eslint-plugin-react-hooks)

# component-hook-factories[](#undefined "Link for this heading")

Validates against higher order functions defining nested components or hooks. Components and hooks should be defined at the module level.

## Rule Details[](#rule-details "Link for Rule Details ")

Defining components or hooks inside other functions creates new instances on every call. React treats each as a completely different component, destroying and recreating the entire component tree, losing all state, and causing performance problems.

### Invalid[](#invalid "Link for Invalid ")

Examples of incorrect code for this rule:

```
// ❌ Factory function creating components

function createComponent(defaultValue) {

  return function Component() {

    // ...

  };

}



// ❌ Component defined inside component

function Parent() {

  function Child() {

    // ...

  }



  return <Child />;

}



// ❌ Hook factory function

function createCustomHook(endpoint) {

  return function useData() {

    // ...

  };

}
```

### Valid[](#valid "Link for Valid ")

Examples of correct code for this rule:

```
// ✅ Component defined at module level

function Component({ defaultValue }) {

  // ...

}



// ✅ Custom hook at module level

function useData(endpoint) {

  // ...

}
```

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### I need dynamic component behavior[](#dynamic-behavior "Link for I need dynamic component behavior ")

You might think you need a factory to create customized components:

```
// ❌ Wrong: Factory pattern

function makeButton(color) {

  return function Button({children}) {

    return (

      <button style={{backgroundColor: color}}>

        {children}

      </button>

    );

  };

}



const RedButton = makeButton('red');

const BlueButton = makeButton('blue');
```

Pass [JSX as children](/learn/passing-props-to-a-component#passing-jsx-as-children) instead:

```
// ✅ Better: Pass JSX as children

function Button({color, children}) {

  return (

    <button style={{backgroundColor: color}}>

      {children}

    </button>

  );

}



function App() {

  return (

    <>

      <Button color="red">Red</Button>

      <Button color="blue">Blue</Button>

    </>

  );

}
```

[Previousrules-of-hooks](/reference/eslint-plugin-react-hooks/lints/rules-of-hooks)

[Nextconfig](/reference/eslint-plugin-react-hooks/lints/config)

***

----
url: https://react.dev/blog/2025/04/23/react-labs-view-transitions-activity-and-more
----

[Blog](/blog)

# React Labs: View Transitions, Activity, and more[](#undefined "Link for this heading")

April 23, 2025 by [Ricky Hanlon](https://twitter.com/rickhanlonii)

***

In React Labs posts, we write about projects in active research and development. In this post, we’re sharing two new experimental features that are ready to try today, and updates on other areas we’re working on now.

Today, we’re excited to release documentation for two new experimental features that are ready for testing:

* [View Transitions](#view-transitions)
* [Activity](#activity)

We’re also sharing updates on new features currently in development:

* [React Performance Tracks](#react-performance-tracks)
* [Compiler IDE Extension](#compiler-ide-extension)
* [Automatic Effect Dependencies](#automatic-effect-dependencies)
* [Fragment Refs](#fragment-refs)
* [Concurrent Stores](#concurrent-stores)

***

# New Experimental Features[](#new-experimental-features "Link for New Experimental Features ")

### Note

`<Activity />` has shipped in `react@19.2`.

`<ViewTransition />` and `addTransitionType` are now available in `react@canary`.

View Transitions and Activity are now ready for testing in `react@experimental`. These features have been tested in production and are stable, but the final API may still change as we incorporate feedback.

You can try them by upgrading React packages to the most recent experimental version:

* `react@experimental`
* `react-dom@experimental`

Read on to learn how to use these features in your app, or check out the newly published docs:

* [`<ViewTransition>`](/reference/react/ViewTransition): A component that lets you activate an animation for a Transition.
* [`addTransitionType`](/reference/react/addTransitionType): A function that allows you to specify the cause of a Transition.
* [`<Activity>`](/reference/react/Activity): A component that lets you hide and show parts of the UI.

## View Transitions[](#view-transitions "Link for View Transitions ")

React View Transitions are a new experimental feature that makes it easier to add animations to UI transitions in your app. Under-the-hood, these animations use the new [`startViewTransition`](https://developer.mozilla.org/en-US/docs/Web/API/Document/startViewTransition) API available in most modern browsers.

To opt-in to animating an element, wrap it in the new `<ViewTransition>` component:

```
// "what" to animate.

<ViewTransition>

  <div>animate me</div>

</ViewTransition>
```

This new component lets you declaratively define “what” to animate when an animation is activated.

You can define “when” to animate by using one of these three triggers for a View Transition:

```
// "when" to animate.



// Transitions

startTransition(() => setState(...));



// Deferred Values

const deferred = useDeferredValue(value);



// Suspense

<Suspense fallback={<Fallback />}>

  <div>Loading...</div>

</Suspense>
```

By default, these animations use the [default CSS animations for View Transitions](https://developer.mozilla.org/en-US/docs/Web/API/View_Transition_API/Using#customizing_your_animations) applied (typically a smooth cross-fade). You can use [view transition pseudo-selectors](https://developer.mozilla.org/en-US/docs/Web/API/View_Transition_API/Using#the_view_transition_pseudo-element_tree) to define “how” the animation runs. For example, you can use `*` to change the default animation for all transitions:

```
// "how" to animate.

::view-transition-old(*) {

  animation: 300ms ease-out fade-out;

}

::view-transition-new(*) {

  animation: 300ms ease-in fade-in;

}
```

When the DOM updates due to an animation trigger—like `startTransition`, `useDeferredValue`, or a `Suspense` fallback switching to content—React will use [declarative heuristics](/reference/react/ViewTransition#viewtransition) to automatically determine which `<ViewTransition>` components to activate for the animation. The browser will then run the animation that’s defined in CSS.

If you’re familiar with the browser’s View Transition API and want to know how React supports it, check out [How does `<ViewTransition>` Work](/reference/react/ViewTransition#how-does-viewtransition-work) in the docs.

In this post, let’s take a look at a few examples of how to use View Transitions.

We’ll start with this app, which doesn’t animate any of the following interactions:

* Click a video to view the details.
* Click “back” to go back to the feed.
* Type in the list to filter the videos.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import TalkDetails from './Details'; import Home from './Home'; import {useRouter} from './router';

export default function App() {
  const {url} = useRouter();

  // 🚩This version doesn't include any animations yet
  return url === '/' ? <Home /> : <TalkDetails />;
}
```

### Note

#### View Transitions do not replace CSS and JS driven animations[](#view-transitions-do-not-replace-css-and-js-driven-animations "Link for View Transitions do not replace CSS and JS driven animations ")

View Transitions are meant to be used for UI transitions such as navigation, expanding, opening, or re-ordering. They are not meant to replace all the animations in your app.

In our example app above, notice that there are already animations when you click the “like” button and in the Suspense fallback glimmer. These are good use cases for CSS animations because they are animating a specific element.

### Animating navigations[](#animating-navigations "Link for Animating navigations ")

Our app includes a Suspense-enabled router, with [page transitions already marked as Transitions](/reference/react/useTransition#building-a-suspense-enabled-router), which means navigations are performed with `startTransition`:

```
function navigate(url) {

  startTransition(() => {

    go(url);

  });

}
```

`startTransition` is a View Transition trigger, so we can add `<ViewTransition>` to animate between pages:

```
// "what" to animate

<ViewTransition key={url}>

  {url === '/' ? <Home /> : <TalkDetails />}

</ViewTransition>
```

When the `url` changes, the `<ViewTransition>` and new route are rendered. Since the `<ViewTransition>` was updated inside of `startTransition`, the `<ViewTransition>` is activated for an animation.

By default, View Transitions include the browser default cross-fade animation. Adding this to our example, we now have a cross-fade whenever we navigate between pages:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import {ViewTransition} from 'react'; import Details from './Details';
import Home from './Home'; import {useRouter} from './router';

export default function App() {
  const {url} = useRouter();

  // Use ViewTransition to animate between pages.
  // No additional CSS needed by default.
  return (
    <ViewTransition>
      {url === '/' ? <Home /> : <Details />}
    </ViewTransition>
  );
}
```

Since our router already updates the route using `startTransition`, this one line change to add `<ViewTransition>` activates with the default cross-fade animation.

If you’re curious how this works, see the docs for [How does `<ViewTransition>` work?](/reference/react/ViewTransition#how-does-viewtransition-work)

### Note

#### Opting out of `<ViewTransition>` animations[](#opting-out-of-viewtransition-animations "Link for this heading")

In this example, we’re wrapping the root of the app in `<ViewTransition>` for simplicity, but this means that all transitions in the app will be animated, which can lead to unexpected animations.

To fix, we’re wrapping route children with `"none"` so each page can control its own animation:

```
// Layout.js

<ViewTransition default="none">

  {children}

</ViewTransition>
```

In practice, navigations should be done via “enter” and “exit” props, or by using Transition Types.

### Customizing animations[](#customizing-animations "Link for Customizing animations ")

By default, `<ViewTransition>` includes the default cross-fade from the browser.

To customize animations, you can provide props to the `<ViewTransition>` component to specify which animations to use, based on [how the `<ViewTransition>` activates](/reference/react/ViewTransition#props).

For example, we can slow down the `default` cross fade animation:

```
<ViewTransition default="slow-fade">

  <Home />

</ViewTransition>
```

And define `slow-fade` in CSS using [view transition classes](/reference/react/ViewTransition#view-transition-class):

```
::view-transition-old(.slow-fade) {

    animation-duration: 500ms;

}



::view-transition-new(.slow-fade) {

    animation-duration: 500ms;

}
```

Now, the cross fade is slower:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { ViewTransition } from "react";
import Details from "./Details";
import Home from "./Home";
import { useRouter } from "./router";

export default function App() {
  const { url } = useRouter();

  // Define a default animation of .slow-fade.
  // See animations.css for the animation definition.
  return (
    <ViewTransition default="slow-fade">
      {url === '/' ? <Home /> : <Details />}
    </ViewTransition>
  );
}
```

See [Styling View Transitions](/reference/react/ViewTransition#styling-view-transitions) for a full guide on styling `<ViewTransition>`.

### Shared Element Transitions[](#shared-element-transitions "Link for Shared Element Transitions ")

When two pages include the same element, often you want to animate it from one page to the next.

To do this you can add a unique `name` to the `<ViewTransition>`:

```
<ViewTransition name={`video-${video.id}`}>

  <Thumbnail video={video} />

</ViewTransition>
```

Now the video thumbnail animates between the two pages:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, ViewTransition } from "react"; import LikeButton from "./LikeButton"; import { useRouter } from "./router"; import { PauseIcon, PlayIcon } from "./Icons"; import { startTransition } from "react";

export function Thumbnail({ video, children }) {
  // Add a name to animate with a shared element transition.
  // This uses the default animation, no additional css needed.
  return (
    <ViewTransition name={`video-${video.id}`}>
      <div
        aria-hidden="true"
        tabIndex={-1}
        className={`thumbnail ${video.image}`}
      >
        {children}
      </div>
    </ViewTransition>
  );
}

export function VideoControls() {
  const [isPlaying, setIsPlaying] = useState(false);

  return (
    <span
      className="controls"
      onClick={() =>
        startTransition(() => {
          setIsPlaying((p) => !p);
        })
      }
    >
      {isPlaying ? <PauseIcon /> : <PlayIcon />}
    </span>
  );
}

export function Video({ video }) {
  const { navigate } = useRouter();

  return (
    <div className="video">
      <div
        className="link"
        onClick={(e) => {
          e.preventDefault();
          navigate(`/video/${video.id}`);
        }}
      >
        <Thumbnail video={video}></Thumbnail>

        <div className="info">
          <div className="video-title">{video.title}</div>
          <div className="video-description">{video.description}</div>
        </div>
      </div>
      <LikeButton video={video} />
    </div>
  );
}
```

By default, React automatically generates a unique `name` for each element activated for a transition (see [How does `<ViewTransition>` work](/reference/react/ViewTransition#how-does-viewtransition-work)). When React sees a transition where a `<ViewTransition>` with a `name` is removed and a new `<ViewTransition>` with the same `name` is added, it will activate a shared element transition.

For more info, see the docs for [Animating a Shared Element](/reference/react/ViewTransition#animating-a-shared-element).

### Animating based on cause[](#animating-based-on-cause "Link for Animating based on cause ")

Sometimes, you may want elements to animate differently based on how it was triggered. For this use case, we’ve added a new API called `addTransitionType` to specify the cause of a transition:

```
function navigate(url) {

  startTransition(() => {

    // Transition type for the cause "nav forward"

    addTransitionType('nav-forward');

    go(url);

  });

}

function navigateBack(url) {

  startTransition(() => {

    // Transition type for the cause "nav backward"

    addTransitionType('nav-back');

    go(url);

  });

}
```

With transition types, you can provide custom animations via props to `<ViewTransition>`. Let’s add a shared element transition to the header for “6 Videos” and “Back”:

```
<ViewTransition

  name="nav"

  share={{

    'nav-forward': 'slide-forward',

    'nav-back': 'slide-back',

  }}>

  {heading}

</ViewTransition>
```

Here we pass a `share` prop to define how to animate based on the transition type. When the share transition activates from `nav-forward`, the view transition class `slide-forward` is applied. When it’s from `nav-back`, the `slide-back` animation is activated. Let’s define these animations in CSS:

```
::view-transition-old(.slide-forward) {

    /* when sliding forward, the "old" page should slide out to left. */

    animation: ...

}



::view-transition-new(.slide-forward) {

    /* when sliding forward, the "new" page should slide in from right. */

    animation: ...

}



::view-transition-old(.slide-back) {

    /* when sliding back, the "old" page should slide out to right. */

    animation: ...

}



::view-transition-new(.slide-back) {

    /* when sliding back, the "new" page should slide in from left. */

    animation: ...

}
```

Now we can animate the header along with thumbnail based on navigation type:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import {ViewTransition} from 'react'; import { useIsNavPending } from "./router";

export default function Page({ heading, children }) {
  const isPending = useIsNavPending();
  return (
    <div className="page">
      <div className="top">
        <div className="top-nav">
          {/* Custom classes based on transition type. */}
          <ViewTransition
            name="nav"
            share={{
              'nav-forward': 'slide-forward',
              'nav-back': 'slide-back',
            }}>
            {heading}
          </ViewTransition>
          {isPending && <span className="loader"></span>}
        </div>
      </div>
      {/* Opt-out of ViewTransition for the content. */}
      {/* Content can define it's own ViewTransition. */}
      <ViewTransition default="none">
        <div className="bottom">
          <div className="content">{children}</div>
        </div>
      </ViewTransition>
    </div>
  );
}
```

### Animating Suspense Boundaries[](#animating-suspense-boundaries "Link for Animating Suspense Boundaries ")

Suspense will also activate View Transitions.

To animate the fallback to content, we can wrap `Suspense` with `<ViewTranstion>`:

```
<ViewTransition>

  <Suspense fallback={<VideoInfoFallback />}>

    <VideoInfo />

  </Suspense>

</ViewTransition>
```

By adding this, the fallback will cross-fade into the content. Click a video and see the video info animate in:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { use, Suspense, ViewTransition } from "react"; import { fetchVideo, fetchVideoDetails } from "./data"; import { Thumbnail, VideoControls } from "./Videos"; import { useRouter } from "./router"; import Layout from "./Layout"; import { ChevronLeft } from "./Icons";

function VideoDetails({ id }) {
  // Cross-fade the fallback to content.
  return (
    <ViewTransition default="slow-fade">
      <Suspense fallback={<VideoInfoFallback />}>
          <VideoInfo id={id} />
      </Suspense>
    </ViewTransition>
  );
}

function VideoInfoFallback() {
  return (
    <div>
      <div className="fit fallback title"></div>
      <div className="fit fallback description"></div>
    </div>
  );
}

export default function Details() {
  const { url, navigateBack } = useRouter();
  const videoId = url.split("/").pop();
  const video = use(fetchVideo(videoId));

  return (
    <Layout
      heading={
        <div
          className="fit back"
          onClick={() => {
            navigateBack("/");
          }}
        >
          <ChevronLeft /> Back
        </div>
      }
    >
      <div className="details">
        <Thumbnail video={video} large>
          <VideoControls />
        </Thumbnail>
        <VideoDetails id={video.id} />
      </div>
    </Layout>
  );
}

function VideoInfo({ id }) {
  const details = use(fetchVideoDetails(id));
  return (
    <div>
      <p className="fit info-title">{details.title}</p>
      <p className="fit info-description">{details.description}</p>
    </div>
  );
}
```

We can also provide custom animations using an `exit` on the fallback, and `enter` on the content:

```
<Suspense

  fallback={

    <ViewTransition exit="slide-down">

      <VideoInfoFallback />

    </ViewTransition>

  }

>

  <ViewTransition enter="slide-up">

    <VideoInfo id={id} />

  </ViewTransition>

</Suspense>
```

Here’s how we’ll define `slide-down` and `slide-up` with CSS:

```
::view-transition-old(.slide-down) {

  /* Slide the fallback down */

  animation: ...;

}



::view-transition-new(.slide-up) {

  /* Slide the content up */

  animation: ...;

}
```

Now, the Suspense content replaces the fallback with a sliding animation:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { use, Suspense, ViewTransition } from "react"; import { fetchVideo, fetchVideoDetails } from "./data"; import { Thumbnail, VideoControls } from "./Videos"; import { useRouter } from "./router"; import Layout from "./Layout"; import { ChevronLeft } from "./Icons";

function VideoDetails({ id }) {
  return (
    <Suspense
      fallback={
        // Animate the fallback down.
        <ViewTransition exit="slide-down">
          <VideoInfoFallback />
        </ViewTransition>
      }
    >
      {/* Animate the content up */}
      <ViewTransition enter="slide-up">
        <VideoInfo id={id} />
      </ViewTransition>
    </Suspense>
  );
}

function VideoInfoFallback() {
  return (
    <>
      <div className="fallback title"></div>
      <div className="fallback description"></div>
    </>
  );
}

export default function Details() {
  const { url, navigateBack } = useRouter();
  const videoId = url.split("/").pop();
  const video = use(fetchVideo(videoId));

  return (
    <Layout
      heading={
        <div
          className="fit back"
          onClick={() => {
            navigateBack("/");
          }}
        >
          <ChevronLeft /> Back
        </div>
      }
    >
      <div className="details">
        <Thumbnail video={video} large>
          <VideoControls />
        </Thumbnail>
        <VideoDetails id={video.id} />
      </div>
    </Layout>
  );
}

function VideoInfo({ id }) {
  const details = use(fetchVideoDetails(id));
  return (
    <>
      <p className="info-title">{details.title}</p>
      <p className="info-description">{details.description}</p>
    </>
  );
}
```

### Animating Lists[](#animating-lists "Link for Animating Lists ")

You can also use `<ViewTransition>` to animate lists of items as they re-order, like in a searchable list of items:

```
<div className="videos">

  {filteredVideos.map((video) => (

    <ViewTransition key={video.id}>

      <Video video={video} />

    </ViewTransition>

  ))}

</div>
```

To activate the ViewTransition, we can use `useDeferredValue`:

```
const [searchText, setSearchText] = useState('');

const deferredSearchText = useDeferredValue(searchText);

const filteredVideos = filterVideos(videos, deferredSearchText);
```

Now the items animate as you type in the search bar:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useId, useState, use, useDeferredValue, ViewTransition } from "react";import { Video } from "./Videos";import Layout from "./Layout";import { fetchVideos } from "./data";import { IconSearch } from "./Icons";

function SearchList({searchText, videos}) {
  // Activate with useDeferredValue ("when")
  const deferredSearchText = useDeferredValue(searchText);
  const filteredVideos = filterVideos(videos, deferredSearchText);
  return (
    <div className="video-list">
      <div className="videos">
        {filteredVideos.map((video) => (
          // Animate each item in list ("what")
          <ViewTransition key={video.id}>
            <Video video={video} />
          </ViewTransition>
        ))}
      </div>
      {filteredVideos.length === 0 && (
        <div className="no-results">No results</div>
      )}
    </div>
  );
}

export default function Home() {
  const videos = use(fetchVideos());
  const count = videos.length;
  const [searchText, setSearchText] = useState('');

  return (
    <Layout heading={<div className="fit">{count} Videos</div>}>
      <SearchInput value={searchText} onChange={setSearchText} />
      <SearchList videos={videos} searchText={searchText} />
    </Layout>
  );
}

function SearchInput({ value, onChange }) {
  const id = useId();
  return (
    <form className="search" onSubmit={(e) => e.preventDefault()}>
      <label htmlFor={id} className="sr-only">
        Search
      </label>
      <div className="search-input">
        <div className="search-icon">
          <IconSearch />
        </div>
        <input
          type="text"
          id={id}
          placeholder="Search"
          value={value}
          onChange={(e) => onChange(e.target.value)}
        />
      </div>
    </form>
  );
}

function filterVideos(videos, query) {
  const keywords = query
    .toLowerCase()
    .split(" ")
    .filter((s) => s !== "");
  if (keywords.length === 0) {
    return videos;
  }
  return videos.filter((video) => {
    const words = (video.title + " " + video.description)
      .toLowerCase()
      .split(" ");
    return keywords.every((kw) => words.some((w) => w.includes(kw)));
  });
}
```

### Final result[](#final-result "Link for Final result ")

By adding a few `<ViewTransition>` components and a few lines of CSS, we were able to add all the animations above into the final result.

We’re excited about View Transitions and think they will level up the apps you’re able to build. They’re ready to start trying today in the experimental channel of React releases.

Let’s remove the slow fade, and take a look at the final result:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import {ViewTransition} from 'react'; import Details from './Details'; import Home from './Home'; import {useRouter} from './router';

export default function App() {
  const {url} = useRouter();

  // Animate with a cross fade between pages.
  return (
    <ViewTransition key={url}>
      {url === '/' ? <Home /> : <Details />}
    </ViewTransition>
  );
}
```

If you’re curious to know more about how they work, check out [How Does `<ViewTransition>` Work](/reference/react/ViewTransition#how-does-viewtransition-work) in the docs.

*For more background on how we built View Transitions, see: [#31975](https://github.com/facebook/react/pull/31975), [#32105](https://github.com/facebook/react/pull/32105), [#32041](https://github.com/facebook/react/pull/32041), [#32734](https://github.com/facebook/react/pull/32734), [#32797](https://github.com/facebook/react/pull/32797) [#31999](https://github.com/facebook/react/pull/31999), [#32031](https://github.com/facebook/react/pull/32031), [#32050](https://github.com/facebook/react/pull/32050), [#32820](https://github.com/facebook/react/pull/32820), [#32029](https://github.com/facebook/react/pull/32029), [#32028](https://github.com/facebook/react/pull/32028), and [#32038](https://github.com/facebook/react/pull/32038) by [@sebmarkbage](https://twitter.com/sebmarkbage) (thanks Seb!).*

***

## Activity[](#activity "Link for Activity ")

### Note

**`<Activity />` is now available in React’s Canary channel.**

[Learn more about React’s release channels here.](/community/versioning-policy#all-release-channels)

In [past](/blog/2022/06/15/react-labs-what-we-have-been-working-on-june-2022#offscreen) [updates](/blog/2024/02/15/react-labs-what-we-have-been-working-on-february-2024#offscreen-renamed-to-activity), we shared that we were researching an API to allow components to be visually hidden and deprioritized, preserving UI state with reduced performance costs relative to unmounting or hiding with CSS.

We’re now ready to share the API and how it works, so you can start testing it in experimental React versions.

`<Activity>` is a new component to hide and show parts of the UI:

```
<Activity mode={isVisible ? 'visible' : 'hidden'}>

  <Page />

</Activity>
```

When an Activity is visible it’s rendered as normal. When an Activity is hidden it is unmounted, but will save its state and continue to render at a lower priority than anything visible on screen.

You can use `Activity` to save state for parts of the UI the user isn’t using, or pre-render parts that a user is likely to use next.

Let’s look at some examples improving the View Transition examples above.

### Note

**Effects don’t mount when an Activity is hidden.**

When an `<Activity>` is `hidden`, Effects are unmounted. Conceptually, the component is unmounted, but React saves the state for later.

In practice, this works as expected if you have followed the [You Might Not Need an Effect](/learn/you-might-not-need-an-effect) guide. To eagerly find problematic Effects, we recommend adding [`<StrictMode>`](/reference/react/StrictMode) which will eagerly perform Activity unmounts and mounts to catch any unexpected side effects.

### Restoring state with Activity[](#restoring-state-with-activity "Link for Restoring state with Activity ")

When a user navigates away from a page, it’s common to stop rendering the old page:

```
function App() {

  const { url } = useRouter();



  return (

    <>

      {url === '/' && <Home />}

      {url !== '/' && <Details />}

    </>

  );

}
```

However, this means if the user goes back to the old page, all of the previous state is lost. For example, if the `<Home />` page has an `<input>` field, when the user leaves the page the `<input>` is unmounted, and all of the text they had typed is lost.

Activity allows you to keep the state around as the user changes pages, so when they come back they can resume where they left off. This is done by wrapping part of the tree in `<Activity>` and toggling the `mode`:

```
function App() {

  const { url } = useRouter();



  return (

    <>

      <Activity mode={url === '/' ? 'visible' : 'hidden'}>

        <Home />

      </Activity>

      {url !== '/' && <Details />}

    </>

  );

}
```

With this change, we can improve on our View Transitions example above. Before, when you searched for a video, selected one, and returned, your search filter was lost. With Activity, your search filter is restored and you can pick up where you left off.

Try searching for a video, selecting it, and clicking “back”:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { Activity, ViewTransition } from "react"; import Details from "./Details"; import Home from "./Home"; import { useRouter } from "./router";

export default function App() {
  const { url } = useRouter();

  return (
    // View Transitions know about Activity
    <ViewTransition>
      {/* Render Home in Activity so we don't lose state */}
      <Activity mode={url === '/' ? 'visible' : 'hidden'}>
        <Home />
      </Activity>
      {url !== '/' && <Details />}
    </ViewTransition>
  );
}
```

### Pre-rendering with Activity[](#prerender-with-activity "Link for Pre-rendering with Activity ")

Sometimes, you may want to prepare the next part of the UI a user is likely to use ahead of time, so it’s ready by the time they are ready to use it. This is especially useful if the next route needs to suspend on data it needs to render, because you can help ensure the data is already fetched before the user navigates.

For example, our app currently needs to suspend to load the data for each video when you select one. We can improve this by rendering all of the pages in a hidden `<Activity>` until the user navigates:

```
<ViewTransition>

  <Activity mode={url === '/' ? 'visible' : 'hidden'}>

    <Home />

  </Activity>

  <Activity mode={url === '/details/1' ? 'visible' : 'hidden'}>

    <Details id={id} />

  </Activity>

  <Activity mode={url === '/details/1' ? 'visible' : 'hidden'}>

    <Details id={id} />

  </Activity>

<ViewTransition>
```

With this update, if the content on the next page has time to pre-render, it will animate in without the Suspense fallback. Click a video, and notice that the video title and description on the Details page render immediately, without a fallback:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { Activity, ViewTransition, use } from "react"; import Details from "./Details"; import Home from "./Home"; import { useRouter } from "./router"; import {fetchVideos} from './data';

export default function App() {
  const { url } = useRouter();
  const videoId = url.split("/").pop();
  const videos = use(fetchVideos());

  return (
    <ViewTransition>
      {/* Render videos in Activity to pre-render them */}
      {videos.map(({id}) => (
        <Activity key={id} mode={videoId === id ? 'visible' : 'hidden'}>
          <Details id={id}/>
        </Activity>
      ))}
      <Activity mode={url === '/' ? 'visible' : 'hidden'}>
        <Home />
      </Activity>
    </ViewTransition>
  );
}
```

### Server-Side Rendering with Activity[](#server-side-rendering-with-activity "Link for Server-Side Rendering with Activity ")

When using Activity on a page that uses server-side rendering (SSR), there are additional optimizations.

If part of the page is rendered with `mode="hidden"`, then it will not be included in the SSR response. Instead, React will schedule a client render for the content inside Activity while the rest of the page hydrates, prioritizing the visible content on screen.

For parts of the UI rendered with `mode="visible"`, React will de-prioritize hydration of content within Activity, similar to how Suspense content is hydrated at a lower priority. If the user interacts with the page, we’ll prioritize hydration within the boundary if needed.

These are advanced use cases, but they show the additional benefits considered with Activity.

### Future modes for Activity[](#future-modes-for-activity "Link for Future modes for Activity ")

In the future, we may add more modes to Activity.

For example, a common use case is rendering a modal, where the previous “inactive” page is visible behind the “active” modal view. The “hidden” mode does not work for this use case because it’s not visible and not included in SSR.

Instead, we’re considering a new mode that would keep the content visible—and included in SSR—but keep it unmounted and de-prioritize updates. This mode may also need to “pause” DOM updates, since it can be distracting to see backgrounded content updating while a modal is open.

Another mode we’re considering for Activity is the ability to automatically destroy state for hidden Activities if there is too much memory being used. Since the component is already unmounted, it may be preferable to destroy state for the least recently used hidden parts of the app rather than consume too many resources.

These are areas we’re still exploring, and we’ll share more as we make progress. For more information on what Activity includes today, [check out the docs](/reference/react/Activity).

***

# Features in development[](#features-in-development "Link for Features in development ")

We’re also developing features to help solve the common problems below.

As we iterate on possible solutions, you may see some potential APIs we’re testing being shared based on the PRs we are landing. Please keep in mind that as we try different ideas, we often change or remove different solutions after trying them out.

When the solutions we’re working on are shared too early, it can create churn and confusion in the community. To balance being transparent and limiting confusion, we’re sharing the problems we’re currently developing solutions for, without sharing a particular solution we have in mind.

As these features progress, we’ll announce them on the blog with docs included so you can try them out.

## React Performance Tracks[](#react-performance-tracks "Link for React Performance Tracks ")

We’re working on a new set of custom tracks to performance profilers using browser APIs that [allow adding custom tracks](https://developer.chrome.com/docs/devtools/performance/extension) to provide more information about the performance of your React app.

This feature is still in progress, so we’re not ready to publish docs to fully release it as an experimental feature yet. You can get a sneak preview when using an experimental version of React, which will automatically add the performance tracks to profiles:

There are a few known issues we plan to address such as performance, and the scheduler track not always “connecting” work across Suspended trees, so it’s not quite ready to try. We’re also still collecting feedback from early adopters to improve the design and usability of the tracks.

Once we solve those issues, we’ll publish experimental docs and share that it’s ready to try.

***

## Automatic Effect Dependencies[](#automatic-effect-dependencies "Link for Automatic Effect Dependencies ")

When we released hooks, we had three motivations:

* **Sharing code between components**: hooks replaced patterns like render props and higher-order components to allow you to reuse stateful logic without changing your component hierarchy.
* **Think in terms of function, not lifecycles**: hooks let you split one component into smaller functions based on what pieces are related (such as setting up a subscription or fetching data), rather than forcing a split based on lifecycle methods.
* **Support ahead-of-time compilation**: hooks were designed to support ahead-of-time compilation with less pitfalls causing unintentional de-optimizations caused by lifecycle methods, and limitations of classes.

Since their release, hooks have been successful at *sharing code between components*. Hooks are now the favored way to share logic between components, and there are less use cases for render props and higher order components. Hooks have also been successful at supporting features like Fast Refresh that were not possible with class components.

### Effects can be hard[](#effects-can-be-hard "Link for Effects can be hard ")

Unfortunately, some hooks are still hard to think in terms of function instead of lifecycles. Effects specifically are still hard to understand and are the most common pain point we hear from developers. Last year, we spent a significant amount of time researching how Effects were used, and how those use cases could be simplified and easier to understand.

We found that often, the confusion is from using an Effect when you don’t need to. The [You Might Not Need an Effect](/learn/you-might-not-need-an-effect) guide covers many cases for when Effects are not the right solution. However, even when an Effect is the right fit for a problem, Effects can still be harder to understand than class component lifecycles.

We believe one of the reasons for confusion is that developers to think of Effects from the *component’s* perspective (like a lifecycle), instead of the *Effects* point of view (what the Effect does).

Let’s look at an example [from the docs](/learn/lifecycle-of-reactive-effects#thinking-from-the-effects-perspective):

```
useEffect(() => {

  // Your Effect connected to the room specified with roomId...

  const connection = createConnection(serverUrl, roomId);

  connection.connect();

  return () => {

    // ...until it disconnected

    connection.disconnect();

  };

}, [roomId]);
```

Many users would read this code as “on mount, connect to the roomId. whenever `roomId` changes, disconnect to the old room and re-create the connection”. However, this is thinking from the component’s lifecycle perspective, which means you will need to think of every component lifecycle state to write the Effect correctly. This can be difficult, so it’s understandable that Effects seem harder than class lifecycles when using the component perspective.

### Effects without dependencies[](#effects-without-dependencies "Link for Effects without dependencies ")

Instead, it’s better to think from the Effect’s perspective. The Effect doesn’t know about the component lifecycles. It only describes how to start synchronization and how to stop it. When users think of Effects in this way, their Effects tend to be easier to write, and more resilient to being started and stopped as many times as is needed.

We spent some time researching why Effects are thought of from the component perspective, and we think one of the reasons is the dependency array. Since you have to write it, it’s right there and in your face reminding you of what you’re “reacting” to and baiting you into the mental model of ‘do this when these values change’.

When we released hooks, we knew we could make them easier to use with ahead-of-time compilation. With the React Compiler, you’re now able to avoid writing `useCallback` and `useMemo` yourself in most cases. For Effects, the compiler can insert the dependencies for you:

```
useEffect(() => {

  const connection = createConnection(serverUrl, roomId);

  connection.connect();

  return () => {

    connection.disconnect();

  };

}); // compiler inserted dependencies.
```

With this code, the React Compiler can infer the dependencies for you and insert them automatically so you don’t need to see or write them. With features like [the IDE extension](#compiler-ide-extension) and [`useEffectEvent`](/reference/react/useEffectEvent), we can provide a CodeLens to show you what the Compiler inserted for times you need to debug, or to optimize by removing a dependency. This helps reinforce the correct mental model for writing Effects, which can run at any time to synchronize your component or hook’s state with something else.

Our hope is that automatically inserting dependencies is not only easier to write, but that it also makes them easier to understand by forcing you to think in terms of what the Effect does, and not in component lifecycles.

***

## Compiler IDE Extension[](#compiler-ide-extension "Link for Compiler IDE Extension ")

Later in 2025 [we shared](/blog/2025/10/07/react-compiler-1) the first stable release of React Compiler, and we’re continuing to invest in shipping more improvements.

We’ve also begun exploring ways to use the React Compiler to provide information that can improve understanding and debugging your code. One idea we’ve started exploring is a new experimental LSP-based React IDE extension powered by React Compiler, similar to the extension used in [Lauren Tan’s React Conf talk](https://conf2024.react.dev/talks/5).

Our idea is that we can use the compiler’s static analysis to provide more information, suggestions, and optimization opportunities directly in your IDE. For example, we can provide diagnostics for code breaking the Rules of React, hovers to show if components and hooks were optimized by the compiler, or a CodeLens to see [automatically inserted Effect dependencies](#automatic-effect-dependencies).

The IDE extension is still an early exploration, but we’ll share our progress in future updates.

***

## Fragment Refs[](#fragment-refs "Link for Fragment Refs ")

Many DOM APIs like those for event management, positioning, and focus are difficult to compose when writing with React. This often leads developers to reach for Effects, managing multiple Refs, by using APIs like `findDOMNode` (removed in React 19).

We are exploring adding refs to Fragments that would point to a group of DOM elements, rather than just a single element. Our hope is that this will simplify managing multiple children and make it easier to write composable React code when calling DOM APIs.

Fragment refs are still being researched. We’ll share more when we’re closer to having the final API finished.

***

## Gesture Animations[](#gesture-animations "Link for Gesture Animations ")

We’re also researching ways to enhance View Transitions to support gesture animations such as swiping to open a menu, or scroll through a photo carousel.

Gestures present new challenges for a few reasons:

* **Gestures are continuous**: as you swipe the animation is tied to your finger placement time, rather than triggering and running to completion.
* **Gestures don’t complete**: when you release your finger gesture animations can run to completion, or revert to their original state (like when you only partially open a menu) depending on how far you go.
* **Gestures invert old and new**: while you’re animating, you want the page you are animating from to stay “alive” and interactive. This inverts the browser View Transition model where the “old” state is a snapshot and the “new” state is the live DOM.

We believe we’ve found an approach that works well and may introduce a new API for triggering gesture transitions. For now, we’re focused on shipping `<ViewTransition>`, and will revisit gestures afterward.

***

## Concurrent Stores[](#concurrent-stores "Link for Concurrent Stores ")

When we released React 18 with concurrent rendering, we also released `useSyncExternalStore` so external store libraries that did not use React state or context could [support concurrent rendering](https://github.com/reactwg/react-18/discussions/70) by forcing a synchronous render when the store is updated.

Using `useSyncExternalStore` comes at a cost though, since it forces a bail out from concurrent features like transitions, and forces existing content to show Suspense fallbacks.

Now that React 19 has shipped, we’re revisiting this problem space to create a primitive to fully support concurrent external stores with the `use` API:

```
const value = use(store);
```

Our goal is to allow external state to be read during render without tearing, and to work seamlessly with all of the concurrent features React offers.

This research is still early. We’ll share more, and what the new APIs will look like, when we’re further along.

***

*Thanks to [Aurora Scharff](https://bsky.app/profile/aurorascharff.no), [Dan Abramov](https://bsky.app/profile/danabra.mov), [Eli White](https://twitter.com/Eli_White), [Lauren Tan](https://bsky.app/profile/no.lol), [Luna Wei](https://github.com/lunaleaps), [Matt Carroll](https://twitter.com/mattcarrollcode), [Jack Pope](https://jackpope.me), [Jason Bonta](https://threads.net/someextent), [Jordan Brown](https://github.com/jbrown215), [Jordan Eldredge](https://bsky.app/profile/capt.dev), [Mofei Zhang](https://threads.net/z_mofei), [Sebastien Lorber](https://bsky.app/profile/sebastienlorber.com), [Sebastian Markbåge](https://bsky.app/profile/sebmarkbage.calyptus.eu), and [Tim Yung](https://github.com/yungsters) for reviewing this post.*

[PreviousReact 19.2](/blog/2025/10/01/react-19-2)

[NextSunsetting Create React App](/blog/2025/02/14/sunsetting-create-react-app)

***

----
url: https://react.dev/blog/2020/12/21/data-fetching-with-react-server-components
----

[Blog](/blog)

# Introducing Zero-Bundle-Size React Server Components[](#undefined "Link for this heading")

December 21, 2020 by [Dan Abramov](https://bsky.app/profile/danabra.mov), [Lauren Tan](https://twitter.com/potetotes), [Joseph Savona](https://twitter.com/en_JS), and [Sebastian Markbåge](https://twitter.com/sebmarkbage)

***

2020 has been a long year. As it comes to an end we wanted to share a special Holiday Update on our research into zero-bundle-size **React Server Components**.

***

To introduce React Server Components, we have prepared a talk and a demo. If you want, you can check them out during the holidays, or later when work picks back up in the new year.

**React Server Components are still in research and development.** We are sharing this work in the spirit of transparency and to get initial feedback from the React community. There will be plenty of time for that, so **don’t feel like you have to catch up right now!**

If you want to check them out, we recommend going in the following order:

1. **Watch the talk** to learn about React Server Components and see the demo.

2. **[Clone the demo](http://github.com/reactjs/server-components-demo)** to play with React Server Components on your computer.

3. **[Read the RFC (with FAQ at the end)](https://github.com/reactjs/rfcs/pull/188)** for a deeper technical breakdown and to provide feedback.

We are excited to hear from you on the RFC or in replies to the [@reactjs](https://twitter.com/reactjs) Twitter handle. Happy holidays, stay safe, and see you next year!

[PreviousThe Plan for React 18](/blog/2021/06/08/the-plan-for-react-18)

[NextOlder posts](https://reactjs.org/blog/all.html)

***

----
url: https://18.react.dev/reference/react-dom/server/renderToStaticNodeStream
----

[API Reference](/reference/react)

[Server APIs](/reference/react-dom/server)

# renderToStaticNodeStream[](#undefined "Link for this heading")

`renderToStaticNodeStream` renders a non-interactive React tree to a [Node.js Readable Stream.](https://nodejs.org/api/stream.html#readable-streams)

```
const stream = renderToStaticNodeStream(reactNode, options?)
```

* [Reference](#reference)
  * [`renderToStaticNodeStream(reactNode, options?)`](#rendertostaticnodestream)
* [Usage](#usage)
  * [Rendering a React tree as static HTML to a Node.js Readable Stream](#rendering-a-react-tree-as-static-html-to-a-nodejs-readable-stream)

***

## Reference[](#reference "Link for Reference ")

### `renderToStaticNodeStream(reactNode, options?)`[](#rendertostaticnodestream "Link for this heading")

On the server, call `renderToStaticNodeStream` to get a [Node.js Readable Stream](https://nodejs.org/api/stream.html#readable-streams).

```
import { renderToStaticNodeStream } from 'react-dom/server';



const stream = renderToStaticNodeStream(<Page />);

stream.pipe(response);
```

[See more examples below.](#usage)

The stream will produce non-interactive HTML output of your React components.

#### Parameters[](#parameters "Link for Parameters ")

* `reactNode`: A React node you want to render to HTML. For example, a JSX element like `<Page />`.

* **optional** `options`: An object for server render.

  * **optional** `identifierPrefix`: A string prefix React uses for IDs generated by [`useId`.](/reference/react/useId) Useful to avoid conflicts when using multiple roots on the same page.

#### Returns[](#returns "Link for Returns ")

A [Node.js Readable Stream](https://nodejs.org/api/stream.html#readable-streams) that outputs an HTML string. The resulting HTML can’t be hydrated on the client.

#### Caveats[](#caveats "Link for Caveats ")

* `renderToStaticNodeStream` output cannot be hydrated.

* This method will wait for all [Suspense boundaries](/reference/react/Suspense) to complete before returning any output.

* As of React 18, this method buffers all of its output, so it doesn’t actually provide any streaming benefits.

* The returned stream is a byte stream encoded in utf-8. If you need a stream in another encoding, take a look at a project like [iconv-lite](https://www.npmjs.com/package/iconv-lite), which provides transform streams for transcoding text.

***

## Usage[](#usage "Link for Usage ")

### Rendering a React tree as static HTML to a Node.js Readable Stream[](#rendering-a-react-tree-as-static-html-to-a-nodejs-readable-stream "Link for Rendering a React tree as static HTML to a Node.js Readable Stream ")

Call `renderToStaticNodeStream` to get a [Node.js Readable Stream](https://nodejs.org/api/stream.html#readable-streams) which you can pipe to your server response:

```
import { renderToStaticNodeStream } from 'react-dom/server';



// The route handler syntax depends on your backend framework

app.use('/', (request, response) => {

  const stream = renderToStaticNodeStream(<Page />);

  stream.pipe(response);

});
```

The stream will produce the initial non-interactive HTML output of your React components.

### Pitfall

This method renders **non-interactive HTML that cannot be hydrated.** This is useful if you want to use React as a simple static page generator, or if you’re rendering completely static content like emails.

Interactive apps should use [`renderToPipeableStream`](/reference/react-dom/server/renderToPipeableStream) on the server and [`hydrateRoot`](/reference/react-dom/client/hydrateRoot) on the client.

[PreviousrenderToStaticMarkup](/reference/react-dom/server/renderToStaticMarkup)

[NextrenderToString](/reference/react-dom/server/renderToString)

***

----
url: https://18.react.dev/learn/passing-data-deeply-with-context
----

```
import Heading from './Heading.js';
import Section from './Section.js';

export default function Page() {
  return (
    <Section>
      <Heading level={1}>Title</Heading>
      <Heading level={2}>Heading</Heading>
      <Heading level={3}>Sub-heading</Heading>
      <Heading level={4}>Sub-sub-heading</Heading>
      <Heading level={5}>Sub-sub-sub-heading</Heading>
      <Heading level={6}>Sub-sub-sub-sub-heading</Heading>
    </Section>
  );
}
```

Let’s say you want multiple headings within the same `Section` to always have the same size:

```
import Heading from './Heading.js';
import Section from './Section.js';

export default function Page() {
  return (
    <Section>
      <Heading level={1}>Title</Heading>
      <Section>
        <Heading level={2}>Heading</Heading>
        <Heading level={2}>Heading</Heading>
        <Heading level={2}>Heading</Heading>
        <Section>
          <Heading level={3}>Sub-heading</Heading>
          <Heading level={3}>Sub-heading</Heading>
          <Heading level={3}>Sub-heading</Heading>
          <Section>
            <Heading level={4}>Sub-sub-heading</Heading>
            <Heading level={4}>Sub-sub-heading</Heading>
            <Heading level={4}>Sub-sub-heading</Heading>
          </Section>
        </Section>
      </Section>
    </Section>
  );
}
```

Currently, you pass the `level` prop to each `<Heading>` separately:

```
<Section>

  <Heading level={3}>About</Heading>

  <Heading level={3}>Photos</Heading>

  <Heading level={3}>Videos</Heading>

</Section>
```

It would be nice if you could pass the `level` prop to the `<Section>` component instead and remove it from the `<Heading>`. This way you could enforce that all headings in the same section have the same size:

```
<Section level={3}>

  <Heading>About</Heading>

  <Heading>Photos</Heading>

  <Heading>Videos</Heading>

</Section>
```

```
import { createContext } from 'react';

export const LevelContext = createContext(1);
```

The only argument to `createContext` is the *default* value. Here, `1` refers to the biggest heading level, but you could pass any kind of value (even an object). You will see the significance of the default value in the next step.

### Step 2: Use the context[](#step-2-use-the-context "Link for Step 2: Use the context ")

Import the `useContext` Hook from React and your context:

```
import { useContext } from 'react';

import { LevelContext } from './LevelContext.js';
```

Currently, the `Heading` component reads `level` from props:

```
export default function Heading({ level, children }) {

  // ...

}
```

Instead, remove the `level` prop and read the value from the context you just imported, `LevelContext`:

```
export default function Heading({ children }) {

  const level = useContext(LevelContext);

  // ...

}
```

`useContext` is a Hook. Just like `useState` and `useReducer`, you can only call a Hook immediately inside a React component (not inside loops or conditions). **`useContext` tells React that the `Heading` component wants to read the `LevelContext`.**

Now that the `Heading` component doesn’t have a `level` prop, you don’t need to pass the level prop to `Heading` in your JSX like this anymore:

```
<Section>

  <Heading level={4}>Sub-sub-heading</Heading>

  <Heading level={4}>Sub-sub-heading</Heading>

  <Heading level={4}>Sub-sub-heading</Heading>

</Section>
```

Update the JSX so that it’s the `Section` that receives it instead:

```
<Section level={4}>

  <Heading>Sub-sub-heading</Heading>

  <Heading>Sub-sub-heading</Heading>

  <Heading>Sub-sub-heading</Heading>

</Section>
```

As a reminder, this is the markup that you were trying to get working:

```
import Heading from './Heading.js';
import Section from './Section.js';

export default function Page() {
  return (
    <Section level={1}>
      <Heading>Title</Heading>
      <Section level={2}>
        <Heading>Heading</Heading>
        <Heading>Heading</Heading>
        <Heading>Heading</Heading>
        <Section level={3}>
          <Heading>Sub-heading</Heading>
          <Heading>Sub-heading</Heading>
          <Heading>Sub-heading</Heading>
          <Section level={4}>
            <Heading>Sub-sub-heading</Heading>
            <Heading>Sub-sub-heading</Heading>
            <Heading>Sub-sub-heading</Heading>
          </Section>
        </Section>
      </Section>
    </Section>
  );
}
```

Notice this example doesn’t quite work, yet! All the headings have the same size because **even though you’re *using* the context, you have not *provided* it yet.** React doesn’t know where to get it!

If you don’t provide the context, React will use the default value you’ve specified in the previous step. In this example, you specified `1` as the argument to `createContext`, so `useContext(LevelContext)` returns `1`, setting all those headings to `<h1>`. Let’s fix this problem by having each `Section` provide its own context.

### Step 3: Provide the context[](#step-3-provide-the-context "Link for Step 3: Provide the context ")

The `Section` component currently renders its children:

```
export default function Section({ children }) {

  return (

    <section className="section">

      {children}

    </section>

  );

}
```

**Wrap them with a context provider** to provide the `LevelContext` to them:

```
import { LevelContext } from './LevelContext.js';



export default function Section({ level, children }) {

  return (

    <section className="section">

      <LevelContext.Provider value={level}>

        {children}

      </LevelContext.Provider>

    </section>

  );

}
```

This tells React: “if any component inside this `<Section>` asks for `LevelContext`, give them this `level`.” The component will use the value of the nearest `<LevelContext.Provider>` in the UI tree above it.

```
import Heading from './Heading.js';
import Section from './Section.js';

export default function Page() {
  return (
    <Section level={1}>
      <Heading>Title</Heading>
      <Section level={2}>
        <Heading>Heading</Heading>
        <Heading>Heading</Heading>
        <Heading>Heading</Heading>
        <Section level={3}>
          <Heading>Sub-heading</Heading>
          <Heading>Sub-heading</Heading>
          <Heading>Sub-heading</Heading>
          <Section level={4}>
            <Heading>Sub-sub-heading</Heading>
            <Heading>Sub-sub-heading</Heading>
            <Heading>Sub-sub-heading</Heading>
          </Section>
        </Section>
      </Section>
    </Section>
  );
}
```

It’s the same result as the original code, but you did not need to pass the `level` prop to each `Heading` component! Instead, it “figures out” its heading level by asking the closest `Section` above:

1. You pass a `level` prop to the `<Section>`.
2. `Section` wraps its children into `<LevelContext.Provider value={level}>`.
3. `Heading` asks the closest value of `LevelContext` above with `useContext(LevelContext)`.

## Using and providing context from the same component[](#using-and-providing-context-from-the-same-component "Link for Using and providing context from the same component ")

Currently, you still have to specify each section’s `level` manually:

```
export default function Page() {

  return (

    <Section level={1}>

      ...

      <Section level={2}>

        ...

        <Section level={3}>

          ...
```

Since context lets you read information from a component above, each `Section` could read the `level` from the `Section` above, and pass `level + 1` down automatically. Here is how you could do it:

```
import { useContext } from 'react';

import { LevelContext } from './LevelContext.js';



export default function Section({ children }) {

  const level = useContext(LevelContext);

  return (

    <section className="section">

      <LevelContext.Provider value={level + 1}>

        {children}

      </LevelContext.Provider>

    </section>

  );

}
```

With this change, you don’t need to pass the `level` prop *either* to the `<Section>` or to the `<Heading>`:

```
import Heading from './Heading.js';
import Section from './Section.js';

export default function Page() {
  return (
    <Section>
      <Heading>Title</Heading>
      <Section>
        <Heading>Heading</Heading>
        <Heading>Heading</Heading>
        <Heading>Heading</Heading>
        <Section>
          <Heading>Sub-heading</Heading>
          <Heading>Sub-heading</Heading>
          <Heading>Sub-heading</Heading>
          <Section>
            <Heading>Sub-sub-heading</Heading>
            <Heading>Sub-sub-heading</Heading>
            <Heading>Sub-sub-heading</Heading>
          </Section>
        </Section>
      </Section>
    </Section>
  );
}
```

Now both `Heading` and `Section` read the `LevelContext` to figure out how “deep” they are. And the `Section` wraps its children into the `LevelContext` to specify that anything inside of it is at a “deeper” level.

### Note

This example uses heading levels because they show visually how nested components can override context. But context is useful for many other use cases too. You can pass down any information needed by the entire subtree: the current color theme, the currently logged in user, and so on.

## Context passes through intermediate components[](#context-passes-through-intermediate-components "Link for Context passes through intermediate components ")

You can insert as many components as you like between the component that provides context and the one that uses it. This includes both built-in components like `<div>` and components you might build yourself.

In this example, the same `Post` component (with a dashed border) is rendered at two different nesting levels. Notice that the `<Heading>` inside of it gets its level automatically from the closest `<Section>`:

```
import Heading from './Heading.js';
import Section from './Section.js';

export default function ProfilePage() {
  return (
    <Section>
      <Heading>My Profile</Heading>
      <Post
        title="Hello traveller!"
        body="Read about my adventures."
      />
      <AllPosts />
    </Section>
  );
}

function AllPosts() {
  return (
    <Section>
      <Heading>Posts</Heading>
      <RecentPosts />
    </Section>
  );
}

function RecentPosts() {
  return (
    <Section>
      <Heading>Recent Posts</Heading>
      <Post
        title="Flavors of Lisbon"
        body="...those pastéis de nata!"
      />
      <Post
        title="Buenos Aires in the rhythm of tango"
        body="I loved it!"
      />
    </Section>
  );
}

function Post({ title, body }) {
  return (
    <Section isFancy={true}>
      <Heading>
        {title}
      </Heading>
      <p><i>{body}</i></p>
    </Section>
  );
}
```

  3. Wrap children into `<MyContext.Provider value={...}>` to provide it from a parent.

```
import { useState } from 'react';
import { places } from './data.js';
import { getImageUrl } from './utils.js';

export default function App() {
  const [isLarge, setIsLarge] = useState(false);
  const imageSize = isLarge ? 150 : 100;
  return (
    <>
      <label>
        <input
          type="checkbox"
          checked={isLarge}
          onChange={e => {
            setIsLarge(e.target.checked);
          }}
        />
        Use large images
      </label>
      <hr />
      <List imageSize={imageSize} />
    </>
  )
}

function List({ imageSize }) {
  const listItems = places.map(place =>
    <li key={place.id}>
      <Place
        place={place}
        imageSize={imageSize}
      />
    </li>
  );
  return <ul>{listItems}</ul>;
}

function Place({ place, imageSize }) {
  return (
    <>
      <PlaceImage
        place={place}
        imageSize={imageSize}
      />
      <p>
        <b>{place.name}</b>
        {': ' + place.description}
      </p>
    </>
  );
}

function PlaceImage({ place, imageSize }) {
  return (
    <img
      src={getImageUrl(place)}
      alt={place.name}
      width={imageSize}
      height={imageSize}
    />
  );
}
```

[PreviousExtracting State Logic into a Reducer](/learn/extracting-state-logic-into-a-reducer)

[NextScaling Up with Reducer and Context](/learn/scaling-up-with-reducer-and-context)

***

----
url: https://legacy.reactjs.org/docs/static-type-checking.html
----

> These docs are old and won’t be updated. Go to [react.dev](https://react.dev/) for the new React docs.
>
> Check out [React TypeScript cheatsheet](https://react-typescript-cheatsheet.netlify.app/) for how to use React with TypeScript.

Static type checkers like [Flow](https://flow.org/) and [TypeScript](https://www.typescriptlang.org/) identify certain types of problems before you even run your code. They can also improve developer workflow by adding features like auto-completion. For this reason, we recommend using Flow or TypeScript instead of `PropTypes` for larger code bases.

## [](#flow)Flow

[Flow](https://flow.org/) is a static type checker for your JavaScript code. It is developed at Facebook and is often used with React. It lets you annotate the variables, functions, and React components with a special type syntax, and catch mistakes early. You can read an [introduction to Flow](https://flow.org/en/docs/getting-started/) to learn its basics.

To use Flow, you need to:

* Add Flow to your project as a dependency.
* Ensure that Flow syntax is stripped from the compiled code.
* Add type annotations and run Flow to check them.

We will explain these steps below in detail.

### [](#adding-flow-to-a-project)Adding Flow to a Project

First, navigate to your project directory in the terminal. You will need to run the following command:

If you use [Yarn](https://yarnpkg.com/), run:

```
yarn add --dev flow-bin
```

If you use [npm](https://www.npmjs.com/), run:

```
npm install --save-dev flow-bin
```

This command installs the latest version of Flow into your project.

Now, add `flow` to the `"scripts"` section of your `package.json` to be able to use this from the terminal:

```
{
  // ...
  "scripts": {
    "flow": "flow",    // ...
  },
  // ...
}
```

Finally, run one of the following commands:

If you use [Yarn](https://yarnpkg.com/), run:

```
yarn run flow init
```

If you use [npm](https://www.npmjs.com/), run:

```
npm run flow init
```

This command will create a Flow configuration file that you will need to commit.

### [](#stripping-flow-syntax-from-the-compiled-code)Stripping Flow Syntax from the Compiled Code

Flow extends the JavaScript language with a special syntax for type annotations. However, browsers aren’t aware of this syntax, so we need to make sure it doesn’t end up in the compiled JavaScript bundle that is sent to the browser.

The exact way to do this depends on the tools you use to compile JavaScript.

#### [](#create-react-app)Create React App

If your project was set up using [Create React App](https://github.com/facebookincubator/create-react-app), congratulations! The Flow annotations are already being stripped by default so you don’t need to do anything else in this step.

#### [](#babel)Babel

> Note:
>
> These instructions are *not* for Create React App users. Even though Create React App uses Babel under the hood, it is already configured to understand Flow. Only follow this step if you *don’t* use Create React App.

If you manually configured Babel for your project, you will need to install a special preset for Flow.

If you use Yarn, run:

```
yarn add --dev @babel/preset-flow
```

If you use npm, run:

```
npm install --save-dev @babel/preset-flow
```

Then add the `flow` preset to your [Babel configuration](https://babeljs.io/docs/usage/babelrc/). For example, if you configure Babel through `.babelrc` file, it could look like this:

```
{
  "presets": [
    "@babel/preset-flow",    "react"
  ]
}
```

This will let you use the Flow syntax in your code.

> Note:
>
> Flow does not require the `react` preset, but they are often used together. Flow itself understands JSX syntax out of the box.

#### [](#other-build-setups)Other Build Setups

If you don’t use either Create React App or Babel, you can use [flow-remove-types](https://github.com/flowtype/flow-remove-types) to strip the type annotations.

### [](#running-flow)Running Flow

If you followed the instructions above, you should be able to run Flow for the first time.

```
yarn flow
```

If you use npm, run:

```
npm run flow
```

You should see a message like:

```
No errors!
✨  Done in 0.17s.
```

### [](#adding-flow-type-annotations)Adding Flow Type Annotations

By default, Flow only checks the files that include this annotation:

```
// @flow
```

Typically it is placed at the top of a file. Try adding it to some files in your project and run `yarn flow` or `npm run flow` to see if Flow already found any issues.

There is also [an option](https://flow.org/en/docs/config/options/#toc-all-boolean) to force Flow to check *all* files regardless of the annotation. This can be too noisy for existing projects, but is reasonable for a new project if you want to fully type it with Flow.

Now you’re all set! We recommend to check out the following resources to learn more about Flow:

* [Flow Documentation: Type Annotations](https://flow.org/en/docs/types/)
* [Flow Documentation: Editors](https://flow.org/en/docs/editors/)
* [Flow Documentation: React](https://flow.org/en/docs/react/)
* [Linting in Flow](https://medium.com/flow-type/linting-in-flow-7709d7a7e969)

## [](#typescript)TypeScript

[TypeScript](https://www.typescriptlang.org/) is a programming language developed by Microsoft. It is a typed superset of JavaScript, and includes its own compiler. Being a typed language, TypeScript can catch errors and bugs at build time, long before your app goes live. You can learn more about using TypeScript with React [here](https://github.com/Microsoft/TypeScript-React-Starter#typescript-react-starter).

To use TypeScript, you need to:

* Add TypeScript as a dependency to your project
* Configure the TypeScript compiler options
* Use the right file extensions
* Add definitions for libraries you use

Let’s go over these in detail.

### [](#using-typescript-with-create-react-app)Using TypeScript with Create React App

Create React App supports TypeScript out of the box.

To create a **new project** with TypeScript support, run:

```
npx create-react-app my-app --template typescript
```

You can also add it to an **existing Create React App project**, [as documented here](https://facebook.github.io/create-react-app/docs/adding-typescript).

> Note:
>
> If you use Create React App, you can **skip the rest of this page**. It describes the manual setup which doesn’t apply to Create React App users.

### [](#adding-typescript-to-a-project)Adding TypeScript to a Project

It all begins with running one command in your terminal.

If you use [Yarn](https://yarnpkg.com/), run:

```
yarn add --dev typescript
```

If you use [npm](https://www.npmjs.com/), run:

```
npm install --save-dev typescript
```

Congrats! You’ve installed the latest version of TypeScript into your project. Installing TypeScript gives us access to the `tsc` command. Before configuration, let’s add `tsc` to the “scripts” section in our `package.json`:

```
{
  // ...
  "scripts": {
    "build": "tsc",    // ...
  },
  // ...
}
```

### [](#configuring-the-typescript-compiler)Configuring the TypeScript Compiler

The compiler is of no help to us until we tell it what to do. In TypeScript, these rules are defined in a special file called `tsconfig.json`. To generate this file:

If you use [Yarn](https://yarnpkg.com/), run:

```
yarn run tsc --init
```

If you use [npm](https://www.npmjs.com/), run:

```
npx tsc --init
```

Looking at the now generated `tsconfig.json`, you can see that there are many options you can use to configure the compiler. For a detailed description of all the options, check [here](https://www.typescriptlang.org/docs/handbook/tsconfig-json.html).

Of the many options, we’ll look at `rootDir` and `outDir`. In its true fashion, the compiler will take in typescript files and generate javascript files. However we don’t want to get confused with our source files and the generated output.

We’ll address this in two steps:

* Firstly, let’s arrange our project structure like this. We’ll place all our source code in the `src` directory.

```
├── package.json
├── src
│   └── index.ts
└── tsconfig.json
```

* Next, we’ll tell the compiler where our source code is and where the output should go.

```
// tsconfig.json

{
  "compilerOptions": {
    // ...
    "rootDir": "src",    "outDir": "build"    // ...
  },
}
```

Great! Now when we run our build script the compiler will output the generated javascript to the `build` folder. The [TypeScript React Starter](https://github.com/Microsoft/TypeScript-React-Starter/blob/master/tsconfig.json) provides a `tsconfig.json` with a good set of rules to get you started.

Generally, you don’t want to keep the generated javascript in your source control, so be sure to add the build folder to your `.gitignore`.

### [](#file-extensions)File extensions

In React, you most likely write your components in a `.js` file. In TypeScript we have 2 file extensions:

`.ts` is the default file extension while `.tsx` is a special extension used for files which contain `JSX`.

### [](#running-typescript)Running TypeScript

If you followed the instructions above, you should be able to run TypeScript for the first time.

```
yarn build
```

If you use npm, run:

```
npm run build
```

If you see no output, it means that it completed successfully.

### [](#type-definitions)Type Definitions

To be able to show errors and hints from other packages, the compiler relies on declaration files. A declaration file provides all the type information about a library. This enables us to use javascript libraries like those on npm in our project.

There are two main ways to get declarations for a library:

**Bundled** - The library bundles its own declaration file. This is great for us, since all we need to do is install the library, and we can use it right away. To check if a library has bundled types, look for an `index.d.ts` file in the project. Some libraries will have it specified in their `package.json` under the `typings` or `types` field.

**[DefinitelyTyped](https://github.com/DefinitelyTyped/DefinitelyTyped)** - DefinitelyTyped is a huge repository of declarations for libraries that don’t bundle a declaration file. The declarations are crowd-sourced and managed by Microsoft and open source contributors. React for example doesn’t bundle its own declaration file. Instead we can get it from DefinitelyTyped. To do so enter this command in your terminal.

```
# yarn
yarn add --dev @types/react

# npm
npm i --save-dev @types/react
```

**Local Declarations** Sometimes the package that you want to use doesn’t bundle declarations nor is it available on DefinitelyTyped. In that case, we can have a local declaration file. To do this, create a `declarations.d.ts` file in the root of your source directory. A simple declaration could look like this:

```
declare module 'querystring' {
  export function stringify(val: object): string
  export function parse(val: string): object
}
```

You are now ready to code! We recommend to check out the following resources to learn more about TypeScript:

* [TypeScript Documentation: Everyday Types](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html)
* [TypeScript Documentation: Migrating from JavaScript](https://www.typescriptlang.org/docs/handbook/migrating-from-javascript.html)
* [TypeScript Documentation: React and Webpack](https://www.typescriptlang.org/docs/handbook/react-&-webpack.html)

## [](#rescript)ReScript

[ReScript](https://rescript-lang.org/) is a typed language that compiles to JavaScript. Some of its core features are guaranteed 100% type coverage, first-class JSX support and [dedicated React bindings](https://rescript-lang.org/docs/react/latest/introduction) to allow integration in existing JS / TS React codebases.

You can find more infos on integrating ReScript in your existing JS / React codebase [here](https://rescript-lang.org/docs/manual/latest/installation#integrate-into-an-existing-js-project).

## [](#kotlin)Kotlin

[Kotlin](https://kotlinlang.org/) is a statically typed language developed by JetBrains. Its target platforms include the JVM, Android, LLVM, and [JavaScript](https://kotlinlang.org/docs/reference/js-overview.html).

JetBrains develops and maintains several tools specifically for the React community: [React bindings](https://github.com/JetBrains/kotlin-wrappers) as well as [Create React Kotlin App](https://github.com/JetBrains/create-react-kotlin-app). The latter helps you start building React apps with Kotlin with no build configuration.

## [](#other-languages)Other Languages

Note there are other statically typed languages that compile to JavaScript and are thus React compatible. For example, [F#/Fable](https://fable.io/) with [elmish-react](https://elmish.github.io/react). Check out their respective sites for more information, and feel free to add more statically typed languages that work with React to this page!

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/static-type-checking.md)

----
url: https://react.dev/reference/react-dom/components/select
----

[API Reference](/reference/react)

[Components](/reference/react-dom/components)

# \<select>[](#undefined "Link for this heading")

The [built-in browser `<select>` component](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/select) lets you render a select box with options.

```
<select>

  <option value="someOption">Some option</option>

  <option value="otherOption">Other option</option>

</select>
```

***

## Reference[](#reference "Link for Reference ")

### `<select>`[](#select "Link for this heading")

To display a select box, render the [built-in browser `<select>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/select) component.

```
<select>

  <option value="someOption">Some option</option>

  <option value="otherOption">Other option</option>

</select>
```

[See more examples below.](#usage)

#### Props[](#props "Link for Props ")

`<select>` supports all [common element props.](/reference/react-dom/components/common#common-props)

***

## Usage[](#usage "Link for Usage ")

### Displaying a select box with options[](#displaying-a-select-box-with-options "Link for Displaying a select box with options ")

Render a `<select>` with a list of `<option>` components inside to display a select box. Give each `<option>` a `value` representing the data to be submitted with the form.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
export default function FruitPicker() {
  return (
    <label>
      Pick a fruit:
      <select name="selectedFruit">
        <option value="apple">Apple</option>
        <option value="banana">Banana</option>
        <option value="orange">Orange</option>
      </select>
    </label>
  );
}
```

***

### Providing a label for a select box[](#providing-a-label-for-a-select-box "Link for Providing a label for a select box ")

Typically, you will place every `<select>` inside a [`<label>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/label) tag. This tells the browser that this label is associated with that select box. When the user clicks the label, the browser will automatically focus the select box. It’s also essential for accessibility: a screen reader will announce the label caption when the user focuses the select box.

If you can’t nest `<select>` into a `<label>`, associate them by passing the same ID to `<select id>` and [`<label htmlFor>`.](https://developer.mozilla.org/en-US/docs/Web/API/HTMLLabelElement/htmlFor) To avoid conflicts between multiple instances of one component, generate such an ID with [`useId`.](/reference/react/useId)

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useId } from 'react';

export default function Form() {
  const vegetableSelectId = useId();
  return (
    <>
      <label>
        Pick a fruit:
        <select name="selectedFruit">
          <option value="apple">Apple</option>
          <option value="banana">Banana</option>
          <option value="orange">Orange</option>
        </select>
      </label>
      <hr />
      <label htmlFor={vegetableSelectId}>
        Pick a vegetable:
      </label>
      <select id={vegetableSelectId} name="selectedVegetable">
        <option value="cucumber">Cucumber</option>
        <option value="corn">Corn</option>
        <option value="tomato">Tomato</option>
      </select>
    </>
  );
}
```

***

### Providing an initially selected option[](#providing-an-initially-selected-option "Link for Providing an initially selected option ")

By default, the browser will select the first `<option>` in the list. To select a different option by default, pass that `<option>`’s `value` as the `defaultValue` to the `<select>` element.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
export default function FruitPicker() {
  return (
    <label>
      Pick a fruit:
      <select name="selectedFruit" defaultValue="orange">
        <option value="apple">Apple</option>
        <option value="banana">Banana</option>
        <option value="orange">Orange</option>
      </select>
    </label>
  );
}
```

### Pitfall

Unlike in HTML, passing a `selected` attribute to an individual `<option>` is not supported.

***

### Enabling multiple selection[](#enabling-multiple-selection "Link for Enabling multiple selection ")

Pass `multiple={true}` to the `<select>` to let the user select multiple options. In that case, if you also specify `defaultValue` to choose the initially selected options, it must be an array.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
export default function FruitPicker() {
  return (
    <label>
      Pick some fruits:
      <select
        name="selectedFruit"
        defaultValue={['orange', 'banana']}
        multiple={true}
      >
        <option value="apple">Apple</option>
        <option value="banana">Banana</option>
        <option value="orange">Orange</option>
      </select>
    </label>
  );
}
```

***

### Reading the select box value when submitting a form[](#reading-the-select-box-value-when-submitting-a-form "Link for Reading the select box value when submitting a form ")

Add a [`<form>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form) around your select box with a [`<button type="submit">`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button) inside. It will call your `<form onSubmit>` event handler. By default, the browser will send the form data to the current URL and refresh the page. You can override that behavior by calling `e.preventDefault()`. Read the form data with [`new FormData(e.target)`](https://developer.mozilla.org/en-US/docs/Web/API/FormData).

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
export default function EditPost() {
  function handleSubmit(e) {
    // Prevent the browser from reloading the page
    e.preventDefault();
    // Read the form data
    const form = e.target;
    const formData = new FormData(form);
    // You can pass formData as a fetch body directly:
    fetch('/some-api', { method: form.method, body: formData });
    // You can generate a URL out of it, as the browser does by default:
    console.log(new URLSearchParams(formData).toString());
    // You can work with it as a plain object.
    const formJson = Object.fromEntries(formData.entries());
    console.log(formJson); // (!) This doesn't include multiple select values
    // Or you can get an array of name-value pairs.
    console.log([...formData.entries()]);
  }

  return (
    <form method="post" onSubmit={handleSubmit}>
      <label>
        Pick your favorite fruit:
        <select name="selectedFruit" defaultValue="orange">
          <option value="apple">Apple</option>
          <option value="banana">Banana</option>
          <option value="orange">Orange</option>
        </select>
      </label>
      <label>
        Pick all your favorite vegetables:
        <select
          name="selectedVegetables"
          multiple={true}
          defaultValue={['corn', 'tomato']}
        >
          <option value="cucumber">Cucumber</option>
          <option value="corn">Corn</option>
          <option value="tomato">Tomato</option>
        </select>
      </label>
      <hr />
      <button type="reset">Reset</button>
      <button type="submit">Submit</button>
    </form>
  );
}
```

### Note

Give a `name` to your `<select>`, for example `<select name="selectedFruit" />`. The `name` you specified will be used as a key in the form data, for example `{ selectedFruit: "orange" }`.

If you use `<select multiple={true}>`, the [`FormData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData) you’ll read from the form will include each selected value as a separate name-value pair. Look closely at the console logs in the example above.

### Pitfall

By default, *any* `<button>` inside a `<form>` will submit it. This can be surprising! If you have your own custom `Button` React component, consider returning [`<button type="button">`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/button) instead of `<button>`. Then, to be explicit, use `<button type="submit">` for buttons that *are* supposed to submit the form.

***

### Controlling a select box with a state variable[](#controlling-a-select-box-with-a-state-variable "Link for Controlling a select box with a state variable ")

A select box like `<select />` is *uncontrolled.* Even if you [pass an initially selected value](#providing-an-initially-selected-option) like `<select defaultValue="orange" />`, your JSX only specifies the initial value, not the value right now.

**To render a *controlled* select box, pass the `value` prop to it.** React will force the select box to always have the `value` you passed. Typically, you will control a select box by declaring a [state variable:](/reference/react/useState)

```
function FruitPicker() {

  const [selectedFruit, setSelectedFruit] = useState('orange'); // Declare a state variable...

  // ...

  return (

    <select

      value={selectedFruit} // ...force the select's value to match the state variable...

      onChange={e => setSelectedFruit(e.target.value)} // ... and update the state variable on any change!

    >

      <option value="apple">Apple</option>

      <option value="banana">Banana</option>

      <option value="orange">Orange</option>

    </select>

  );

}
```

This is useful if you want to re-render some part of the UI in response to every selection.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function FruitPicker() {
  const [selectedFruit, setSelectedFruit] = useState('orange');
  const [selectedVegs, setSelectedVegs] = useState(['corn', 'tomato']);
  return (
    <>
      <label>
        Pick a fruit:
        <select
          value={selectedFruit}
          onChange={e => setSelectedFruit(e.target.value)}
        >
          <option value="apple">Apple</option>
          <option value="banana">Banana</option>
          <option value="orange">Orange</option>
        </select>
      </label>
      <hr />
      <label>
        Pick all your favorite vegetables:
        <select
          multiple={true}
          value={selectedVegs}
          onChange={e => {
            const options = [...e.target.selectedOptions];
            const values = options.map(option => option.value);
            setSelectedVegs(values);
          }}
        >
          <option value="cucumber">Cucumber</option>
          <option value="corn">Corn</option>
          <option value="tomato">Tomato</option>
        </select>
      </label>
      <hr />
      <p>Your favorite fruit: {selectedFruit}</p>
      <p>Your favorite vegetables: {selectedVegs.join(', ')}</p>
    </>
  );
}
```

### Pitfall

**If you pass `value` without `onChange`, it will be impossible to select an option.** When you control a select box by passing some `value` to it, you *force* it to always have the value you passed. So if you pass a state variable as a `value` but forget to update that state variable synchronously during the `onChange` event handler, React will revert the select box after every keystroke back to the `value` that you specified.

Unlike in HTML, passing a `selected` attribute to an individual `<option>` is not supported.

[Previous\<progress>](/reference/react-dom/components/progress)

[Next\<textarea>](/reference/react-dom/components/textarea)

***

----
url: https://react.dev/reference/eslint-plugin-react-hooks/lints/immutability
----

[API Reference](/reference/react)

[Lints](/reference/eslint-plugin-react-hooks)

# immutability[](#undefined "Link for this heading")

Validates against mutating props, state, and other values that [are immutable](/reference/rules/components-and-hooks-must-be-pure#props-and-state-are-immutable).

## Rule Details[](#rule-details "Link for Rule Details ")

A component’s props and state are immutable snapshots. Never mutate them directly. Instead, pass new props down, and use the setter function from `useState`.

## Common Violations[](#common-violations "Link for Common Violations ")

### Invalid[](#invalid "Link for Invalid ")

```
// ❌ Array push mutation

function Component() {

  const [items, setItems] = useState([1, 2, 3]);



  const addItem = () => {

    items.push(4); // Mutating!

    setItems(items); // Same reference, no re-render

  };

}



// ❌ Object property assignment

function Component() {

  const [user, setUser] = useState({name: 'Alice'});



  const updateName = () => {

    user.name = 'Bob'; // Mutating!

    setUser(user); // Same reference

  };

}



// ❌ Sort without spreading

function Component() {

  const [items, setItems] = useState([3, 1, 2]);



  const sortItems = () => {

    setItems(items.sort()); // sort mutates!

  };

}
```

### Valid[](#valid "Link for Valid ")

```
// ✅ Create new array

function Component() {

  const [items, setItems] = useState([1, 2, 3]);



  const addItem = () => {

    setItems([...items, 4]); // New array

  };

}



// ✅ Create new object

function Component() {

  const [user, setUser] = useState({name: 'Alice'});



  const updateName = () => {

    setUser({...user, name: 'Bob'}); // New object

  };

}
```

## Troubleshooting[](#troubleshooting "Link for Troubleshooting ")

### I need to add items to an array[](#add-items-array "Link for I need to add items to an array ")

Mutating arrays with methods like `push()` won’t trigger re-renders:

```
// ❌ Wrong: Mutating the array

function TodoList() {

  const [todos, setTodos] = useState([]);



  const addTodo = (id, text) => {

    todos.push({id, text});

    setTodos(todos); // Same array reference!

  };



  return (

    <ul>

      {todos.map(todo => <li key={todo.id}>{todo.text}</li>)}

    </ul>

  );

}
```

Create a new array instead:

```
// ✅ Better: Create a new array

function TodoList() {

  const [todos, setTodos] = useState([]);



  const addTodo = (id, text) => {

    setTodos([...todos, {id, text}]);

    // Or: setTodos(todos => [...todos, {id: Date.now(), text}])

  };



  return (

    <ul>

      {todos.map(todo => <li key={todo.id}>{todo.text}</li>)}

    </ul>

  );

}
```

### I need to update nested objects[](#update-nested-objects "Link for I need to update nested objects ")

Mutating nested properties doesn’t trigger re-renders:

```
// ❌ Wrong: Mutating nested object

function UserProfile() {

  const [user, setUser] = useState({

    name: 'Alice',

    settings: {

      theme: 'light',

      notifications: true

    }

  });



  const toggleTheme = () => {

    user.settings.theme = 'dark'; // Mutation!

    setUser(user); // Same object reference

  };

}
```

Spread at each level that needs updating:

```
// ✅ Better: Create new objects at each level

function UserProfile() {

  const [user, setUser] = useState({

    name: 'Alice',

    settings: {

      theme: 'light',

      notifications: true

    }

  });



  const toggleTheme = () => {

    setUser({

      ...user,

      settings: {

        ...user.settings,

        theme: 'dark'

      }

    });

  };

}
```

[Previousglobals](/reference/eslint-plugin-react-hooks/lints/globals)

[Nextincompatible-library](/reference/eslint-plugin-react-hooks/lints/incompatible-library)

***

----
url: https://18.react.dev/reference/react-dom/preloadModule
----

[API Reference](/reference/react)

[APIs](/reference/react-dom)

# preloadModule[](#undefined "Link for this heading")

### Canary

The `preloadModule` function is currently only available in React’s Canary and experimental channels. Learn more about [React’s release channels here](/community/versioning-policy#all-release-channels).

### Note

[React-based frameworks](/learn/start-a-new-react-project) frequently handle resource loading for you, so you might not have to call this API yourself. Consult your framework’s documentation for details.

`preloadModule` lets you eagerly fetch an ESM module that you expect to use.

```
preloadModule("https://example.com/module.js", {as: "script"});
```

* [Reference](#reference)
  * [`preloadModule(href, options)`](#preloadmodule)

* [Usage](#usage)

  * [Preloading when rendering](#preloading-when-rendering)
  * [Preloading in an event handler](#preloading-in-an-event-handler)

***

## Reference[](#reference "Link for Reference ")

### `preloadModule(href, options)`[](#preloadmodule "Link for this heading")

To preload an ESM module, call the `preloadModule` function from `react-dom`.

```
import { preloadModule } from 'react-dom';



function AppRoot() {

  preloadModule("https://example.com/module.js", {as: "script"});

  // ...

}
```

***

## Usage[](#usage "Link for Usage ")

### Preloading when rendering[](#preloading-when-rendering "Link for Preloading when rendering ")

Call `preloadModule` when rendering a component if you know that it or its children will use a specific module.

```
import { preloadModule } from 'react-dom';



function AppRoot() {

  preloadModule("https://example.com/module.js", {as: "script"});

  return ...;

}
```

If you want the browser to start executing the module immediately (rather than just downloading it), use [`preinitModule`](/reference/react-dom/preinitModule) instead. If you want to load a script that isn’t an ESM module, use [`preload`](/reference/react-dom/preload).

### Preloading in an event handler[](#preloading-in-an-event-handler "Link for Preloading in an event handler ")

Call `preloadModule` in an event handler before transitioning to a page or state where the module will be needed. This gets the process started earlier than if you call it during the rendering of the new page or state.

```
import { preloadModule } from 'react-dom';



function CallToAction() {

  const onClick = () => {

    preloadModule("https://example.com/module.js", {as: "script"});

    startWizard();

  }

  return (

    <button onClick={onClick}>Start Wizard</button>

  );

}
```

[Previouspreload](/reference/react-dom/preload)

[Nextrender](/reference/react-dom/render)

***

----
url: https://18.react.dev/reference/react/isValidElement
----

[API Reference](/reference/react)

[Legacy React APIs](/reference/react/legacy)

# isValidElement[](#undefined "Link for this heading")

`isValidElement` checks whether a value is a React element.

```
const isElement = isValidElement(value)
```

* [Reference](#reference)
  * [`isValidElement(value)`](#isvalidelement)
* [Usage](#usage)
  * [Checking if something is a React element](#checking-if-something-is-a-react-element)

***

## Reference[](#reference "Link for Reference ")

### `isValidElement(value)`[](#isvalidelement "Link for this heading")

Call `isValidElement(value)` to check whether `value` is a React element.

```
import { isValidElement, createElement } from 'react';



// ✅ React elements

console.log(isValidElement(<p />)); // true

console.log(isValidElement(createElement('p'))); // true



// ❌ Not React elements

console.log(isValidElement(25)); // false

console.log(isValidElement('Hello')); // false

console.log(isValidElement({ age: 42 })); // false
```

***

```
import { isValidElement, createElement } from 'react';



// ✅ JSX tags are React elements

console.log(isValidElement(<p />)); // true

console.log(isValidElement(<MyComponent />)); // true



// ✅ Values returned by createElement are React elements

console.log(isValidElement(createElement('p'))); // true

console.log(isValidElement(createElement(MyComponent))); // true
```

Any other values, such as strings, numbers, or arbitrary objects and arrays, are not React elements.

For them, `isValidElement` returns `false`:

```
// ❌ These are *not* React elements

console.log(isValidElement(null)); // false

console.log(isValidElement(25)); // false

console.log(isValidElement('Hello')); // false

console.log(isValidElement({ age: 42 })); // false

console.log(isValidElement([<div />, <div />])); // false

console.log(isValidElement(MyComponent)); // false
```

It is very uncommon to need `isValidElement`. It’s mostly useful if you’re calling another API that *only* accepts elements (like [`cloneElement`](/reference/react/cloneElement) does) and you want to avoid an error when your argument is not a React element.

Unless you have some very specific reason to add an `isValidElement` check, you probably don’t need it.

##### Deep Dive#### React elements vs React nodes[](#react-elements-vs-react-nodes "Link for React elements vs React nodes ")

When you write a component, you can return any kind of *React node* from it:

```
function MyComponent() {

  // ... you can return any React node ...

}
```

```
function MyComponent() {

  return 42; // It's ok to return a number from component

}
```

This is why you shouldn’t use `isValidElement` as a way to check whether something can be rendered.

[PreviouscreateRef](/reference/react/createRef)

[NextPureComponent](/reference/react/PureComponent)

***

----
url: https://legacy.reactjs.org/docs/implementation-notes.html
----

This section is a collection of implementation notes for the [stack reconciler](/docs/codebase-overview.html#stack-reconciler).

It is very technical and assumes a strong understanding of React public API as well as how it’s divided into core, renderers, and the reconciler. If you’re not very familiar with the React codebase, read [the codebase overview](/docs/codebase-overview.html) first.

It also assumes an understanding of the [differences between React components, their instances, and elements](/blog/2015/12/18/react-components-elements-and-instances.html).

The stack reconciler was used in React 15 and earlier. It is located at [src/renderers/shared/stack/reconciler](https://github.com/facebook/react/tree/15-stable/src/renderers/shared/stack/reconciler).

### [](#video-building-react-from-scratch)Video: Building React from Scratch

[Paul O’Shannessy](https://twitter.com/zpao) gave a talk about [building React from scratch](https://www.youtube.com/watch?v=_MAD4Oly9yg) that largely inspired this document.

Both this document and his talk are simplifications of the real codebase so you might get a better understanding by getting familiar with both of them.

### [](#overview)Overview

The reconciler itself doesn’t have a public API. [Renderers](/docs/codebase-overview.html#renderers) like React DOM and React Native use it to efficiently update the user interface according to the React components written by the user.

### [](#mounting-as-a-recursive-process)Mounting as a Recursive Process

Let’s consider the first time you mount a component:

```
const root = ReactDOM.createRoot(rootEl);
root.render(<App />);
```

`root.render` will pass `<App />` along to the reconciler. Remember that `<App />` is a React element, that is, a description of *what* to render. You can think about it as a plain object:

```
console.log(<App />);
// { type: App, props: {} }
```

The reconciler will check if `App` is a class or a function.

If `App` is a function, the reconciler will call `App(props)` to get the rendered element.

If `App` is a class, the reconciler will instantiate an `App` with `new App(props)`, call the `componentWillMount()` lifecycle method, and then will call the `render()` method to get the rendered element.

Either way, the reconciler will learn the element `App` “rendered to”.

This process is recursive. `App` may render to a `<Greeting />`, `Greeting` may render to a `<Button />`, and so on. The reconciler will “drill down” through user-defined components recursively as it learns what each component renders to.

You can imagine this process as a pseudocode:

```
function isClass(type) {
  // React.Component subclasses have this flag
  return (
    Boolean(type.prototype) &&
    Boolean(type.prototype.isReactComponent)
  );
}

// This function takes a React element (e.g. <App />)
// and returns a DOM or Native node representing the mounted tree.
function mount(element) {
  var type = element.type;
  var props = element.props;

  // We will determine the rendered element
  // by either running the type as function
  // or creating an instance and calling render().
  var renderedElement;
  if (isClass(type)) {
    // Component class
    var publicInstance = new type(props);
    // Set the props
    publicInstance.props = props;
    // Call the lifecycle if necessary
    if (publicInstance.componentWillMount) {
      publicInstance.componentWillMount();
    }
    // Get the rendered element by calling render()
    renderedElement = publicInstance.render();
  } else {
    // Component function
    renderedElement = type(props);
  }

  // This process is recursive because a component may
  // return an element with a type of another component.
  return mount(renderedElement);

  // Note: this implementation is incomplete and recurses infinitely!
  // It only handles elements like <App /> or <Button />.
  // It doesn't handle elements like <div /> or <p /> yet.
}

var rootEl = document.getElementById('root');
var node = mount(<App />);
rootEl.appendChild(node);
```

> **Note:**
>
> This really *is* a pseudo-code. It isn’t similar to the real implementation. It will also cause a stack overflow because we haven’t discussed when to stop the recursion.

Let’s recap a few key ideas in the example above:

* React elements are plain objects representing the component type (e.g. `App`) and the props.
* User-defined components (e.g. `App`) can be classes or functions but they all “render to” elements.
* “Mounting” is a recursive process that creates a DOM or Native tree given the top-level React element (e.g. `<App />`).

### [](#mounting-host-elements)Mounting Host Elements

This process would be useless if we didn’t render something to the screen as a result.

In addition to user-defined (“composite”) components, React elements may also represent platform-specific (“host”) components. For example, `Button` might return a `<div />` from its render method.

If element’s `type` property is a string, we are dealing with a host element:

```
console.log(<div />);
// { type: 'div', props: {} }
```

There is no user-defined code associated with host elements.

When the reconciler encounters a host element, it lets the renderer take care of mounting it. For example, React DOM would create a DOM node.

If the host element has children, the reconciler recursively mounts them following the same algorithm as above. It doesn’t matter whether children are host (like `<div><hr /></div>`), composite (like `<div><Button /></div>`), or both.

The DOM nodes produced by the child components will be appended to the parent DOM node, and recursively, the complete DOM structure will be assembled.

> **Note:**
>
> The reconciler itself is not tied to the DOM. The exact result of mounting (sometimes called “mount image” in the source code) depends on the renderer, and can be a DOM node (React DOM), a string (React DOM Server), or a number representing a native view (React Native).

If we were to extend the code to handle host elements, it would look like this:

```
function isClass(type) {
  // React.Component subclasses have this flag
  return (
    Boolean(type.prototype) &&
    Boolean(type.prototype.isReactComponent)
  );
}

// This function only handles elements with a composite type.
// For example, it handles <App /> and <Button />, but not a <div />.
function mountComposite(element) {
  var type = element.type;
  var props = element.props;

  var renderedElement;
  if (isClass(type)) {
    // Component class
    var publicInstance = new type(props);
    // Set the props
    publicInstance.props = props;
    // Call the lifecycle if necessary
    if (publicInstance.componentWillMount) {
      publicInstance.componentWillMount();
    }
    renderedElement = publicInstance.render();
  } else if (typeof type === 'function') {
    // Component function
    renderedElement = type(props);
  }

  // This is recursive but we'll eventually reach the bottom of recursion when
  // the element is host (e.g. <div />) rather than composite (e.g. <App />):
  return mount(renderedElement);
}

// This function only handles elements with a host type.
// For example, it handles <div /> and <p /> but not an <App />.
function mountHost(element) {
  var type = element.type;
  var props = element.props;
  var children = props.children || [];
  if (!Array.isArray(children)) {
    children = [children];
  }
  children = children.filter(Boolean);

  // This block of code shouldn't be in the reconciler.
  // Different renderers might initialize nodes differently.
  // For example, React Native would create iOS or Android views.
  var node = document.createElement(type);
  Object.keys(props).forEach(propName => {
    if (propName !== 'children') {
      node.setAttribute(propName, props[propName]);
    }
  });

  // Mount the children
  children.forEach(childElement => {
    // Children may be host (e.g. <div />) or composite (e.g. <Button />).
    // We will also mount them recursively:
    var childNode = mount(childElement);

    // This line of code is also renderer-specific.
    // It would be different depending on the renderer:
    node.appendChild(childNode);
  });

  // Return the DOM node as mount result.
  // This is where the recursion ends.
  return node;
}

function mount(element) {
  var type = element.type;
  if (typeof type === 'function') {
    // User-defined components
    return mountComposite(element);
  } else if (typeof type === 'string') {
    // Platform-specific components
    return mountHost(element);
  }
}

var rootEl = document.getElementById('root');
var node = mount(<App />);
rootEl.appendChild(node);
```

This is working but still far from how the reconciler is really implemented. The key missing ingredient is support for updates.

### [](#introducing-internal-instances)Introducing Internal Instances

The key feature of React is that you can re-render everything, and it won’t recreate the DOM or reset the state:

```
root.render(<App />);
// Should reuse the existing DOM:
root.render(<App />);
```

However, our implementation above only knows how to mount the initial tree. It can’t perform updates on it because it doesn’t store all the necessary information, such as all the `publicInstance`s, or which DOM `node`s correspond to which components.

The stack reconciler codebase solves this by making the `mount()` function a method and putting it on a class. There are drawbacks to this approach, and we are going in the opposite direction in the [ongoing rewrite of the reconciler](/docs/codebase-overview.html#fiber-reconciler). Nevertheless this is how it works now.

Instead of separate `mountHost` and `mountComposite` functions, we will create two classes: `DOMComponent` and `CompositeComponent`.

Both classes have a constructor accepting the `element`, as well as a `mount()` method returning the mounted node. We will replace a top-level `mount()` function with a factory that instantiates the correct class:

```
function instantiateComponent(element) {
  var type = element.type;
  if (typeof type === 'function') {
    // User-defined components
    return new CompositeComponent(element);
  } else if (typeof type === 'string') {
    // Platform-specific components
    return new DOMComponent(element);
  }  
}
```

First, let’s consider the implementation of `CompositeComponent`:

```
class CompositeComponent {
  constructor(element) {
    this.currentElement = element;
    this.renderedComponent = null;
    this.publicInstance = null;
  }

  getPublicInstance() {
    // For composite components, expose the class instance.
    return this.publicInstance;
  }

  mount() {
    var element = this.currentElement;
    var type = element.type;
    var props = element.props;

    var publicInstance;
    var renderedElement;
    if (isClass(type)) {
      // Component class
      publicInstance = new type(props);
      // Set the props
      publicInstance.props = props;
      // Call the lifecycle if necessary
      if (publicInstance.componentWillMount) {
        publicInstance.componentWillMount();
      }
      renderedElement = publicInstance.render();
    } else if (typeof type === 'function') {
      // Component function
      publicInstance = null;
      renderedElement = type(props);
    }

    // Save the public instance
    this.publicInstance = publicInstance;

    // Instantiate the child internal instance according to the element.
    // It would be a DOMComponent for <div /> or <p />,
    // and a CompositeComponent for <App /> or <Button />:
    var renderedComponent = instantiateComponent(renderedElement);
    this.renderedComponent = renderedComponent;

    // Mount the rendered output
    return renderedComponent.mount();
  }
}
```

This is not much different from our previous `mountComposite()` implementation, but now we can save some information, such as `this.currentElement`, `this.renderedComponent`, and `this.publicInstance`, for use during updates.

Note that an instance of `CompositeComponent` is not the same thing as an instance of the user-supplied `element.type`. `CompositeComponent` is an implementation detail of our reconciler, and is never exposed to the user. The user-defined class is the one we read from `element.type`, and `CompositeComponent` creates an instance of it.

To avoid the confusion, we will call instances of `CompositeComponent` and `DOMComponent` “internal instances”. They exist so we can associate some long-lived data with them. Only the renderer and the reconciler are aware that they exist.

In contrast, we call an instance of the user-defined class a “public instance”. The public instance is what you see as `this` in the `render()` and other methods of your custom components.

The `mountHost()` function, refactored to be a `mount()` method on `DOMComponent` class, also looks familiar:

```
class DOMComponent {
  constructor(element) {
    this.currentElement = element;
    this.renderedChildren = [];
    this.node = null;
  }

  getPublicInstance() {
    // For DOM components, only expose the DOM node.
    return this.node;
  }

  mount() {
    var element = this.currentElement;
    var type = element.type;
    var props = element.props;
    var children = props.children || [];
    if (!Array.isArray(children)) {
      children = [children];
    }

    // Create and save the node
    var node = document.createElement(type);
    this.node = node;

    // Set the attributes
    Object.keys(props).forEach(propName => {
      if (propName !== 'children') {
        node.setAttribute(propName, props[propName]);
      }
    });

    // Create and save the contained children.
    // Each of them can be a DOMComponent or a CompositeComponent,
    // depending on whether the element type is a string or a function.
    var renderedChildren = children.map(instantiateComponent);
    this.renderedChildren = renderedChildren;

    // Collect DOM nodes they return on mount
    var childNodes = renderedChildren.map(child => child.mount());
    childNodes.forEach(childNode => node.appendChild(childNode));

    // Return the DOM node as mount result
    return node;
  }
}
```

The main difference after refactoring from `mountHost()` is that we now keep `this.node` and `this.renderedChildren` associated with the internal DOM component instance. We will also use them for applying non-destructive updates in the future.

As a result, each internal instance, composite or host, now points to its child internal instances. To help visualize this, if a function `<App>` component renders a `<Button>` class component, and `Button` class renders a `<div>`, the internal instance tree would look like this:

```
[object CompositeComponent] {
  currentElement: <App />,
  publicInstance: null,
  renderedComponent: [object CompositeComponent] {
    currentElement: <Button />,
    publicInstance: [object Button],
    renderedComponent: [object DOMComponent] {
      currentElement: <div />,
      node: [object HTMLDivElement],
      renderedChildren: []
    }
  }
}
```

In the DOM you would only see the `<div>`. However the internal instance tree contains both composite and host internal instances.

The composite internal instances need to store:

* The current element.
* The public instance if element type is a class.
* The single rendered internal instance. It can be either a `DOMComponent` or a `CompositeComponent`.

The host internal instances need to store:

* The current element.
* The DOM node.
* All the child internal instances. Each of them can be either a `DOMComponent` or a `CompositeComponent`.

If you’re struggling to imagine how an internal instance tree is structured in more complex applications, [React DevTools](https://github.com/facebook/react-devtools) can give you a close approximation, as it highlights host instances with grey, and composite instances with purple:

[](/static/d96fec10d250eace9756f09543bf5d58/00d43/implementation-notes-tree.png)

To complete this refactoring, we will introduce a function that mounts a complete tree into a container node and a public instance:

```
function mountTree(element, containerNode) {
  // Create the top-level internal instance
  var rootComponent = instantiateComponent(element);

  // Mount the top-level component into the container
  var node = rootComponent.mount();
  containerNode.appendChild(node);

  // Return the public instance it provides
  var publicInstance = rootComponent.getPublicInstance();
  return publicInstance;
}

var rootEl = document.getElementById('root');
mountTree(<App />, rootEl);
```

### [](#unmounting)Unmounting

Now that we have internal instances that hold onto their children and the DOM nodes, we can implement unmounting. For a composite component, unmounting calls a lifecycle method and recurses.

```
class CompositeComponent {

  // ...

  unmount() {
    // Call the lifecycle method if necessary
    var publicInstance = this.publicInstance;
    if (publicInstance) {
      if (publicInstance.componentWillUnmount) {
        publicInstance.componentWillUnmount();
      }
    }

    // Unmount the single rendered component
    var renderedComponent = this.renderedComponent;
    renderedComponent.unmount();
  }
}
```

For `DOMComponent`, unmounting tells each child to unmount:

```
class DOMComponent {

  // ...

  unmount() {
    // Unmount all the children
    var renderedChildren = this.renderedChildren;
    renderedChildren.forEach(child => child.unmount());
  }
}
```

In practice, unmounting DOM components also removes the event listeners and clears some caches, but we will skip those details.

We can now add a new top-level function called `unmountTree(containerNode)` that is similar to `ReactDOM.unmountComponentAtNode()`:

```
function unmountTree(containerNode) {
  // Read the internal instance from a DOM node:
  // (This doesn't work yet, we will need to change mountTree() to store it.)
  var node = containerNode.firstChild;
  var rootComponent = node._internalInstance;

  // Unmount the tree and clear the container
  rootComponent.unmount();
  containerNode.innerHTML = '';
}
```

In order for this to work, we need to read an internal root instance from a DOM node. We will modify `mountTree()` to add the `_internalInstance` property to the root DOM node. We will also teach `mountTree()` to destroy any existing tree so it can be called multiple times:

```
function mountTree(element, containerNode) {
  // Destroy any existing tree
  if (containerNode.firstChild) {
    unmountTree(containerNode);
  }

  // Create the top-level internal instance
  var rootComponent = instantiateComponent(element);

  // Mount the top-level component into the container
  var node = rootComponent.mount();
  containerNode.appendChild(node);

  // Save a reference to the internal instance
  node._internalInstance = rootComponent;

  // Return the public instance it provides
  var publicInstance = rootComponent.getPublicInstance();
  return publicInstance;
}
```

Now, running `unmountTree()`, or running `mountTree()` repeatedly, removes the old tree and runs the `componentWillUnmount()` lifecycle method on components.

### [](#updating)Updating

In the previous section, we implemented unmounting. However React wouldn’t be very useful if each prop change unmounted and mounted the whole tree. The goal of the reconciler is to reuse existing instances where possible to preserve the DOM and the state:

```
var rootEl = document.getElementById('root');

mountTree(<App />, rootEl);
// Should reuse the existing DOM:
mountTree(<App />, rootEl);
```

We will extend our internal instance contract with one more method. In addition to `mount()` and `unmount()`, both `DOMComponent` and `CompositeComponent` will implement a new method called `receive(nextElement)`:

```
class CompositeComponent {
  // ...

  receive(nextElement) {
    // ...
  }
}

class DOMComponent {
  // ...

  receive(nextElement) {
    // ...
  }
}
```

Its job is to do whatever is necessary to bring the component (and any of its children) up to date with the description provided by the `nextElement`.

This is the part that is often described as “virtual DOM diffing” although what really happens is that we walk the internal tree recursively and let each internal instance receive an update.

### [](#updating-composite-components)Updating Composite Components

When a composite component receives a new element, we run the `componentWillUpdate()` lifecycle method.

Then we re-render the component with the new props, and get the next rendered element:

```
class CompositeComponent {

  // ...

  receive(nextElement) {
    var prevProps = this.currentElement.props;
    var publicInstance = this.publicInstance;
    var prevRenderedComponent = this.renderedComponent;
    var prevRenderedElement = prevRenderedComponent.currentElement;

    // Update *own* element
    this.currentElement = nextElement;
    var type = nextElement.type;
    var nextProps = nextElement.props;

    // Figure out what the next render() output is
    var nextRenderedElement;
    if (isClass(type)) {
      // Component class
      // Call the lifecycle if necessary
      if (publicInstance.componentWillUpdate) {
        publicInstance.componentWillUpdate(nextProps);
      }
      // Update the props
      publicInstance.props = nextProps;
      // Re-render
      nextRenderedElement = publicInstance.render();
    } else if (typeof type === 'function') {
      // Component function
      nextRenderedElement = type(nextProps);
    }

    // ...
```

Next, we can look at the rendered element’s `type`. If the `type` has not changed since the last render, the component below can also be updated in place.

For example, if it returned `<Button color="red" />` the first time, and `<Button color="blue" />` the second time, we can just tell the corresponding internal instance to `receive()` the next element:

```
    // ...

    // If the rendered element type has not changed,
    // reuse the existing component instance and exit.
    if (prevRenderedElement.type === nextRenderedElement.type) {
      prevRenderedComponent.receive(nextRenderedElement);
      return;
    }

    // ...
```

However, if the next rendered element has a different `type` than the previously rendered element, we can’t update the internal instance. A `<button>` can’t “become” an `<input>`.

Instead, we have to unmount the existing internal instance and mount the new one corresponding to the rendered element type. For example, this is what happens when a component that previously rendered a `<button />` renders an `<input />`:

```
    // ...

    // If we reached this point, we need to unmount the previously
    // mounted component, mount the new one, and swap their nodes.

    // Find the old node because it will need to be replaced
    var prevNode = prevRenderedComponent.getHostNode();

    // Unmount the old child and mount a new child
    prevRenderedComponent.unmount();
    var nextRenderedComponent = instantiateComponent(nextRenderedElement);
    var nextNode = nextRenderedComponent.mount();

    // Replace the reference to the child
    this.renderedComponent = nextRenderedComponent;

    // Replace the old node with the new one
    // Note: this is renderer-specific code and
    // ideally should live outside of CompositeComponent:
    prevNode.parentNode.replaceChild(nextNode, prevNode);
  }
}
```

To sum this up, when a composite component receives a new element, it may either delegate the update to its rendered internal instance, or unmount it and mount a new one in its place.

There is another condition under which a component will re-mount rather than receive an element, and that is when the element’s `key` has changed. We don’t discuss `key` handling in this document because it adds more complexity to an already complex tutorial.

Note that we needed to add a method called `getHostNode()` to the internal instance contract so that it’s possible to locate the platform-specific node and replace it during the update. Its implementation is straightforward for both classes:

```
class CompositeComponent {
  // ...

  getHostNode() {
    // Ask the rendered component to provide it.
    // This will recursively drill down any composites.
    return this.renderedComponent.getHostNode();
  }
}

class DOMComponent {
  // ...

  getHostNode() {
    return this.node;
  }  
}
```

### [](#updating-host-components)Updating Host Components

Host component implementations, such as `DOMComponent`, update differently. When they receive an element, they need to update the underlying platform-specific view. In case of React DOM, this means updating the DOM attributes:

```
class DOMComponent {
  // ...

  receive(nextElement) {
    var node = this.node;
    var prevElement = this.currentElement;
    var prevProps = prevElement.props;
    var nextProps = nextElement.props;    
    this.currentElement = nextElement;

    // Remove old attributes.
    Object.keys(prevProps).forEach(propName => {
      if (propName !== 'children' && !nextProps.hasOwnProperty(propName)) {
        node.removeAttribute(propName);
      }
    });
    // Set next attributes.
    Object.keys(nextProps).forEach(propName => {
      if (propName !== 'children') {
        node.setAttribute(propName, nextProps[propName]);
      }
    });

    // ...
```

Then, host components need to update their children. Unlike composite components, they might contain more than a single child.

In this simplified example, we use an array of internal instances and iterate over it, either updating or replacing the internal instances depending on whether the received `type` matches their previous `type`. The real reconciler also takes element’s `key` in the account and track moves in addition to insertions and deletions, but we will omit this logic.

We collect DOM operations on children in a list so we can execute them in batch:

```
    // ...

    // These are arrays of React elements:
    var prevChildren = prevProps.children || [];
    if (!Array.isArray(prevChildren)) {
      prevChildren = [prevChildren];
    }
    var nextChildren = nextProps.children || [];
    if (!Array.isArray(nextChildren)) {
      nextChildren = [nextChildren];
    }
    // These are arrays of internal instances:
    var prevRenderedChildren = this.renderedChildren;
    var nextRenderedChildren = [];

    // As we iterate over children, we will add operations to the array.
    var operationQueue = [];

    // Note: the section below is extremely simplified!
    // It doesn't handle reorders, children with holes, or keys.
    // It only exists to illustrate the overall flow, not the specifics.

    for (var i = 0; i < nextChildren.length; i++) {
      // Try to get an existing internal instance for this child
      var prevChild = prevRenderedChildren[i];

      // If there is no internal instance under this index,
      // a child has been appended to the end. Create a new
      // internal instance, mount it, and use its node.
      if (!prevChild) {
        var nextChild = instantiateComponent(nextChildren[i]);
        var node = nextChild.mount();

        // Record that we need to append a node
        operationQueue.push({type: 'ADD', node});
        nextRenderedChildren.push(nextChild);
        continue;
      }

      // We can only update the instance if its element's type matches.
      // For example, <Button size="small" /> can be updated to
      // <Button size="large" /> but not to an <App />.
      var canUpdate = prevChildren[i].type === nextChildren[i].type;

      // If we can't update an existing instance, we have to unmount it
      // and mount a new one instead of it.
      if (!canUpdate) {
        var prevNode = prevChild.getHostNode();
        prevChild.unmount();

        var nextChild = instantiateComponent(nextChildren[i]);
        var nextNode = nextChild.mount();

        // Record that we need to swap the nodes
        operationQueue.push({type: 'REPLACE', prevNode, nextNode});
        nextRenderedChildren.push(nextChild);
        continue;
      }

      // If we can update an existing internal instance,
      // just let it receive the next element and handle its own update.
      prevChild.receive(nextChildren[i]);
      nextRenderedChildren.push(prevChild);
    }

    // Finally, unmount any children that don't exist:
    for (var j = nextChildren.length; j < prevChildren.length; j++) {
      var prevChild = prevRenderedChildren[j];
      var node = prevChild.getHostNode();
      prevChild.unmount();

      // Record that we need to remove the node
      operationQueue.push({type: 'REMOVE', node});
    }

    // Point the list of rendered children to the updated version.
    this.renderedChildren = nextRenderedChildren;

    // ...
```

As the last step, we execute the DOM operations. Again, the real reconciler code is more complex because it also handles moves:

```
    // ...

    // Process the operation queue.
    while (operationQueue.length > 0) {
      var operation = operationQueue.shift();
      switch (operation.type) {
      case 'ADD':
        this.node.appendChild(operation.node);
        break;
      case 'REPLACE':
        this.node.replaceChild(operation.nextNode, operation.prevNode);
        break;
      case 'REMOVE':
        this.node.removeChild(operation.node);
        break;
      }
    }
  }
}
```

And that is it for updating host components.

### [](#top-level-updates)Top-Level Updates

Now that both `CompositeComponent` and `DOMComponent` implement the `receive(nextElement)` method, we can change the top-level `mountTree()` function to use it when the element `type` is the same as it was the last time:

```
function mountTree(element, containerNode) {
  // Check for an existing tree
  if (containerNode.firstChild) {
    var prevNode = containerNode.firstChild;
    var prevRootComponent = prevNode._internalInstance;
    var prevElement = prevRootComponent.currentElement;

    // If we can, reuse the existing root component
    if (prevElement.type === element.type) {
      prevRootComponent.receive(element);
      return;
    }

    // Otherwise, unmount the existing tree
    unmountTree(containerNode);
  }

  // ...

}
```

Now calling `mountTree()` two times with the same type isn’t destructive:

```
var rootEl = document.getElementById('root');

mountTree(<App />, rootEl);
// Reuses the existing DOM:
mountTree(<App />, rootEl);
```

These are the basics of how React works internally.

### [](#what-we-left-out)What We Left Out

This document is simplified compared to the real codebase. There are a few important aspects we didn’t address:

* Components can render `null`, and the reconciler can handle “empty slots” in arrays and rendered output.
* The reconciler also reads `key` from the elements, and uses it to establish which internal instance corresponds to which element in an array. A bulk of complexity in the actual React implementation is related to that.
* In addition to composite and host internal instance classes, there are also classes for “text” and “empty” components. They represent text nodes and the “empty slots” you get by rendering `null`.
* Renderers use [injection](/docs/codebase-overview.html#dynamic-injection) to pass the host internal class to the reconciler. For example, React DOM tells the reconciler to use `ReactDOMComponent` as the host internal instance implementation.
* The logic for updating the list of children is extracted into a mixin called `ReactMultiChild` which is used by the host internal instance class implementations both in React DOM and React Native.
* The reconciler also implements support for `setState()` in composite components. Multiple updates inside event handlers get batched into a single update.
* The reconciler also takes care of attaching and detaching refs to composite components and host nodes.
* Lifecycle methods that are called after the DOM is ready, such as `componentDidMount()` and `componentDidUpdate()`, get collected into “callback queues” and are executed in a single batch.
* React puts information about the current update into an internal object called “transaction”. Transactions are useful for keeping track of the queue of pending lifecycle methods, the current DOM nesting for the warnings, and anything else that is “global” to a specific update. Transactions also ensure React “cleans everything up” after updates. For example, the transaction class provided by React DOM restores the input selection after any update.

### [](#jumping-into-the-code)Jumping into the Code

* [`ReactMount`](https://github.com/facebook/react/blob/83381c1673d14cd16cf747e34c945291e5518a86/src/renderers/dom/client/ReactMount.js) is where the code like `mountTree()` and `unmountTree()` from this tutorial lives. It takes care of mounting and unmounting top-level components. [`ReactNativeMount`](https://github.com/facebook/react/blob/83381c1673d14cd16cf747e34c945291e5518a86/src/renderers/native/ReactNativeMount.js) is its React Native analog.
* [`ReactDOMComponent`](https://github.com/facebook/react/blob/83381c1673d14cd16cf747e34c945291e5518a86/src/renderers/dom/shared/ReactDOMComponent.js) is the equivalent of `DOMComponent` in this tutorial. It implements the host component class for React DOM renderer. [`ReactNativeBaseComponent`](https://github.com/facebook/react/blob/83381c1673d14cd16cf747e34c945291e5518a86/src/renderers/native/ReactNativeBaseComponent.js) is its React Native analog.
* [`ReactCompositeComponent`](https://github.com/facebook/react/blob/83381c1673d14cd16cf747e34c945291e5518a86/src/renderers/shared/stack/reconciler/ReactCompositeComponent.js) is the equivalent of `CompositeComponent` in this tutorial. It handles calling user-defined components and maintaining their state.
* [`instantiateReactComponent`](https://github.com/facebook/react/blob/83381c1673d14cd16cf747e34c945291e5518a86/src/renderers/shared/stack/reconciler/instantiateReactComponent.js) contains the switch that picks the right internal instance class to construct for an element. It is equivalent to `instantiateComponent()` in this tutorial.
* [`ReactReconciler`](https://github.com/facebook/react/blob/83381c1673d14cd16cf747e34c945291e5518a86/src/renderers/shared/stack/reconciler/ReactReconciler.js) is a wrapper with `mountComponent()`, `receiveComponent()`, and `unmountComponent()` methods. It calls the underlying implementations on the internal instances, but also includes some code around them that is shared by all internal instance implementations.
* [`ReactChildReconciler`](https://github.com/facebook/react/blob/83381c1673d14cd16cf747e34c945291e5518a86/src/renderers/shared/stack/reconciler/ReactChildReconciler.js) implements the logic for mounting, updating, and unmounting children according to the `key` of their elements.
* [`ReactMultiChild`](https://github.com/facebook/react/blob/83381c1673d14cd16cf747e34c945291e5518a86/src/renderers/shared/stack/reconciler/ReactMultiChild.js) implements processing the operation queue for child insertions, deletions, and moves independently of the renderer.
* `mount()`, `receive()`, and `unmount()` are really called `mountComponent()`, `receiveComponent()`, and `unmountComponent()` in React codebase for legacy reasons, but they receive elements.
* Properties on the internal instances start with an underscore, e.g. `_currentElement`. They are considered to be read-only public fields throughout the codebase.

### [](#future-directions)Future Directions

Stack reconciler has inherent limitations such as being synchronous and unable to interrupt the work or split it in chunks. There is a work in progress on the [new Fiber reconciler](/docs/codebase-overview.html#fiber-reconciler) with a [completely different architecture](https://github.com/acdlite/react-fiber-architecture). In the future, we intend to replace stack reconciler with it, but at the moment it is far from feature parity.

### [](#next-steps)Next Steps

Read the [next section](/docs/design-principles.html) to learn about the guiding principles we use for React development.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/implementation-notes.md)

* Previous article

  [Codebase Overview](/docs/codebase-overview.html)

* Next article

  [Design Principles](/docs/design-principles.html)

----
url: https://18.react.dev/community/conferences
----

[Community](/community)

# React Conferences[](#undefined "Link for this heading")

Do you know of a local React.js conference? Add it here! (Please keep the list chronological)

## Upcoming Conferences[](#upcoming-conferences "Link for Upcoming Conferences ")

### React Universe Conf 2024[](#react-universe-conf-2024 "Link for React Universe Conf 2024 ")

September 5-6, 2024. Wrocław, Poland.

[Website](https://www.reactuniverseconf.com/) - [Twitter](https://twitter.com/react_native_eu) - [LinkedIn](https://www.linkedin.com/events/reactuniverseconf7163919537074118657/)

### React Alicante 2024[](#react-alicante-2024 "Link for React Alicante 2024 ")

September 19-21, 2024. Alicante, Spain.

[Website](https://reactalicante.es/) - [Twitter](https://twitter.com/ReactAlicante) - [YouTube](https://www.youtube.com/channel/UCaSdUaITU1Cz6PvC97A7e0w)

### RenderCon Kenya 2024[](#rendercon-kenya-2024 "Link for RenderCon Kenya 2024 ")

October 04 - 05, 2024. Nairobi, Kenya

[Website](https://rendercon.org/) - [Twitter](https://twitter.com/renderconke) - [LinkedIn](https://www.linkedin.com/company/renderconke/) - [YouTube](https://www.youtube.com/channel/UC0bCcG8gHUL4njDOpQGcMIA)

### React India 2024[](#react-india-2024 "Link for React India 2024 ")

October 17 - 19, 2024. In-person in Goa, India (hybrid event) + Oct 15 2024 - remote day

[Website](https://www.reactindia.io) - [Twitter](https://twitter.com/react_india) - [Facebook](https://www.facebook.com/ReactJSIndia) - [Youtube](https://www.youtube.com/channel/UCaFbHCBkPvVv1bWs_jwYt3w)

### React Brussels 2024[](#react-brussels-2024 "Link for React Brussels 2024 ")

October 18, 2024. In-person in Brussels, Belgium (hybrid event)

[Website](https://www.react.brussels/) - [Twitter](https://x.com/BrusselsReact)

### reactjsday 2024[](#reactjsday-2024 "Link for reactjsday 2024 ")

October 25, 2024. In-person in Verona, Italy + online (hybrid event)

[Website](https://2024.reactjsday.it/) - [Twitter](https://x.com/reactjsday) - [Facebook](https://www.facebook.com/GrUSP/) - [YouTube](https://www.youtube.com/c/grusp)

### React Advanced London 2024[](#react-advanced-london-2024 "Link for React Advanced London 2024 ")

October 25 & 28, 2024. In-person in London, UK + online (hybrid event)

[Website](https://reactadvanced.com/) - [Twitter](https://x.com/reactadvanced)

### React Native London Conf 2024[](#react-native-london-2024 "Link for React Native London Conf 2024 ")

November 14 & 15, 2024. In-person in London, UK

[Website](https://reactnativelondon.co.uk/) - [Twitter](https://x.com/RNLConf)

### React Summit US 2024[](#react-summit-us-2024 "Link for React Summit US 2024 ")

November 19 & 22, 2024. In-person in New York, USA + online (hybrid event)

[Website](https://reactsummit.us/) - [Twitter](https://twitter.com/reactsummit) - [Videos](https://portal.gitnation.org/)

### React Africa 2024[](#react-africa-2024 "Link for React Africa 2024 ")

November 29, 2024. In-person in Casablanca, Morocco (hybrid event)

[Website](https://react-africa.com/) - [Twitter](https://x.com/BeJS_)

### React Day Berlin 2024[](#react-day-berlin-2024 "Link for React Day Berlin 2024 ")

December 13 & 16, 2024. In-person in Berlin, Germany + remote (hybrid event)

[Website](https://reactday.berlin/) - [Twitter](https://x.com/reactdayberlin)

## Past Conferences[](#past-conferences "Link for Past Conferences ")

***

----
url: https://legacy.reactjs.org/docs/react-dom.html
----

> These docs are old and won’t be updated. Go to [react.dev](https://react.dev/) for the new React docs.
>
> These new documentation pages teach modern React:
>
> * [`react-dom`: Components](https://react.dev/reference/react-dom/components)
> * [`react-dom`: APIs](https://react.dev/reference/react-dom)
> * [`react-dom`: Client APIs](https://react.dev/reference/react-dom/client)
> * [`react-dom`: Server APIs](https://react.dev/reference/react-dom/server)

The `react-dom` package provides DOM-specific methods that can be used at the top level of your app and as an escape hatch to get outside the React model if you need to.

```
import * as ReactDOM from 'react-dom';
```

If you use ES5 with npm, you can write:

```
var ReactDOM = require('react-dom');
```

The `react-dom` package also provides modules specific to client and server apps:

* [`react-dom/client`](/docs/react-dom-client.html)
* [`react-dom/server`](/docs/react-dom-server.html)

## [](#overview)Overview

The `react-dom` package exports these methods:

* [`createPortal()`](#createportal)
* [`flushSync()`](#flushsync)

These `react-dom` methods are also exported, but are considered legacy:

* [`render()`](#render)
* [`hydrate()`](#hydrate)
* [`findDOMNode()`](#finddomnode)
* [`unmountComponentAtNode()`](#unmountcomponentatnode)

> Note:
>
> Both `render` and `hydrate` have been replaced with new [client methods](/docs/react-dom-client.html) in React 18. These methods will warn that your app will behave as if it’s running React 17 (learn more [here](https://reactjs.org/link/switch-to-createroot)).

### [](#browser-support)Browser Support

React supports all modern browsers, although [some polyfills are required](/docs/javascript-environment-requirements.html) for older versions.

> Note
>
> We do not support older browsers that don’t support ES5 methods or microtasks such as Internet Explorer. You may find that your apps do work in older browsers if polyfills such as [es5-shim and es5-sham](https://github.com/es-shims/es5-shim) are included in the page, but you’re on your own if you choose to take this path.

## [](#reference)Reference

### [](#createportal)`createPortal()`

> This content is out of date.
>
> Read the new React documentation for [`createPortal`](https://react.dev/reference/react-dom/createPortal).

```
createPortal(child, container)
```

Creates a portal. Portals provide a way to [render children into a DOM node that exists outside the hierarchy of the DOM component](/docs/portals.html).

### [](#flushsync)`flushSync()`

> This content is out of date.
>
> Read the new React documentation for [`flushSync`](https://react.dev/reference/react-dom/flushSync).

```
flushSync(callback)
```

Force React to flush any updates inside the provided callback synchronously. This ensures that the DOM is updated immediately.

```
// Force this state update to be synchronous.
flushSync(() => {
  setCount(count + 1);
});
// By this point, DOM is updated.
```

> Note:
>
> `flushSync` can significantly hurt performance. Use sparingly.
>
> `flushSync` may force pending Suspense boundaries to show their `fallback` state.
>
> `flushSync` may also run pending effects and synchronously apply any updates they contain before returning.
>
> `flushSync` may also flush updates outside the callback when necessary to flush the updates inside the callback. For example, if there are pending updates from a click, React may flush those before flushing the updates inside the callback.

## [](#legacy-reference)Legacy Reference

### [](#render)`render()`

> This content is out of date.
>
> Read the new React documentation for [`render`](https://react.dev/reference/react-dom/render).

```
render(element, container[, callback])
```

> Note:
>
> `render` has been replaced with `createRoot` in React 18. See [createRoot](/docs/react-dom-client.html#createroot) for more info.

Render a React element into the DOM in the supplied `container` and return a [reference](/docs/more-about-refs.html) to the component (or returns `null` for [stateless components](/docs/components-and-props.html#function-and-class-components)).

If the React element was previously rendered into `container`, this will perform an update on it and only mutate the DOM as necessary to reflect the latest React element.

If the optional callback is provided, it will be executed after the component is rendered or updated.

> Note:
>
> `render()` controls the contents of the container node you pass in. Any existing DOM elements inside are replaced when first called. Later calls use React’s DOM diffing algorithm for efficient updates.
>
> `render()` does not modify the container node (only modifies the children of the container). It may be possible to insert a component to an existing DOM node without overwriting the existing children.
>
> `render()` currently returns a reference to the root `ReactComponent` instance. However, using this return value is legacy and should be avoided because future versions of React may render components asynchronously in some cases. If you need a reference to the root `ReactComponent` instance, the preferred solution is to attach a [callback ref](/docs/refs-and-the-dom.html#callback-refs) to the root element.
>
> Using `render()` to hydrate a server-rendered container is deprecated. Use [`hydrateRoot()`](/docs/react-dom-client.html#hydrateroot) instead.

***

### [](#hydrate)`hydrate()`

> This content is out of date.
>
> Read the new React documentation for [`hydrate`](https://react.dev/reference/react-dom/hydrate).

```
hydrate(element, container[, callback])
```

> Note:
>
> `hydrate` has been replaced with `hydrateRoot` in React 18. See [hydrateRoot](/docs/react-dom-client.html#hydrateroot) for more info.

Same as [`render()`](#render), but is used to hydrate a container whose HTML contents were rendered by [`ReactDOMServer`](/docs/react-dom-server.html). React will attempt to attach event listeners to the existing markup.

React expects that the rendered content is identical between the server and the client. It can patch up differences in text content, but you should treat mismatches as bugs and fix them. In development mode, React warns about mismatches during hydration. There are no guarantees that attribute differences will be patched up in case of mismatches. This is important for performance reasons because in most apps, mismatches are rare, and so validating all markup would be prohibitively expensive.

If a single element’s attribute or text content is unavoidably different between the server and the client (for example, a timestamp), you may silence the warning by adding `suppressHydrationWarning={true}` to the element. It only works one level deep, and is intended to be an escape hatch. Don’t overuse it. Unless it’s text content, React still won’t attempt to patch it up, so it may remain inconsistent until future updates.

If you intentionally need to render something different on the server and the client, you can do a two-pass rendering. Components that render something different on the client can read a state variable like `this.state.isClient`, which you can set to `true` in `componentDidMount()`. This way the initial render pass will render the same content as the server, avoiding mismatches, but an additional pass will happen synchronously right after hydration. Note that this approach will make your components slower because they have to render twice, so use it with caution.

Remember to be mindful of user experience on slow connections. The JavaScript code may load significantly later than the initial HTML render, so if you render something different in the client-only pass, the transition can be jarring. However, if executed well, it may be beneficial to render a “shell” of the application on the server, and only show some of the extra widgets on the client. To learn how to do this without getting the markup mismatch issues, refer to the explanation in the previous paragraph.

***

### [](#unmountcomponentatnode)`unmountComponentAtNode()`

> This content is out of date.
>
> Read the new React documentation for [`unmountComponentAtNode`](https://react.dev/reference/react-dom/unmountComponentAtNode).

```
unmountComponentAtNode(container)
```

> Note:
>
> `unmountComponentAtNode` has been replaced with `root.unmount()` in React 18. See [createRoot](/docs/react-dom-client.html#createroot) for more info.

Remove a mounted React component from the DOM and clean up its event handlers and state. If no component was mounted in the container, calling this function does nothing. Returns `true` if a component was unmounted and `false` if there was no component to unmount.

***

### [](#finddomnode)`findDOMNode()`

> This content is out of date.
>
> Read the new React documentation for [`findDOMNode`](https://react.dev/reference/react-dom/findDOMNode).

> Note:
>
> `findDOMNode` is an escape hatch used to access the underlying DOM node. In most cases, use of this escape hatch is discouraged because it pierces the component abstraction. [It has been deprecated in `StrictMode`.](/docs/strict-mode.html#warning-about-deprecated-finddomnode-usage)

```
findDOMNode(component)
```

If this component has been mounted into the DOM, this returns the corresponding native browser DOM element. This method is useful for reading values out of the DOM, such as form field values and performing DOM measurements. **In most cases, you can attach a ref to the DOM node and avoid using `findDOMNode` at all.**

When a component renders to `null` or `false`, `findDOMNode` returns `null`. When a component renders to a string, `findDOMNode` returns a text DOM node containing that value. As of React 16, a component may return a fragment with multiple children, in which case `findDOMNode` will return the DOM node corresponding to the first non-empty child.

> Note:
>
> `findDOMNode` only works on mounted components (that is, components that have been placed in the DOM). If you try to call this on a component that has not been mounted yet (like calling `findDOMNode()` in `render()` on a component that has yet to be created) an exception will be thrown.
>
> `findDOMNode` cannot be used on function components.

***

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/reference-react-dom.md)

----
url: https://react.dev/community/acknowledgements
----

* [Luna Wei](https://github.com/lunaleaps)
* [Noah Lemen](https://github.com/noahlemen)
* [Sathya Gunasekaran](https://github.com/gsathya)
* [Sophia Shoemaker](https://github.com/mrscobbler)
* [Sunil Pai](https://github.com/threepointone)
* [Tianyu Yao](https://github.com/)

***

----
url: https://react.dev/community/meetups
----

* [Montreal, QC](https://guild.host/react-montreal/)
* [Vancouver, BC](https://www.meetup.com/ReactJS-Vancouver-Meetup/)
* [Ottawa, ON](https://www.meetup.com/Ottawa-ReactJS-Meetup/)
* [Saskatoon, SK](https://www.meetup.com/saskatoon-react-meetup/)
* [Toronto, ON](https://www.meetup.com/Toronto-React-Native/events/)

## Colombia[](#colombia "Link for Colombia ")

* [Medellin](https://www.meetup.com/React-Medellin/)

## Czechia[](#czechia "Link for Czechia ")

* [Prague](https://guild.host/react-prague/)

* [React Native Liverpool](https://www.meetup.com/react-native-liverpool/)
* [React Native London](https://guild.host/RNLDN)

## Finland[](#finland "Link for Finland ")

* [Helsinki](https://www.meetabit.com/communities/react-helsinki)

* [Ahmedabad](https://reactahmedabad.dev/)
* [Bangalore (React)](https://www.meetup.com/ReactJS-Bangalore/)
* [Bangalore (React Native)](https://www.meetup.com/React-Native-Bangalore-Meetup)
* [Chennai](https://www.linkedin.com/company/chennaireact)
* [Delhi NCR](https://www.meetup.com/React-Delhi-NCR/)
* [Mumbai](https://reactmumbai.dev)
* [Pune](https://www.meetup.com/ReactJS-and-Friends/)
* [Rajasthan](https://reactrajasthan.com)

* [Edinburgh](https://www.meetup.com/react-edinburgh/)

## Spain[](#spain "Link for Spain ")

* [Barcelona](https://www.meetup.com/ReactJS-Barcelona/)

## Sri Lanka[](#sri-lanka "Link for Sri Lanka ")

* [Colombo](https://www.javascriptcolombo.com/)

* [Denver, CO - React Denver](https://reactdenver.com/)

***

----
url: https://react.dev/learn/reusing-logic-with-custom-hooks
----


[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useEffect } from 'react';

export default function StatusBar() {
  const [isOnline, setIsOnline] = useState(true);
  useEffect(() => {
    function handleOnline() {
      setIsOnline(true);
    }
    function handleOffline() {
      setIsOnline(false);
    }
    window.addEventListener('online', handleOnline);
    window.addEventListener('offline', handleOffline);
    return () => {
      window.removeEventListener('online', handleOnline);
      window.removeEventListener('offline', handleOffline);
    };
  }, []);

  return <h1>{isOnline ? '✅ Online' : '❌ Disconnected'}</h1>;
}
```

Try turning your network on and off, and notice how this `StatusBar` updates in response to your actions.

Now imagine you *also* want to use the same logic in a different component. You want to implement a Save button that will become disabled and show “Reconnecting…” instead of “Save” while the network is off.

To start, you can copy and paste the `isOnline` state and the Effect into `SaveButton`:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useEffect } from 'react';

export default function SaveButton() {
  const [isOnline, setIsOnline] = useState(true);
  useEffect(() => {
    function handleOnline() {
      setIsOnline(true);
    }
    function handleOffline() {
      setIsOnline(false);
    }
    window.addEventListener('online', handleOnline);
    window.addEventListener('offline', handleOffline);
    return () => {
      window.removeEventListener('online', handleOnline);
      window.removeEventListener('offline', handleOffline);
    };
  }, []);

  function handleSaveClick() {
    console.log('✅ Progress saved');
  }

  return (
    <button disabled={!isOnline} onClick={handleSaveClick}>
      {isOnline ? 'Save progress' : 'Reconnecting...'}
    </button>
  );
}
```

Verify that, if you turn off the network, the button will change its appearance.

These two components work fine, but the duplication in logic between them is unfortunate. It seems like even though they have different *visual appearance,* you want to reuse the logic between them.

### Extracting your own custom Hook from a component[](#extracting-your-own-custom-hook-from-a-component "Link for Extracting your own custom Hook from a component ")

Imagine for a moment that, similar to [`useState`](/reference/react/useState) and [`useEffect`](/reference/react/useEffect), there was a built-in `useOnlineStatus` Hook. Then both of these components could be simplified and you could remove the duplication between them:

```
function StatusBar() {

  const isOnline = useOnlineStatus();

  return <h1>{isOnline ? '✅ Online' : '❌ Disconnected'}</h1>;

}



function SaveButton() {

  const isOnline = useOnlineStatus();



  function handleSaveClick() {

    console.log('✅ Progress saved');

  }



  return (

    <button disabled={!isOnline} onClick={handleSaveClick}>

      {isOnline ? 'Save progress' : 'Reconnecting...'}

    </button>

  );

}
```

Although there is no such built-in Hook, you can write it yourself. Declare a function called `useOnlineStatus` and move all the duplicated code into it from the components you wrote earlier:

```
function useOnlineStatus() {

  const [isOnline, setIsOnline] = useState(true);

  useEffect(() => {

    function handleOnline() {

      setIsOnline(true);

    }

    function handleOffline() {

      setIsOnline(false);

    }

    window.addEventListener('online', handleOnline);

    window.addEventListener('offline', handleOffline);

    return () => {

      window.removeEventListener('online', handleOnline);

      window.removeEventListener('offline', handleOffline);

    };

  }, []);

  return isOnline;

}
```

At the end of the function, return `isOnline`. This lets your components read that value:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useOnlineStatus } from './useOnlineStatus.js';

function StatusBar() {
  const isOnline = useOnlineStatus();
  return <h1>{isOnline ? '✅ Online' : '❌ Disconnected'}</h1>;
}

function SaveButton() {
  const isOnline = useOnlineStatus();

  function handleSaveClick() {
    console.log('✅ Progress saved');
  }

  return (
    <button disabled={!isOnline} onClick={handleSaveClick}>
      {isOnline ? 'Save progress' : 'Reconnecting...'}
    </button>
  );
}

export default function App() {
  return (
    <>
      <SaveButton />
      <StatusBar />
    </>
  );
}
```

```
// 🔴 Avoid: A Hook that doesn't use Hooks

function useSorted(items) {

  return items.slice().sort();

}



// ✅ Good: A regular function that doesn't use Hooks

function getSorted(items) {

  return items.slice().sort();

}
```

This ensures that your code can call this regular function anywhere, including conditions:

```
function List({ items, shouldSort }) {

  let displayedItems = items;

  if (shouldSort) {

    // ✅ It's ok to call getSorted() conditionally because it's not a Hook

    displayedItems = getSorted(items);

  }

  // ...

}
```

You should give `use` prefix to a function (and thus make it a Hook) if it uses at least one Hook inside of it:

```
// ✅ Good: A Hook that uses other Hooks

function useAuth() {

  return useContext(Auth);

}
```

Technically, this isn’t enforced by React. In principle, you could make a Hook that doesn’t call other Hooks. This is often confusing and limiting so it’s best to avoid that pattern. However, there may be rare cases where it is helpful. For example, maybe your function doesn’t use any Hooks right now, but you plan to add some Hook calls to it in the future. Then it makes sense to name it with the `use` prefix:

```
// ✅ Good: A Hook that will likely use some other Hooks later

function useAuth() {

  // TODO: Replace with this line when authentication is implemented:

  // return useContext(Auth);

  return TEST_USER;

}
```

Then components won’t be able to call it conditionally. This will become important when you actually add Hook calls inside. If you don’t plan to use Hooks inside it (now or later), don’t make it a Hook.

### Custom Hooks let you share stateful logic, not state itself[](#custom-hooks-let-you-share-stateful-logic-not-state-itself "Link for Custom Hooks let you share stateful logic, not state itself ")

In the earlier example, when you turned the network on and off, both components updated together. However, it’s wrong to think that a single `isOnline` state variable is shared between them. Look at this code:

```
function StatusBar() {

  const isOnline = useOnlineStatus();

  // ...

}



function SaveButton() {

  const isOnline = useOnlineStatus();

  // ...

}
```

It works the same way as before you extracted the duplication:

```
function StatusBar() {

  const [isOnline, setIsOnline] = useState(true);

  useEffect(() => {

    // ...

  }, []);

  // ...

}



function SaveButton() {

  const [isOnline, setIsOnline] = useState(true);

  useEffect(() => {

    // ...

  }, []);

  // ...

}
```

These are two completely independent state variables and Effects! They happened to have the same value at the same time because you synchronized them with the same external value (whether the network is on).

To better illustrate this, we’ll need a different example. Consider this `Form` component:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export default function Form() {
  const [firstName, setFirstName] = useState('Mary');
  const [lastName, setLastName] = useState('Poppins');

  function handleFirstNameChange(e) {
    setFirstName(e.target.value);
  }

  function handleLastNameChange(e) {
    setLastName(e.target.value);
  }

  return (
    <>
      <label>
        First name:
        <input value={firstName} onChange={handleFirstNameChange} />
      </label>
      <label>
        Last name:
        <input value={lastName} onChange={handleLastNameChange} />
      </label>
      <p><b>Good morning, {firstName} {lastName}.</b></p>
    </>
  );
}
```

There’s some repetitive logic for each form field:

1. There’s a piece of state (`firstName` and `lastName`).
2. There’s a change handler (`handleFirstNameChange` and `handleLastNameChange`).
3. There’s a piece of JSX that specifies the `value` and `onChange` attributes for that input.

You can extract the repetitive logic into this `useFormInput` custom Hook:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';

export function useFormInput(initialValue) {
  const [value, setValue] = useState(initialValue);

  function handleChange(e) {
    setValue(e.target.value);
  }

  const inputProps = {
    value: value,
    onChange: handleChange
  };

  return inputProps;
}
```

Notice that it only declares *one* state variable called `value`.

However, the `Form` component calls `useFormInput` *two times:*

```
function Form() {

  const firstNameProps = useFormInput('Mary');

  const lastNameProps = useFormInput('Poppins');

  // ...
```

This is why it works like declaring two separate state variables!

**Custom Hooks let you share *stateful logic* but not *state itself.* Each call to a Hook is completely independent from every other call to the same Hook.** This is why the two sandboxes above are completely equivalent. If you’d like, scroll back up and compare them. The behavior before and after extracting a custom Hook is identical.

When you need to share the state itself between multiple components, [lift it up and pass it down](/learn/sharing-state-between-components) instead.

## Passing reactive values between Hooks[](#passing-reactive-values-between-hooks "Link for Passing reactive values between Hooks ")

The code inside your custom Hooks will re-run during every re-render of your component. This is why, like components, custom Hooks [need to be pure.](/learn/keeping-components-pure) Think of custom Hooks’ code as part of your component’s body!

Because custom Hooks re-render together with your component, they always receive the latest props and state. To see what this means, consider this chat room example. Change the server URL or the chat room:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useEffect } from 'react';
import { createConnection } from './chat.js';
import { showNotification } from './notifications.js';

export default function ChatRoom({ roomId }) {
  const [serverUrl, setServerUrl] = useState('https://localhost:1234');

  useEffect(() => {
    const options = {
      serverUrl: serverUrl,
      roomId: roomId
    };
    const connection = createConnection(options);
    connection.on('message', (msg) => {
      showNotification('New message: ' + msg);
    });
    connection.connect();
    return () => connection.disconnect();
  }, [roomId, serverUrl]);

  return (
    <>
      <label>
        Server URL:
        <input value={serverUrl} onChange={e => setServerUrl(e.target.value)} />
      </label>
      <h1>Welcome to the {roomId} room!</h1>
    </>
  );
}
```

When you change `serverUrl` or `roomId`, the Effect [“reacts” to your changes](/learn/lifecycle-of-reactive-effects#effects-react-to-reactive-values) and re-synchronizes. You can tell by the console messages that the chat re-connects every time that you change your Effect’s dependencies.

Now move the Effect’s code into a custom Hook:

```
export function useChatRoom({ serverUrl, roomId }) {

  useEffect(() => {

    const options = {

      serverUrl: serverUrl,

      roomId: roomId

    };

    const connection = createConnection(options);

    connection.connect();

    connection.on('message', (msg) => {

      showNotification('New message: ' + msg);

    });

    return () => connection.disconnect();

  }, [roomId, serverUrl]);

}
```

This lets your `ChatRoom` component call your custom Hook without worrying about how it works inside:

```
export default function ChatRoom({ roomId }) {

  const [serverUrl, setServerUrl] = useState('https://localhost:1234');



  useChatRoom({

    roomId: roomId,

    serverUrl: serverUrl

  });



  return (

    <>

      <label>

        Server URL:

        <input value={serverUrl} onChange={e => setServerUrl(e.target.value)} />

      </label>

      <h1>Welcome to the {roomId} room!</h1>

    </>

  );

}
```

This looks much simpler! (But it does the same thing.)

Notice that the logic *still responds* to prop and state changes. Try editing the server URL or the selected room:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';
import { useChatRoom } from './useChatRoom.js';

export default function ChatRoom({ roomId }) {
  const [serverUrl, setServerUrl] = useState('https://localhost:1234');

  useChatRoom({
    roomId: roomId,
    serverUrl: serverUrl
  });

  return (
    <>
      <label>
        Server URL:
        <input value={serverUrl} onChange={e => setServerUrl(e.target.value)} />
      </label>
      <h1>Welcome to the {roomId} room!</h1>
    </>
  );
}
```

Notice how you’re taking the return value of one Hook:

```
export default function ChatRoom({ roomId }) {

  const [serverUrl, setServerUrl] = useState('https://localhost:1234');



  useChatRoom({

    roomId: roomId,

    serverUrl: serverUrl

  });

  // ...
```

and passing it as an input to another Hook:

```
export default function ChatRoom({ roomId }) {

  const [serverUrl, setServerUrl] = useState('https://localhost:1234');



  useChatRoom({

    roomId: roomId,

    serverUrl: serverUrl

  });

  // ...
```

Every time your `ChatRoom` component re-renders, it passes the latest `roomId` and `serverUrl` to your Hook. This is why your Effect re-connects to the chat whenever their values are different after a re-render. (If you ever worked with audio or video processing software, chaining Hooks like this might remind you of chaining visual or audio effects. It’s as if the output of `useState` “feeds into” the input of the `useChatRoom`.)

### Passing event handlers to custom Hooks[](#passing-event-handlers-to-custom-hooks "Link for Passing event handlers to custom Hooks ")

As you start using `useChatRoom` in more components, you might want to let components customize its behavior. For example, currently, the logic for what to do when a message arrives is hardcoded inside the Hook:

```
export function useChatRoom({ serverUrl, roomId }) {

  useEffect(() => {

    const options = {

      serverUrl: serverUrl,

      roomId: roomId

    };

    const connection = createConnection(options);

    connection.connect();

    connection.on('message', (msg) => {

      showNotification('New message: ' + msg);

    });

    return () => connection.disconnect();

  }, [roomId, serverUrl]);

}
```

Let’s say you want to move this logic back to your component:

```
export default function ChatRoom({ roomId }) {

  const [serverUrl, setServerUrl] = useState('https://localhost:1234');



  useChatRoom({

    roomId: roomId,

    serverUrl: serverUrl,

    onReceiveMessage(msg) {

      showNotification('New message: ' + msg);

    }

  });

  // ...
```

To make this work, change your custom Hook to take `onReceiveMessage` as one of its named options:

```
export function useChatRoom({ serverUrl, roomId, onReceiveMessage }) {

  useEffect(() => {

    const options = {

      serverUrl: serverUrl,

      roomId: roomId

    };

    const connection = createConnection(options);

    connection.connect();

    connection.on('message', (msg) => {

      onReceiveMessage(msg);

    });

    return () => connection.disconnect();

  }, [roomId, serverUrl, onReceiveMessage]); // ✅ All dependencies declared

}
```

This will work, but there’s one more improvement you can do when your custom Hook accepts event handlers.

Adding a dependency on `onReceiveMessage` is not ideal because it will cause the chat to re-connect every time the component re-renders. [Wrap this event handler into an Effect Event to remove it from the dependencies:](/learn/removing-effect-dependencies#wrapping-an-event-handler-from-the-props)

```
import { useEffect, useEffectEvent } from 'react';

// ...



export function useChatRoom({ serverUrl, roomId, onReceiveMessage }) {

  const onMessage = useEffectEvent(onReceiveMessage);



  useEffect(() => {

    const options = {

      serverUrl: serverUrl,

      roomId: roomId

    };

    const connection = createConnection(options);

    connection.connect();

    connection.on('message', (msg) => {

      onMessage(msg);

    });

    return () => connection.disconnect();

  }, [roomId, serverUrl]); // ✅ All dependencies declared

}
```

Now the chat won’t re-connect every time that the `ChatRoom` component re-renders. Here is a fully working demo of passing an event handler to a custom Hook that you can play with:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState } from 'react';
import { useChatRoom } from './useChatRoom.js';
import { showNotification } from './notifications.js';

export default function ChatRoom({ roomId }) {
  const [serverUrl, setServerUrl] = useState('https://localhost:1234');

  useChatRoom({
    roomId: roomId,
    serverUrl: serverUrl,
    onReceiveMessage(msg) {
      showNotification('New message: ' + msg);
    }
  });

  return (
    <>
      <label>
        Server URL:
        <input value={serverUrl} onChange={e => setServerUrl(e.target.value)} />
      </label>
      <h1>Welcome to the {roomId} room!</h1>
    </>
  );
}
```

Notice how you no longer need to know *how* `useChatRoom` works in order to use it. You could add it to any other component, pass any other options, and it would work the same way. That’s the power of custom Hooks.

## When to use custom Hooks[](#when-to-use-custom-hooks "Link for When to use custom Hooks ")

You don’t need to extract a custom Hook for every little duplicated bit of code. Some duplication is fine. For example, extracting a `useFormInput` Hook to wrap a single `useState` call like earlier is probably unnecessary.

However, whenever you write an Effect, consider whether it would be clearer to also wrap it in a custom Hook. [You shouldn’t need Effects very often,](/learn/you-might-not-need-an-effect) so if you’re writing one, it means that you need to “step outside React” to synchronize with some external system or to do something that React doesn’t have a built-in API for. Wrapping it into a custom Hook lets you precisely communicate your intent and how the data flows through it.

For example, consider a `ShippingForm` component that displays two dropdowns: one shows the list of cities, and another shows the list of areas in the selected city. You might start with some code that looks like this:

```
function ShippingForm({ country }) {

  const [cities, setCities] = useState(null);

  // This Effect fetches cities for a country

  useEffect(() => {

    let ignore = false;

    fetch(`/api/cities?country=${country}`)

      .then(response => response.json())

      .then(json => {

        if (!ignore) {

          setCities(json);

        }

      });

    return () => {

      ignore = true;

    };

  }, [country]);



  const [city, setCity] = useState(null);

  const [areas, setAreas] = useState(null);

  // This Effect fetches areas for the selected city

  useEffect(() => {

    if (city) {

      let ignore = false;

      fetch(`/api/areas?city=${city}`)

        .then(response => response.json())

        .then(json => {

          if (!ignore) {

            setAreas(json);

          }

        });

      return () => {

        ignore = true;

      };

    }

  }, [city]);



  // ...
```

Although this code is quite repetitive, [it’s correct to keep these Effects separate from each other.](/learn/removing-effect-dependencies#is-your-effect-doing-several-unrelated-things) They synchronize two different things, so you shouldn’t merge them into one Effect. Instead, you can simplify the `ShippingForm` component above by extracting the common logic between them into your own `useData` Hook:

```
function useData(url) {

  const [data, setData] = useState(null);

  useEffect(() => {

    if (url) {

      let ignore = false;

      fetch(url)

        .then(response => response.json())

        .then(json => {

          if (!ignore) {

            setData(json);

          }

        });

      return () => {

        ignore = true;

      };

    }

  }, [url]);

  return data;

}
```

Now you can replace both Effects in the `ShippingForm` components with calls to `useData`:

```
function ShippingForm({ country }) {

  const cities = useData(`/api/cities?country=${country}`);

  const [city, setCity] = useState(null);

  const areas = useData(city ? `/api/areas?city=${city}` : null);

  // ...
```

```
function ChatRoom({ roomId }) {

  const [serverUrl, setServerUrl] = useState('https://localhost:1234');



  // 🔴 Avoid: using custom "lifecycle" Hooks

  useMount(() => {

    const connection = createConnection({ roomId, serverUrl });

    connection.connect();



    post('/analytics/event', { eventName: 'visit_chat' });

  });

  // ...

}



// 🔴 Avoid: creating custom "lifecycle" Hooks

function useMount(fn) {

  useEffect(() => {

    fn();

  }, []); // 🔴 React Hook useEffect has a missing dependency: 'fn'

}
```

**Custom “lifecycle” Hooks like `useMount` don’t fit well into the React paradigm.** For example, this code example has a mistake (it doesn’t “react” to `roomId` or `serverUrl` changes), but the linter won’t warn you about it because the linter only checks direct `useEffect` calls. It won’t know about your Hook.

If you’re writing an Effect, start by using the React API directly:

```
function ChatRoom({ roomId }) {

  const [serverUrl, setServerUrl] = useState('https://localhost:1234');



  // ✅ Good: two raw Effects separated by purpose



  useEffect(() => {

    const connection = createConnection({ serverUrl, roomId });

    connection.connect();

    return () => connection.disconnect();

  }, [serverUrl, roomId]);



  useEffect(() => {

    post('/analytics/event', { eventName: 'visit_chat', roomId });

  }, [roomId]);



  // ...

}
```

Then, you can (but don’t have to) extract custom Hooks for different high-level use cases:

```
function ChatRoom({ roomId }) {

  const [serverUrl, setServerUrl] = useState('https://localhost:1234');



  // ✅ Great: custom Hooks named after their purpose

  useChatRoom({ serverUrl, roomId });

  useImpressionLog('visit_chat', { roomId });

  // ...

}
```

**A good custom Hook makes the calling code more declarative by constraining what it does.** For example, `useChatRoom(options)` can only connect to the chat room, while `useImpressionLog(eventName, extraData)` can only send an impression log to the analytics. If your custom Hook API doesn’t constrain the use cases and is very abstract, in the long run it’s likely to introduce more problems than it solves.

### Custom Hooks help you migrate to better patterns[](#custom-hooks-help-you-migrate-to-better-patterns "Link for Custom Hooks help you migrate to better patterns ")

Effects are an [“escape hatch”](/learn/escape-hatches): you use them when you need to “step outside React” and when there is no better built-in solution for your use case. With time, the React team’s goal is to reduce the number of the Effects in your app to the minimum by providing more specific solutions to more specific problems. Wrapping your Effects in custom Hooks makes it easier to upgrade your code when these solutions become available.

Let’s return to this example:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useEffect } from 'react';

export function useOnlineStatus() {
  const [isOnline, setIsOnline] = useState(true);
  useEffect(() => {
    function handleOnline() {
      setIsOnline(true);
    }
    function handleOffline() {
      setIsOnline(false);
    }
    window.addEventListener('online', handleOnline);
    window.addEventListener('offline', handleOffline);
    return () => {
      window.removeEventListener('online', handleOnline);
      window.removeEventListener('offline', handleOffline);
    };
  }, []);
  return isOnline;
}
```

In the above example, `useOnlineStatus` is implemented with a pair of [`useState`](/reference/react/useState) and [`useEffect`.](/reference/react/useEffect) However, this isn’t the best possible solution. There is a number of edge cases it doesn’t consider. For example, it assumes that when the component mounts, `isOnline` is already `true`, but this may be wrong if the network already went offline. You can use the browser [`navigator.onLine`](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/onLine) API to check for that, but using it directly would not work on the server for generating the initial HTML. In short, this code could be improved.

React includes a dedicated API called [`useSyncExternalStore`](/reference/react/useSyncExternalStore) which takes care of all of these problems for you. Here is your `useOnlineStatus` Hook, rewritten to take advantage of this new API:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useSyncExternalStore } from 'react';

function subscribe(callback) {
  window.addEventListener('online', callback);
  window.addEventListener('offline', callback);
  return () => {
    window.removeEventListener('online', callback);
    window.removeEventListener('offline', callback);
  };
}

export function useOnlineStatus() {
  return useSyncExternalStore(
    subscribe,
    () => navigator.onLine, // How to get the value on the client
    () => true // How to get the value on the server
  );
}
```

Notice how **you didn’t need to change any of the components** to make this migration:

```
function StatusBar() {

  const isOnline = useOnlineStatus();

  // ...

}



function SaveButton() {

  const isOnline = useOnlineStatus();

  // ...

}
```

This is another reason for why wrapping Effects in custom Hooks is often beneficial:

1. You make the data flow to and from your Effects very explicit.
2. You let your components focus on the intent rather than on the exact implementation of your Effects.
3. When React adds new features, you can remove those Effects without changing any of your components.

Similar to a [design system,](https://uxdesign.cc/everything-you-need-to-know-about-design-systems-54b109851969) you might find it helpful to start extracting common idioms from your app’s components into custom Hooks. This will keep your components’ code focused on the intent, and let you avoid writing raw Effects very often. Many excellent custom Hooks are maintained by the React community.

##### Deep Dive#### Will React provide any built-in solution for data fetching?[](#will-react-provide-any-built-in-solution-for-data-fetching "Link for Will React provide any built-in solution for data fetching? ")

Today, with the [`use`](/reference/react/use#streaming-data-from-server-to-client) API, data can be read in render by passing a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) to `use`:

```
import { use, Suspense } from "react";



function Message({ messagePromise }) {

  const messageContent = use(messagePromise);

  return <p>Here is the message: {messageContent}</p>;

}



export function MessageContainer({ messagePromise }) {

  return (

    <Suspense fallback={<p>⌛Downloading message...</p>}>

      <Message messagePromise={messagePromise} />

    </Suspense>

  );

}
```

We’re still working out the details, but we expect that in the future, you’ll write data fetching like this:

```
import { use } from 'react';



function ShippingForm({ country }) {

  const cities = use(fetch(`/api/cities?country=${country}`));

  const [city, setCity] = useState(null);

  const areas = city ? use(fetch(`/api/areas?city=${city}`)) : null;

  // ...
```

If you use custom Hooks like `useData` above in your app, it will require fewer changes to migrate to the eventually recommended approach than if you write raw Effects in every component manually. However, the old approach will still work fine, so if you feel happy writing raw Effects, you can continue to do that.

### There is more than one way to do it[](#there-is-more-than-one-way-to-do-it "Link for There is more than one way to do it ")

Let’s say you want to implement a fade-in animation *from scratch* using the browser [`requestAnimationFrame`](https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame) API. You might start with an Effect that sets up an animation loop. During each frame of the animation, you could change the opacity of the DOM node you [hold in a ref](/learn/manipulating-the-dom-with-refs) until it reaches `1`. Your code might start like this:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useEffect, useRef } from 'react';

function Welcome() {
  const ref = useRef(null);

  useEffect(() => {
    const duration = 1000;
    const node = ref.current;

    let startTime = performance.now();
    let frameId = null;

    function onFrame(now) {
      const timePassed = now - startTime;
      const progress = Math.min(timePassed / duration, 1);
      onProgress(progress);
      if (progress < 1) {
        // We still have more frames to paint
        frameId = requestAnimationFrame(onFrame);
      }
    }

    function onProgress(progress) {
      node.style.opacity = progress;
    }

    function start() {
      onProgress(0);
      startTime = performance.now();
      frameId = requestAnimationFrame(onFrame);
    }

    function stop() {
      cancelAnimationFrame(frameId);
      startTime = null;
      frameId = null;
    }

    start();
    return () => stop();
  }, []);

  return (
    <h1 className="welcome" ref={ref}>
      Welcome
    </h1>
  );
}

export default function App() {
  const [show, setShow] = useState(false);
  return (
    <>
      <button onClick={() => setShow(!show)}>
        {show ? 'Remove' : 'Show'}
      </button>
      <hr />
      {show && <Welcome />}
    </>
  );
}
```

To make the component more readable, you might extract the logic into a `useFadeIn` custom Hook:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useEffect, useRef } from 'react';
import { useFadeIn } from './useFadeIn.js';

function Welcome() {
  const ref = useRef(null);

  useFadeIn(ref, 1000);

  return (
    <h1 className="welcome" ref={ref}>
      Welcome
    </h1>
  );
}

export default function App() {
  const [show, setShow] = useState(false);
  return (
    <>
      <button onClick={() => setShow(!show)}>
        {show ? 'Remove' : 'Show'}
      </button>
      <hr />
      {show && <Welcome />}
    </>
  );
}
```

You could keep the `useFadeIn` code as is, but you could also refactor it more. For example, you could extract the logic for setting up the animation loop out of `useFadeIn` into a custom `useAnimationLoop` Hook:

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useEffect } from 'react';
import { useEffectEvent } from 'react';

export function useFadeIn(ref, duration) {
  const [isRunning, setIsRunning] = useState(true);

  useAnimationLoop(isRunning, (timePassed) => {
    const progress = Math.min(timePassed / duration, 1);
    ref.current.style.opacity = progress;
    if (progress === 1) {
      setIsRunning(false);
    }
  });
}

function useAnimationLoop(isRunning, drawFrame) {
  const onFrame = useEffectEvent(drawFrame);

  useEffect(() => {
    if (!isRunning) {
      return;
    }

    const startTime = performance.now();
    let frameId = null;

    function tick(now) {
      const timePassed = now - startTime;
      onFrame(timePassed);
      frameId = requestAnimationFrame(tick);
    }

    tick();
    return () => cancelAnimationFrame(frameId);
  }, [isRunning]);
}
```

However, you didn’t *have to* do that. As with regular functions, ultimately you decide where to draw the boundaries between different parts of your code. You could also take a very different approach. Instead of keeping the logic in the Effect, you could move most of the imperative logic inside a JavaScript [class:](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes)

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useEffect } from 'react';
import { FadeInAnimation } from './animation.js';

export function useFadeIn(ref, duration) {
  useEffect(() => {
    const animation = new FadeInAnimation(ref.current);
    animation.start(duration);
    return () => {
      animation.stop();
    };
  }, [ref, duration]);
}
```

Effects let you connect React to external systems. The more coordination between Effects is needed (for example, to chain multiple animations), the more it makes sense to extract that logic out of Effects and Hooks *completely* like in the sandbox above. Then, the code you extracted *becomes* the “external system”. This lets your Effects stay simple because they only need to send messages to the system you’ve moved outside React.

The examples above assume that the fade-in logic needs to be written in JavaScript. However, this particular fade-in animation is both simpler and much more efficient to implement with a plain [CSS Animation:](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Animations/Using_CSS_animations)

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
.welcome {
  color: white;
  padding: 50px;
  text-align: center;
  font-size: 50px;
  background-image: radial-gradient(circle, rgba(63,94,251,1) 0%, rgba(252,70,107,1) 100%);

  animation: fadeIn 1000ms;
}

@keyframes fadeIn {
  0% { opacity: 0; }
  100% { opacity: 1; }
}
```

```
export default function Counter() {

  const count = useCounter();

  return <h1>Seconds passed: {count}</h1>;

}
```

You’ll need to write your custom Hook in `useCounter.js` and import it into the `App.js` file.

[Fork](https://codesandbox.io/api/v1/sandboxes/define?undefined\&environment=create-react-app "Open in CodeSandbox")

```
import { useState, useEffect } from 'react';

export default function Counter() {
  const [count, setCount] = useState(0);
  useEffect(() => {
    const id = setInterval(() => {
      setCount(c => c + 1);
    }, 1000);
    return () => clearInterval(id);
  }, []);
  return <h1>Seconds passed: {count}</h1>;
}
```

[PreviousRemoving Effect Dependencies](/learn/removing-effect-dependencies)

***

----
url: https://legacy.reactjs.org/docs/faq-internals.html
----

### [](#what-is-the-virtual-dom)What is the Virtual DOM?

The virtual DOM (VDOM) is a programming concept where an ideal, or “virtual”, representation of a UI is kept in memory and synced with the “real” DOM by a library such as ReactDOM. This process is called [reconciliation](/docs/reconciliation.html).

This approach enables the declarative API of React: You tell React what state you want the UI to be in, and it makes sure the DOM matches that state. This abstracts out the attribute manipulation, event handling, and manual DOM updating that you would otherwise have to use to build your app.

Since “virtual DOM” is more of a pattern than a specific technology, people sometimes say it to mean different things. In React world, the term “virtual DOM” is usually associated with [React elements](/docs/rendering-elements.html) since they are the objects representing the user interface. React, however, also uses internal objects called “fibers” to hold additional information about the component tree. They may also be considered a part of “virtual DOM” implementation in React.

### [](#is-the-shadow-dom-the-same-as-the-virtual-dom)Is the Shadow DOM the same as the Virtual DOM?

No, they are different. The Shadow DOM is a browser technology designed primarily for scoping variables and CSS in web components. The virtual DOM is a concept implemented by libraries in JavaScript on top of browser APIs.

### [](#what-is-react-fiber)What is “React Fiber”?

Fiber is the new reconciliation engine in React 16. Its main goal is to enable incremental rendering of the virtual DOM. [Read more](https://github.com/acdlite/react-fiber-architecture).

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/docs/faq-internals.md)

----
url: https://legacy.reactjs.org/blog/2014/10/27/react-js-conf.html
----

October 27, 2014 by [Vjeux](https://twitter.com/vjeux)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

Every few weeks someone asks us when we are going to organize a conference for React. Our answer has always been “some day”. In the mean time, people have been talking about React at other JavaScript conferences around the world. But now the time has finally come for us to have a conference of our own.

**We’re happy to announce [React.js Conf](http://conf.reactjs.com/)! It will take place January 28-29, 2015 on Facebook’s campus in Menlo Park, California.**

Before we open registration, [we’re looking for great talks](http://conf.reactjs.com/call-for-presenters.html). We want to see how you pushed application development forward! If you ever talked to a meet-up, pitched React to your co-workers, or done something awesome and want to talk about it, let us know!

Here are some areas of research we want to explore during the conference if you need some inspiration: server-side rendering, data fetching, language features (eg es6, clojure), immutability, rendering targets (eg svg, canvas), real-time updates…

We look forward to seeing many of you in person in just a few short months!

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2014-10-27-react-js-conf.md)

----
url: https://18.react.dev/learn/removing-effect-dependencies
----

```
const serverUrl = 'https://localhost:1234';



function ChatRoom({ roomId }) {

  useEffect(() => {

    const connection = createConnection(serverUrl, roomId);

    connection.connect();

    return () => connection.disconnect();

  	// ...

}
```

Then, if you leave the Effect dependencies empty (`[]`), the linter will suggest the correct dependencies:

```
import { useState, useEffect } from 'react';
import { createConnection } from './chat.js';

const serverUrl = 'https://localhost:1234';

function ChatRoom({ roomId }) {
  useEffect(() => {
    const connection = createConnection(serverUrl, roomId);
    connection.connect();
    return () => connection.disconnect();
  }, []); // <-- Fix the mistake here!
  return <h1>Welcome to the {roomId} room!</h1>;
}

export default function App() {
  const [roomId, setRoomId] = useState('general');
  return (
    <>
      <label>
        Choose the chat room:{' '}
        <select
          value={roomId}
          onChange={e => setRoomId(e.target.value)}
        >
          <option value="general">general</option>
          <option value="travel">travel</option>
          <option value="music">music</option>
        </select>
      </label>
      <hr />
      <ChatRoom roomId={roomId} />
    </>
  );
}
```

✅ Connecting to "general" room at https\://localhost:1234...

❌ Disconnected from "general" room at https\://localhost:1234

✅ Connecting to "general" room at https\://localhost:1234...

Fill them in according to what the linter says:

```
function ChatRoom({ roomId }) {

  useEffect(() => {

    const connection = createConnection(serverUrl, roomId);

    connection.connect();

    return () => connection.disconnect();

  }, [roomId]); // ✅ All dependencies declared

  // ...

}
```

[Effects “react” to reactive values.](/learn/lifecycle-of-reactive-effects#effects-react-to-reactive-values) Since `roomId` is a reactive value (it can change due to a re-render), the linter verifies that you’ve specified it as a dependency. If `roomId` receives a different value, React will re-synchronize your Effect. This ensures that the chat stays connected to the selected room and “reacts” to the dropdown:

```
import { useState, useEffect } from 'react';
import { createConnection } from './chat.js';

const serverUrl = 'https://localhost:1234';

function ChatRoom({ roomId }) {
  useEffect(() => {
    const connection = createConnection(serverUrl, roomId);
    connection.connect();
    return () => connection.disconnect();
  }, [roomId]);
  return <h1>Welcome to the {roomId} room!</h1>;
}

export default function App() {
  const [roomId, setRoomId] = useState('general');
  return (
    <>
      <label>
        Choose the chat room:{' '}
        <select
          value={roomId}
          onChange={e => setRoomId(e.target.value)}
        >
          <option value="general">general</option>
          <option value="travel">travel</option>
          <option value="music">music</option>
        </select>
      </label>
      <hr />
      <ChatRoom roomId={roomId} />
    </>
  );
}
```

### To remove a dependency, prove that it’s not a dependency[](#to-remove-a-dependency-prove-that-its-not-a-dependency "Link for To remove a dependency, prove that it’s not a dependency ")

Notice that you can’t “choose” the dependencies of your Effect. Every reactive value used by your Effect’s code must be declared in your dependency list. The dependency list is determined by the surrounding code:

```
const serverUrl = 'https://localhost:1234';



function ChatRoom({ roomId }) { // This is a reactive value

  useEffect(() => {

    const connection = createConnection(serverUrl, roomId); // This Effect reads that reactive value

    connection.connect();

    return () => connection.disconnect();

  }, [roomId]); // ✅ So you must specify that reactive value as a dependency of your Effect

  // ...

}
```

[Reactive values](/learn/lifecycle-of-reactive-effects#all-variables-declared-in-the-component-body-are-reactive) include props and all variables and functions declared directly inside of your component. Since `roomId` is a reactive value, you can’t remove it from the dependency list. The linter wouldn’t allow it:

```
const serverUrl = 'https://localhost:1234';



function ChatRoom({ roomId }) {

  useEffect(() => {

    const connection = createConnection(serverUrl, roomId);

    connection.connect();

    return () => connection.disconnect();

  }, []); // 🔴 React Hook useEffect has a missing dependency: 'roomId'

  // ...

}
```

And the linter would be right! Since `roomId` may change over time, this would introduce a bug in your code.

**To remove a dependency, “prove” to the linter that it *doesn’t need* to be a dependency.** For example, you can move `roomId` out of your component to prove that it’s not reactive and won’t change on re-renders:

```
const serverUrl = 'https://localhost:1234';

const roomId = 'music'; // Not a reactive value anymore



function ChatRoom() {

  useEffect(() => {

    const connection = createConnection(serverUrl, roomId);

    connection.connect();

    return () => connection.disconnect();

  }, []); // ✅ All dependencies declared

  // ...

}
```

Now that `roomId` is not a reactive value (and can’t change on a re-render), it doesn’t need to be a dependency:

```
import { useState, useEffect } from 'react';
import { createConnection } from './chat.js';

const serverUrl = 'https://localhost:1234';
const roomId = 'music';

export default function ChatRoom() {
  useEffect(() => {
    const connection = createConnection(serverUrl, roomId);
    connection.connect();
    return () => connection.disconnect();
  }, []);
  return <h1>Welcome to the {roomId} room!</h1>;
}
```

```
useEffect(() => {

  // ...

  // 🔴 Avoid suppressing the linter like this:

  // eslint-ignore-next-line react-hooks/exhaustive-deps

}, []);
```

**When dependencies don’t match the code, there is a very high risk of introducing bugs.** By suppressing the linter, you “lie” to React about the values your Effect depends on.

Instead, use the techniques below.

##### Deep Dive#### Why is suppressing the dependency linter so dangerous?[](#why-is-suppressing-the-dependency-linter-so-dangerous "Link for Why is suppressing the dependency linter so dangerous? ")

Suppressing the linter leads to very unintuitive bugs that are hard to find and fix. Here’s one example:

```
import { useState, useEffect } from 'react';

export default function Timer() {
  const [count, setCount] = useState(0);
  const [increment, setIncrement] = useState(1);

  function onTick() {
	setCount(count + increment);
  }

  useEffect(() => {
    const id = setInterval(onTick, 1000);
    return () => clearInterval(id);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  return (
    <>
      <h1>
        Counter: {count}
        <button onClick={() => setCount(0)}>Reset</button>
      </h1>
      <hr />
      <p>
        Every second, increment by:
        <button disabled={increment === 0} onClick={() => {
          setIncrement(i => i - 1);
        }}>–</button>
        <b>{increment}</b>
        <button onClick={() => {
          setIncrement(i => i + 1);
        }}>+</button>
      </p>
    </>
  );
}
```

```
function Form() {

  const [submitted, setSubmitted] = useState(false);



  useEffect(() => {

    if (submitted) {

      // 🔴 Avoid: Event-specific logic inside an Effect

      post('/api/register');

      showNotification('Successfully registered!');

    }

  }, [submitted]);



  function handleSubmit() {

    setSubmitted(true);

  }



  // ...

}
```

Later, you want to style the notification message according to the current theme, so you read the current theme. Since `theme` is declared in the component body, it is a reactive value, so you add it as a dependency:

```
function Form() {

  const [submitted, setSubmitted] = useState(false);

  const theme = useContext(ThemeContext);



  useEffect(() => {

    if (submitted) {

      // 🔴 Avoid: Event-specific logic inside an Effect

      post('/api/register');

      showNotification('Successfully registered!', theme);

    }

  }, [submitted, theme]); // ✅ All dependencies declared



  function handleSubmit() {

    setSubmitted(true);

  }  



  // ...

}
```

By doing this, you’ve introduced a bug. Imagine you submit the form first and then switch between Dark and Light themes. The `theme` will change, the Effect will re-run, and so it will display the same notification again!

**The problem here is that this shouldn’t be an Effect in the first place.** You want to send this POST request and show the notification in response to *submitting the form,* which is a particular interaction. To run some code in response to particular interaction, put that logic directly into the corresponding event handler:

```
function Form() {

  const theme = useContext(ThemeContext);



  function handleSubmit() {

    // ✅ Good: Event-specific logic is called from event handlers

    post('/api/register');

    showNotification('Successfully registered!', theme);

  }  



  // ...

}
```

Now that the code is in an event handler, it’s not reactive—so it will only run when the user submits the form. Read more about [choosing between event handlers and Effects](/learn/separating-events-from-effects#reactive-values-and-reactive-logic) and [how to delete unnecessary Effects.](/learn/you-might-not-need-an-effect)

### Is your Effect doing several unrelated things?[](#is-your-effect-doing-several-unrelated-things "Link for Is your Effect doing several unrelated things? ")

The next question you should ask yourself is whether your Effect is doing several unrelated things.

Imagine you’re creating a shipping form where the user needs to choose their city and area. You fetch the list of `cities` from the server according to the selected `country` to show them in a dropdown:

```
function ShippingForm({ country }) {

  const [cities, setCities] = useState(null);

  const [city, setCity] = useState(null);



  useEffect(() => {

    let ignore = false;

    fetch(`/api/cities?country=${country}`)

      .then(response => response.json())

      .then(json => {

        if (!ignore) {

          setCities(json);

        }

      });

    return () => {

      ignore = true;

    };

  }, [country]); // ✅ All dependencies declared



  // ...
```

This is a good example of [fetching data in an Effect.](/learn/you-might-not-need-an-effect#fetching-data) You are synchronizing the `cities` state with the network according to the `country` prop. You can’t do this in an event handler because you need to fetch as soon as `ShippingForm` is displayed and whenever the `country` changes (no matter which interaction causes it).

Now let’s say you’re adding a second select box for city areas, which should fetch the `areas` for the currently selected `city`. You might start by adding a second `fetch` call for the list of areas inside the same Effect:

```
function ShippingForm({ country }) {

  const [cities, setCities] = useState(null);

  const [city, setCity] = useState(null);

  const [areas, setAreas] = useState(null);



  useEffect(() => {

    let ignore = false;

    fetch(`/api/cities?country=${country}`)

      .then(response => response.json())

      .then(json => {

        if (!ignore) {

          setCities(json);

        }

      });

    // 🔴 Avoid: A single Effect synchronizes two independent processes

    if (city) {

      fetch(`/api/areas?city=${city}`)

        .then(response => response.json())

        .then(json => {

          if (!ignore) {

            setAreas(json);

          }

        });

    }

    return () => {

      ignore = true;

    };

  }, [country, city]); // ✅ All dependencies declared



  // ...
```

However, since the Effect now uses the `city` state variable, you’ve had to add `city` to the list of dependencies. That, in turn, introduced a problem: when the user selects a different city, the Effect will re-run and call `fetchCities(country)`. As a result, you will be unnecessarily refetching the list of cities many times.

**The problem with this code is that you’re synchronizing two different unrelated things:**

1. You want to synchronize the `cities` state to the network based on the `country` prop.
2. You want to synchronize the `areas` state to the network based on the `city` state.

Split the logic into two Effects, each of which reacts to the prop that it needs to synchronize with:

```
function ShippingForm({ country }) {

  const [cities, setCities] = useState(null);

  useEffect(() => {

    let ignore = false;

    fetch(`/api/cities?country=${country}`)

      .then(response => response.json())

      .then(json => {

        if (!ignore) {

          setCities(json);

        }

      });

    return () => {

      ignore = true;

    };

  }, [country]); // ✅ All dependencies declared



  const [city, setCity] = useState(null);

  const [areas, setAreas] = useState(null);

  useEffect(() => {

    if (city) {

      let ignore = false;

      fetch(`/api/areas?city=${city}`)

        .then(response => response.json())

        .then(json => {

          if (!ignore) {

            setAreas(json);

          }

        });

      return () => {

        ignore = true;

      };

    }

  }, [city]); // ✅ All dependencies declared



  // ...
```

Now the first Effect only re-runs if the `country` changes, while the second Effect re-runs when the `city` changes. You’ve separated them by purpose: two different things are synchronized by two separate Effects. Two separate Effects have two separate dependency lists, so they won’t trigger each other unintentionally.

The final code is longer than the original, but splitting these Effects is still correct. [Each Effect should represent an independent synchronization process.](/learn/lifecycle-of-reactive-effects#each-effect-represents-a-separate-synchronization-process) In this example, deleting one Effect doesn’t break the other Effect’s logic. This means they *synchronize different things,* and it’s good to split them up. If you’re concerned about duplication, you can improve this code by [extracting repetitive logic into a custom Hook.](/learn/reusing-logic-with-custom-hooks#when-to-use-custom-hooks)

### Are you reading some state to calculate the next state?[](#are-you-reading-some-state-to-calculate-the-next-state "Link for Are you reading some state to calculate the next state? ")

This Effect updates the `messages` state variable with a newly created array every time a new message arrives:

```
function ChatRoom({ roomId }) {

  const [messages, setMessages] = useState([]);

  useEffect(() => {

    const connection = createConnection();

    connection.connect();

    connection.on('message', (receivedMessage) => {

      setMessages([...messages, receivedMessage]);

    });

    // ...
```

It uses the `messages` variable to [create a new array](/learn/updating-arrays-in-state) starting with all the existing messages and adds the new message at the end. However, since `messages` is a reactive value read by an Effect, it must be a dependency:

```
function ChatRoom({ roomId }) {

  const [messages, setMessages] = useState([]);

  useEffect(() => {

    const connection = createConnection();

    connection.connect();

    connection.on('message', (receivedMessage) => {

      setMessages([...messages, receivedMessage]);

    });

    return () => connection.disconnect();

  }, [roomId, messages]); // ✅ All dependencies declared

  // ...
```

And making `messages` a dependency introduces a problem.

Every time you receive a message, `setMessages()` causes the component to re-render with a new `messages` array that includes the received message. However, since this Effect now depends on `messages`, this will *also* re-synchronize the Effect. So every new message will make the chat re-connect. The user would not like that!

To fix the issue, don’t read `messages` inside the Effect. Instead, pass an [updater function](/reference/react/useState#updating-state-based-on-the-previous-state) to `setMessages`:

```
function ChatRoom({ roomId }) {

  const [messages, setMessages] = useState([]);

  useEffect(() => {

    const connection = createConnection();

    connection.connect();

    connection.on('message', (receivedMessage) => {

      setMessages(msgs => [...msgs, receivedMessage]);

    });

    return () => connection.disconnect();

  }, [roomId]); // ✅ All dependencies declared

  // ...
```

**Notice how your Effect does not read the `messages` variable at all now.** You only need to pass an updater function like `msgs => [...msgs, receivedMessage]`. React [puts your updater function in a queue](/learn/queueing-a-series-of-state-updates) and will provide the `msgs` argument to it during the next render. This is why the Effect itself doesn’t need to depend on `messages` anymore. As a result of this fix, receiving a chat message will no longer make the chat re-connect.

### Do you want to read a value without “reacting” to its changes?[](#do-you-want-to-read-a-value-without-reacting-to-its-changes "Link for Do you want to read a value without “reacting” to its changes? ")

### Under Construction

This section describes an **experimental API that has not yet been released** in a stable version of React.

Suppose that you want to play a sound when the user receives a new message unless `isMuted` is `true`:

```
function ChatRoom({ roomId }) {

  const [messages, setMessages] = useState([]);

  const [isMuted, setIsMuted] = useState(false);



  useEffect(() => {

    const connection = createConnection();

    connection.connect();

    connection.on('message', (receivedMessage) => {

      setMessages(msgs => [...msgs, receivedMessage]);

      if (!isMuted) {

        playSound();

      }

    });

    // ...
```

Since your Effect now uses `isMuted` in its code, you have to add it to the dependencies:

```
function ChatRoom({ roomId }) {

  const [messages, setMessages] = useState([]);

  const [isMuted, setIsMuted] = useState(false);



  useEffect(() => {

    const connection = createConnection();

    connection.connect();

    connection.on('message', (receivedMessage) => {

      setMessages(msgs => [...msgs, receivedMessage]);

      if (!isMuted) {

        playSound();

      }

    });

    return () => connection.disconnect();

  }, [roomId, isMuted]); // ✅ All dependencies declared

  // ...
```

The problem is that every time `isMuted` changes (for example, when the user presses the “Muted” toggle), the Effect will re-synchronize, and reconnect to the chat. This is not the desired user experience! (In this example, even disabling the linter would not work—if you do that, `isMuted` would get “stuck” with its old value.)

To solve this problem, you need to extract the logic that shouldn’t be reactive out of the Effect. You don’t want this Effect to “react” to the changes in `isMuted`. [Move this non-reactive piece of logic into an Effect Event:](/learn/separating-events-from-effects#declaring-an-effect-event)

```
import { useState, useEffect, useEffectEvent } from 'react';



function ChatRoom({ roomId }) {

  const [messages, setMessages] = useState([]);

  const [isMuted, setIsMuted] = useState(false);



  const onMessage = useEffectEvent(receivedMessage => {

    setMessages(msgs => [...msgs, receivedMessage]);

    if (!isMuted) {

      playSound();

    }

  });



  useEffect(() => {

    const connection = createConnection();

    connection.connect();

    connection.on('message', (receivedMessage) => {

      onMessage(receivedMessage);

    });

    return () => connection.disconnect();

  }, [roomId]); // ✅ All dependencies declared

  // ...
```

Effect Events let you split an Effect into reactive parts (which should “react” to reactive values like `roomId` and their changes) and non-reactive parts (which only read their latest values, like `onMessage` reads `isMuted`). **Now that you read `isMuted` inside an Effect Event, it doesn’t need to be a dependency of your Effect.** As a result, the chat won’t re-connect when you toggle the “Muted” setting on and off, solving the original issue!

#### Wrapping an event handler from the props[](#wrapping-an-event-handler-from-the-props "Link for Wrapping an event handler from the props ")

You might run into a similar problem when your component receives an event handler as a prop:

```
function ChatRoom({ roomId, onReceiveMessage }) {

  const [messages, setMessages] = useState([]);



  useEffect(() => {

    const connection = createConnection();

    connection.connect();

    connection.on('message', (receivedMessage) => {

      onReceiveMessage(receivedMessage);

    });

    return () => connection.disconnect();

  }, [roomId, onReceiveMessage]); // ✅ All dependencies declared

  // ...
```

Suppose that the parent component passes a *different* `onReceiveMessage` function on every render:

```
<ChatRoom

  roomId={roomId}

  onReceiveMessage={receivedMessage => {

    // ...

  }}

/>
```

Since `onReceiveMessage` is a dependency, it would cause the Effect to re-synchronize after every parent re-render. This would make it re-connect to the chat. To solve this, wrap the call in an Effect Event:

```
function ChatRoom({ roomId, onReceiveMessage }) {

  const [messages, setMessages] = useState([]);



  const onMessage = useEffectEvent(receivedMessage => {

    onReceiveMessage(receivedMessage);

  });



  useEffect(() => {

    const connection = createConnection();

    connection.connect();

    connection.on('message', (receivedMessage) => {

      onMessage(receivedMessage);

    });

    return () => connection.disconnect();

  }, [roomId]); // ✅ All dependencies declared

  // ...
```

Effect Events aren’t reactive, so you don’t need to specify them as dependencies. As a result, the chat will no longer re-connect even if the parent component passes a function that’s different on every re-render.

#### Separating reactive and non-reactive code[](#separating-reactive-and-non-reactive-code "Link for Separating reactive and non-reactive code ")

In this example, you want to log a visit every time `roomId` changes. You want to include the current `notificationCount` with every log, but you *don’t* want a change to `notificationCount` to trigger a log event.

The solution is again to split out the non-reactive code into an Effect Event:

```
function Chat({ roomId, notificationCount }) {

  const onVisit = useEffectEvent(visitedRoomId => {

    logVisit(visitedRoomId, notificationCount);

  });



  useEffect(() => {

    onVisit(roomId);

  }, [roomId]); // ✅ All dependencies declared

  // ...

}
```

You want your logic to be reactive with regards to `roomId`, so you read `roomId` inside of your Effect. However, you don’t want a change to `notificationCount` to log an extra visit, so you read `notificationCount` inside of the Effect Event. [Learn more about reading the latest props and state from Effects using Effect Events.](/learn/separating-events-from-effects#reading-latest-props-and-state-with-effect-events)

### Does some reactive value change unintentionally?[](#does-some-reactive-value-change-unintentionally "Link for Does some reactive value change unintentionally? ")

Sometimes, you *do* want your Effect to “react” to a certain value, but that value changes more often than you’d like—and might not reflect any actual change from the user’s perspective. For example, let’s say that you create an `options` object in the body of your component, and then read that object from inside of your Effect:

```
function ChatRoom({ roomId }) {

  // ...

  const options = {

    serverUrl: serverUrl,

    roomId: roomId

  };



  useEffect(() => {

    const connection = createConnection(options);

    connection.connect();

    // ...
```

This object is declared in the component body, so it’s a [reactive value.](/learn/lifecycle-of-reactive-effects#effects-react-to-reactive-values) When you read a reactive value like this inside an Effect, you declare it as a dependency. This ensures your Effect “reacts” to its changes:

```
  // ...

  useEffect(() => {

    const connection = createConnection(options);

    connection.connect();

    return () => connection.disconnect();

  }, [options]); // ✅ All dependencies declared

  // ...
```

It is important to declare it as a dependency! This ensures, for example, that if the `roomId` changes, your Effect will re-connect to the chat with the new `options`. However, there is also a problem with the code above. To see it, try typing into the input in the sandbox below, and watch what happens in the console:

```
import { useState, useEffect } from 'react';
import { createConnection } from './chat.js';

const serverUrl = 'https://localhost:1234';

function ChatRoom({ roomId }) {
  const [message, setMessage] = useState('');

  // Temporarily disable the linter to demonstrate the problem
  // eslint-disable-next-line react-hooks/exhaustive-deps
  const options = {
    serverUrl: serverUrl,
    roomId: roomId
  };

  useEffect(() => {
    const connection = createConnection(options);
    connection.connect();
    return () => connection.disconnect();
  }, [options]);

  return (
    <>
      <h1>Welcome to the {roomId} room!</h1>
      <input value={message} onChange={e => setMessage(e.target.value)} />
    </>
  );
}

export default function App() {
  const [roomId, setRoomId] = useState('general');
  return (
    <>
      <label>
        Choose the chat room:{' '}
        <select
          value={roomId}
          onChange={e => setRoomId(e.target.value)}
        >
          <option value="general">general</option>
          <option value="travel">travel</option>
          <option value="music">music</option>
        </select>
      </label>
      <hr />
      <ChatRoom roomId={roomId} />
    </>
  );
}
```

In the sandbox above, the input only updates the `message` state variable. From the user’s perspective, this should not affect the chat connection. However, every time you update the `message`, your component re-renders. When your component re-renders, the code inside of it runs again from scratch.

A new `options` object is created from scratch on every re-render of the `ChatRoom` component. React sees that the `options` object is a *different object* from the `options` object created during the last render. This is why it re-synchronizes your Effect (which depends on `options`), and the chat re-connects as you type.

**This problem only affects objects and functions. In JavaScript, each newly created object and function is considered distinct from all the others. It doesn’t matter that the contents inside of them may be the same!**

```
// During the first render

const options1 = { serverUrl: 'https://localhost:1234', roomId: 'music' };



// During the next render

const options2 = { serverUrl: 'https://localhost:1234', roomId: 'music' };



// These are two different objects!

console.log(Object.is(options1, options2)); // false
```

**Object and function dependencies can make your Effect re-synchronize more often than you need.**

This is why, whenever possible, you should try to avoid objects and functions as your Effect’s dependencies. Instead, try moving them outside the component, inside the Effect, or extracting primitive values out of them.

#### Move static objects and functions outside your component[](#move-static-objects-and-functions-outside-your-component "Link for Move static objects and functions outside your component ")

If the object does not depend on any props and state, you can move that object outside your component:

```
const options = {

  serverUrl: 'https://localhost:1234',

  roomId: 'music'

};



function ChatRoom() {

  const [message, setMessage] = useState('');



  useEffect(() => {

    const connection = createConnection(options);

    connection.connect();

    return () => connection.disconnect();

  }, []); // ✅ All dependencies declared

  // ...
```

This way, you *prove* to the linter that it’s not reactive. It can’t change as a result of a re-render, so it doesn’t need to be a dependency. Now re-rendering `ChatRoom` won’t cause your Effect to re-synchronize.

This works for functions too:

```
function createOptions() {

  return {

    serverUrl: 'https://localhost:1234',

    roomId: 'music'

  };

}



function ChatRoom() {

  const [message, setMessage] = useState('');



  useEffect(() => {

    const options = createOptions();

    const connection = createConnection(options);

    connection.connect();

    return () => connection.disconnect();

  }, []); // ✅ All dependencies declared

  // ...
```

Since `createOptions` is declared outside your component, it’s not a reactive value. This is why it doesn’t need to be specified in your Effect’s dependencies, and why it won’t ever cause your Effect to re-synchronize.

#### Move dynamic objects and functions inside your Effect[](#move-dynamic-objects-and-functions-inside-your-effect "Link for Move dynamic objects and functions inside your Effect ")

If your object depends on some reactive value that may change as a result of a re-render, like a `roomId` prop, you can’t pull it *outside* your component. You can, however, move its creation *inside* of your Effect’s code:

```
const serverUrl = 'https://localhost:1234';



function ChatRoom({ roomId }) {

  const [message, setMessage] = useState('');



  useEffect(() => {

    const options = {

      serverUrl: serverUrl,

      roomId: roomId

    };

    const connection = createConnection(options);

    connection.connect();

    return () => connection.disconnect();

  }, [roomId]); // ✅ All dependencies declared

  // ...
```

Now that `options` is declared inside of your Effect, it is no longer a dependency of your Effect. Instead, the only reactive value used by your Effect is `roomId`. Since `roomId` is not an object or function, you can be sure that it won’t be *unintentionally* different. In JavaScript, numbers and strings are compared by their content:

```
// During the first render

const roomId1 = 'music';



// During the next render

const roomId2 = 'music';



// These two strings are the same!

console.log(Object.is(roomId1, roomId2)); // true
```

Thanks to this fix, the chat no longer re-connects if you edit the input:

```
import { useState, useEffect } from 'react';
import { createConnection } from './chat.js';

const serverUrl = 'https://localhost:1234';

function ChatRoom({ roomId }) {
  const [message, setMessage] = useState('');

  useEffect(() => {
    const options = {
      serverUrl: serverUrl,
      roomId: roomId
    };
    const connection = createConnection(options);
    connection.connect();
    return () => connection.disconnect();
  }, [roomId]);

  return (
    <>
      <h1>Welcome to the {roomId} room!</h1>
      <input value={message} onChange={e => setMessage(e.target.value)} />
    </>
  );
}

export default function App() {
  const [roomId, setRoomId] = useState('general');
  return (
    <>
      <label>
        Choose the chat room:{' '}
        <select
          value={roomId}
          onChange={e => setRoomId(e.target.value)}
        >
          <option value="general">general</option>
          <option value="travel">travel</option>
          <option value="music">music</option>
        </select>
      </label>
      <hr />
      <ChatRoom roomId={roomId} />
    </>
  );
}
```

However, it *does* re-connect when you change the `roomId` dropdown, as you would expect.

This works for functions, too:

```
const serverUrl = 'https://localhost:1234';



function ChatRoom({ roomId }) {

  const [message, setMessage] = useState('');



  useEffect(() => {

    function createOptions() {

      return {

        serverUrl: serverUrl,

        roomId: roomId

      };

    }



    const options = createOptions();

    const connection = createConnection(options);

    connection.connect();

    return () => connection.disconnect();

  }, [roomId]); // ✅ All dependencies declared

  // ...
```

You can write your own functions to group pieces of logic inside your Effect. As long as you also declare them *inside* your Effect, they’re not reactive values, and so they don’t need to be dependencies of your Effect.

#### Read primitive values from objects[](#read-primitive-values-from-objects "Link for Read primitive values from objects ")

Sometimes, you may receive an object from props:

```
function ChatRoom({ options }) {

  const [message, setMessage] = useState('');



  useEffect(() => {

    const connection = createConnection(options);

    connection.connect();

    return () => connection.disconnect();

  }, [options]); // ✅ All dependencies declared

  // ...
```

The risk here is that the parent component will create the object during rendering:

```
<ChatRoom

  roomId={roomId}

  options={{

    serverUrl: serverUrl,

    roomId: roomId

  }}

/>
```

This would cause your Effect to re-connect every time the parent component re-renders. To fix this, read information from the object *outside* the Effect, and avoid having object and function dependencies:

```
function ChatRoom({ options }) {

  const [message, setMessage] = useState('');



  const { roomId, serverUrl } = options;

  useEffect(() => {

    const connection = createConnection({

      roomId: roomId,

      serverUrl: serverUrl

    });

    connection.connect();

    return () => connection.disconnect();

  }, [roomId, serverUrl]); // ✅ All dependencies declared

  // ...
```

The logic gets a little repetitive (you read some values from an object outside an Effect, and then create an object with the same values inside the Effect). But it makes it very explicit what information your Effect *actually* depends on. If an object is re-created unintentionally by the parent component, the chat would not re-connect. However, if `options.roomId` or `options.serverUrl` really are different, the chat would re-connect.

#### Calculate primitive values from functions[](#calculate-primitive-values-from-functions "Link for Calculate primitive values from functions ")

The same approach can work for functions. For example, suppose the parent component passes a function:

```
<ChatRoom

  roomId={roomId}

  getOptions={() => {

    return {

      serverUrl: serverUrl,

      roomId: roomId

    };

  }}

/>
```

To avoid making it a dependency (and causing it to re-connect on re-renders), call it outside the Effect. This gives you the `roomId` and `serverUrl` values that aren’t objects, and that you can read from inside your Effect:

```
function ChatRoom({ getOptions }) {

  const [message, setMessage] = useState('');



  const { roomId, serverUrl } = getOptions();

  useEffect(() => {

    const connection = createConnection({

      roomId: roomId,

      serverUrl: serverUrl

    });

    connection.connect();

    return () => connection.disconnect();

  }, [roomId, serverUrl]); // ✅ All dependencies declared

  // ...
```

```
import { useState, useEffect } from 'react';

export default function Timer() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    console.log('✅ Creating an interval');
    const id = setInterval(() => {
      console.log('⏰ Interval tick');
      setCount(count + 1);
    }, 1000);
    return () => {
      console.log('❌ Clearing an interval');
      clearInterval(id);
    };
  }, [count]);

  return <h1>Counter: {count}</h1>
}
```

[PreviousSeparating Events from Effects](/learn/separating-events-from-effects)

[NextReusing Logic with Custom Hooks](/learn/reusing-logic-with-custom-hooks)

***

----
url: https://legacy.reactjs.org/blog/2014/07/30/flux-actions-and-the-dispatcher.html
----

July 30, 2014 by [Bill Fisher](https://twitter.com/fisherwebdev)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

Flux is the application architecture Facebook uses to build JavaScript applications. It’s based on a unidirectional data flow. We’ve built everything from small widgets to huge applications with Flux, and it’s handled everything we’ve thrown at it. Because we’ve found it to be a great way to structure our code, we’re excited to share it with the open source community. [Jing Chen presented Flux](http://youtu.be/nYkdrAPrdcw?t=10m20s) at the F8 conference, and since that time we’ve seen a lot of interest in it. We’ve also published an [overview of Flux](https://facebook.github.io/flux/docs/overview.html) and a [TodoMVC example](https://github.com/facebook/flux/tree/master/examples/flux-todomvc/), with an accompanying [tutorial](https://facebook.github.io/flux/docs/todo-list.html).

Flux is more of a pattern than a full-blown framework, and you can start using it without a lot of new code beyond React. Up until recently, however, we haven’t released one crucial piece of our Flux software: the dispatcher. But along with the creation of the new [Flux code repository](https://github.com/facebook/flux) and [Flux website](https://facebook.github.io/flux/), we’ve now open sourced the same [dispatcher](https://facebook.github.io/flux/docs/dispatcher.html) we use in our production applications.

## [](#where-the-dispatcher-fits-in-the-flux-data-flow)Where the Dispatcher Fits in the Flux Data Flow

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

The dispatcher is a singleton, and operates as the central hub of data flow in a Flux application. It is essentially a registry of callbacks, and can invoke these callbacks in order. Each *store* registers a callback with the dispatcher. When new data comes into the dispatcher, it then uses these callbacks to propagate that data to all of the stores. The process of invoking the callbacks is initiated through the dispatch() method, which takes a data payload object as its sole argument.

## [](#actions-and-actioncreators)Actions and ActionCreators

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

When new data enters the system, whether through a person interacting with the application or through a web api call, that data is packaged into an *action* — an object literal containing the new fields of data and a specific action type. We often create a library of helper methods called ActionCreators that not only create the action object, but also pass the action to the dispatcher.

Different actions are identified by a type attribute. When all of the stores receive the action, they typically use this attribute to determine if and how they should respond to it. In a Flux application, both stores and views control themselves; they are not acted upon by external objects. Actions flow into the stores through the callbacks they define and register, not through setter methods.

Letting the stores update themselves eliminates many entanglements typically found in MVC applications, where cascading updates between models can lead to unstable state and make accurate testing very difficult. The objects within a Flux application are highly decoupled, and adhere very strongly to the [Law of Demeter](https://en.wikipedia.org/wiki/Law_of_Demeter), the principle that each object within a system should know as little as possible about the other objects in the system. This results in software that is more maintainable, adaptable, testable, and easier for new engineering team members to understand.

[](/static/b4643456a3de61c8352415a6fc171876/c658e/flux-diagram.png)

## [](#why-we-need-a-dispatcher)Why We Need a Dispatcher

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

As an application grows, dependencies across different stores are a near certainty. Store A will inevitably need Store B to update itself first, so that Store A can know how to update itself. We need the dispatcher to be able to invoke the callback for Store B, and finish that callback, before moving forward with Store A. To declaratively assert this dependency, a store needs to be able to say to the dispatcher, “I need to wait for Store B to finish processing this action.” The dispatcher provides this functionality through its waitFor() method.

The dispatch() method provides a simple, synchronous iteration through the callbacks, invoking each in turn. When waitFor() is encountered within one of the callbacks, execution of that callback stops and waitFor() provides us with a new iteration cycle over the dependencies. After the entire set of dependencies have been fulfilled, the original callback then continues to execute.

Further, the waitFor() method may be used in different ways for different actions, within the same store’s callback. In one case, Store A might need to wait for Store B. But in another case, it might need to wait for Store C. Using waitFor() within the code block that is specific to an action allows us to have fine-grained control of these dependencies.

Problems arise, however, if we have circular dependencies. That is, if Store A needs to wait for Store B, and Store B needs to wait for Store A, we could wind up in an endless loop. The dispatcher now available in the Flux repo protects against this by throwing an informative error to alert the developer that this problem has occurred. The developer can then create a third store and resolve the circular dependency.

## [](#example-chat-app)Example Chat App

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

Along with the same dispatcher that Facebook uses in its production applications, we’ve also published a new example [chat app](https://github.com/facebook/flux/tree/master/examples/flux-chat), slightly more complicated than the simplistic TodoMVC, so that engineers can better understand how Flux solves problems like dependencies between stores and calls to a web API.

We’re hopeful that the new Flux repository will grow with time to include additional tools, boilerplate code and further examples. And we hope that Flux will prove as useful to you as it has to us. Enjoy!

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2014-07-30-flux-actions-and-the-dispatcher.md)

----
url: https://legacy.reactjs.org/blog/2014/09/03/introducing-the-jsx-specification.html
----

September 03, 2014 by [Sebastian Markbåge](https://twitter.com/sebmarkbage)

> This blog site has been archived. Go to [react.dev/blog](https://react.dev/blog) to see the recent posts.

At Facebook we’ve been using JSX for a long time. We originally introduced it to the world last year alongside React, but we actually used it in another form before that to create native DOM nodes. We’ve also seen some similar efforts grow out of our work in order to be used with other libraries and in interesting ways. At this point React JSX is just one of many implementations.

In order to make it easier to implement new versions and to make sure that the syntax remains compatible, we’re now formalizing the syntax of JSX in a stand-alone spec without any semantic meaning. It’s completely stand-alone from React itself.

Read the spec now at <https://facebook.github.io/jsx/>.

This is not a proposal to be standardized in ECMAScript. It’s just a reference document that transpiler writers and syntax highlighters can agree on. It’s currently in a draft stage and will probably continue to be a living document.

Feel free to [open an Issue](https://github.com/facebook/jsx/issues/new) or Pull Request if you find something wrong.

Is this page useful?[Edit this page](https://github.com/reactjs/reactjs.org/tree/main/content/blog/2014-09-03-introducing-the-jsx-specification.md)

----
url: https://18.react.dev/reference/react/useDeferredValue
----

[API Reference](/reference/react)

[Hooks](/reference/react/hooks)

# useDeferredValue[](#undefined "Link for this heading")

`useDeferredValue` is a React Hook that lets you defer updating a part of the UI.

```
const deferredValue = useDeferredValue(value)
```

* [Reference](#reference)
  * [`useDeferredValue(value, initialValue?)`](#usedeferredvalue)

* [Usage](#usage)

  * [Showing stale content while fresh content is loading](#showing-stale-content-while-fresh-content-is-loading)
  * [Indicating that the content is stale](#indicating-that-the-content-is-stale)
  * [Deferring re-rendering for a part of the UI](#deferring-re-rendering-for-a-part-of-the-ui)

***

## Reference[](#reference "Link for Reference ")

### `useDeferredValue(value, initialValue?)`[](#usedeferredvalue "Link for this heading")

Call `useDeferredValue` at the top level of your component to get a deferred version of that value.

```
import { useState, useDeferredValue } from 'react';



function SearchPage() {

  const [query, setQuery] = useState('');

  const deferredQuery = useDeferredValue(query);

  // ...

}
```

[See more examples below.](#usage)

#### Parameters[](#parameters "Link for Parameters ")

* `value`: The value you want to defer. It can have any type.
* Canary only **optional** `initialValue`: A value to use during the initial render of a component. If this option is omitted, `useDeferredValue` will not defer during the initial render, because there’s no previous version of `value` that it can render instead.

#### Returns[](#returns "Link for Returns ")

* `currentValue`: During the initial render, the returned deferred value will be the same as the value you provided. During updates, React will first attempt a re-render with the old value (so it will return the old value), and then try another re-render in the background with the new value (so it will return the updated value).

### Canary

In the latest React Canary versions, `useDeferredValue` returns the `initialValue` on initial render, and schedules a re-render in the background with the `value` returned.

***

## Usage[](#usage "Link for Usage ")

### Showing stale content while fresh content is loading[](#showing-stale-content-while-fresh-content-is-loading "Link for Showing stale content while fresh content is loading ")

Call `useDeferredValue` at the top level of your component to defer updating some part of your UI.

```
import { useState, useDeferredValue } from 'react';



function SearchPage() {

  const [query, setQuery] = useState('');

  const deferredQuery = useDeferredValue(query);

  // ...

}
```

During the initial render, the deferred value will be the same as the value you provided.

During updates, the deferred value will “lag behind” the latest value. In particular, React will first re-render *without* updating the deferred value, and then try to re-render with the newly received value in the background.

**Let’s walk through an example to see when this is useful.**

### Note

This example assumes you use a Suspense-enabled data source:

* Data fetching with Suspense-enabled frameworks like [Relay](https://relay.dev/docs/guided-tour/rendering/loading-states/) and [Next.js](https://nextjs.org/docs/getting-started/react-essentials)
* Lazy-loading component code with [`lazy`](/reference/react/lazy)
* Reading the value of a Promise with [`use`](/reference/react/use)

[Learn more about Suspense and its limitations.](/reference/react/Suspense)

In this example, the `SearchResults` component [suspends](/reference/react/Suspense#displaying-a-fallback-while-content-is-loading) while fetching the search results. Try typing `"a"`, waiting for the results, and then editing it to `"ab"`. The results for `"a"` get replaced by the loading fallback.

```
import { Suspense, useState } from 'react';
import SearchResults from './SearchResults.js';

export default function App() {
  const [query, setQuery] = useState('');
  return (
    <>
      <label>
        Search albums:
        <input value={query} onChange={e => setQuery(e.target.value)} />
      </label>
      <Suspense fallback={<h2>Loading...</h2>}>
        <SearchResults query={query} />
      </Suspense>
    </>
  );
}
```

A common alternative UI pattern is to *defer* updating the list of results and to keep showing the previous results until the new results are ready. Call `useDeferredValue` to pass a deferred version of the query down:

```
export default function App() {

  const [query, setQuery] = useState('');

  const deferredQuery = useDeferredValue(query);

  return (

    <>

      <label>

        Search albums:

        <input value={query} onChange={e => setQuery(e.target.value)} />

      </label>

      <Suspense fallback={<h2>Loading...</h2>}>

        <SearchResults query={deferredQuery} />

      </Suspense>

    </>

  );

}
```

The `query` will update immediately, so the input will display the new value. However, the `deferredQuery` will keep its previous value until the data has loaded, so `SearchResults` will show the stale results for a bit.

Enter `"a"` in the example below, wait for the results to load, and then edit the input to `"ab"`. Notice how instead of the Suspense fallback, you now see the stale result list until the new results have loaded:

```
import { Suspense, useState, useDeferredValue } from 'react';
import SearchResults from './SearchResults.js';

export default function App() {
  const [query, setQuery] = useState('');
  const deferredQuery = useDeferredValue(query);
  return (
    <>
      <label>
        Search albums:
        <input value={query} onChange={e => setQuery(e.target.value)} />
      </label>
      <Suspense fallback={<h2>Loading...</h2>}>
        <SearchResults query={deferredQuery} />
      </Suspense>
    </>
  );
}
```

##### Deep Dive#### How does deferring a value work under the hood?[](#how-does-deferring-a-value-work-under-the-hood "Link for How does deferring a value work under the hood? ")

You can think of it as happening in two steps:

1. **First, React re-renders with the new `query` (`"ab"`) but with the old `deferredQuery` (still `"a")`.** The `deferredQuery` value, which you pass to the result list, is *deferred:* it “lags behind” the `query` value.

2. **In the background, React tries to re-render with *both* `query` and `deferredQuery` updated to `"ab"`.** If this re-render completes, React will show it on the screen. However, if it suspends (the results for `"ab"` have not loaded yet), React will abandon this rendering attempt, and retry this re-render again after the data has loaded. The user will keep seeing the stale deferred value until the data is ready.

The deferred “background” rendering is interruptible. For example, if you type into the input again, React will abandon it and restart with the new value. React will always use the latest provided value.

Note that there is still a network request per each keystroke. What’s being deferred here is displaying results (until they’re ready), not the network requests themselves. Even if the user continues typing, responses for each keystroke get cached, so pressing Backspace is instant and doesn’t fetch again.

***

### Indicating that the content is stale[](#indicating-that-the-content-is-stale "Link for Indicating that the content is stale ")

In the example above, there is no indication that the result list for the latest query is still loading. This can be confusing to the user if the new results take a while to load. To make it more obvious to the user that the result list does not match the latest query, you can add a visual indication when the stale result list is displayed:

```
<div style={{

  opacity: query !== deferredQuery ? 0.5 : 1,

}}>

  <SearchResults query={deferredQuery} />

</div>
```

With this change, as soon as you start typing, the stale result list gets slightly dimmed until the new result list loads. You can also add a CSS transition to delay dimming so that it feels gradual, like in the example below:

```
import { Suspense, useState, useDeferredValue } from 'react';
import SearchResults from './SearchResults.js';

export default function App() {
  const [query, setQuery] = useState('');
  const deferredQuery = useDeferredValue(query);
  const isStale = query !== deferredQuery;
  return (
    <>
      <label>
        Search albums:
        <input value={query} onChange={e => setQuery(e.target.value)} />
      </label>
      <Suspense fallback={<h2>Loading...</h2>}>
        <div style={{
          opacity: isStale ? 0.5 : 1,
          transition: isStale ? 'opacity 0.2s 0.2s linear' : 'opacity 0s 0s linear'
        }}>
          <SearchResults query={deferredQuery} />
        </div>
      </Suspense>
    </>
  );
}
```

***

### Deferring re-rendering for a part of the UI[](#deferring-re-rendering-for-a-part-of-the-ui "Link for Deferring re-rendering for a part of the UI ")

You can also apply `useDeferredValue` as a performance optimization. It is useful when a part of your UI is slow to re-render, there’s no easy way to optimize it, and you want to prevent it from blocking the rest of the UI.

Imagine you have a text field and a component (like a chart or a long list) that re-renders on every keystroke:

```
function App() {

  const [text, setText] = useState('');

  return (

    <>

      <input value={text} onChange={e => setText(e.target.value)} />

      <SlowList text={text} />

    </>

  );

}
```

First, optimize `SlowList` to skip re-rendering when its props are the same. To do this, [wrap it in `memo`:](/reference/react/memo#skipping-re-rendering-when-props-are-unchanged)

```
const SlowList = memo(function SlowList({ text }) {

  // ...

});
```

However, this only helps if the `SlowList` props are *the same* as during the previous render. The problem you’re facing now is that it’s slow when they’re *different,* and when you actually need to show different visual output.

Concretely, the main performance problem is that whenever you type into the input, the `SlowList` receives new props, and re-rendering its entire tree makes the typing feel janky. In this case, `useDeferredValue` lets you prioritize updating the input (which must be fast) over updating the result list (which is allowed to be slower):

```
function App() {

  const [text, setText] = useState('');

  const deferredText = useDeferredValue(text);

  return (

    <>

      <input value={text} onChange={e => setText(e.target.value)} />

      <SlowList text={deferredText} />

    </>

  );

}
```

This does not make re-rendering of the `SlowList` faster. However, it tells React that re-rendering the list can be deprioritized so that it doesn’t block the keystrokes. The list will “lag behind” the input and then “catch up”. Like before, React will attempt to update the list as soon as possible, but will not block the user from typing.

#### The difference between useDeferredValue and unoptimized re-rendering[](#examples "Link for The difference between useDeferredValue and unoptimized re-rendering")

#### Example 1 of 2:Deferred re-rendering of the list[](#deferred-re-rendering-of-the-list "Link for this heading")

In this example, each item in the `SlowList` component is **artificially slowed down** so that you can see how `useDeferredValue` lets you keep the input responsive. Type into the input and notice that typing feels snappy while the list “lags behind” it.

```
import { useState, useDeferredValue } from 'react';
import SlowList from './SlowList.js';

export default function App() {
  const [text, setText] = useState('');
  const deferredText = useDeferredValue(text);
  return (
    <>
      <input value={text} onChange={e => setText(e.target.value)} />
      <SlowList text={deferredText} />
    </>
  );
}
```

***