- [Updating the rendered tree](#updating-the-rendered-tree)
## Reference {/*reference*/}
### `render(reactNode, domNode)` {/*render*/}
Call `render` to display a React component inside a browser DOM element.
```js
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 examples below.](#usage)
#### Parameters {/*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()`](/TODO), 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.
#### Returns {/*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*/}
* 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()`](/TODO) 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](/apis/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`](TODO) instead of `render`.
### Rendering the root component {/*rendering-the-root-component*/}
In apps fully built with React, you will do this once at the top level of your app--to render the "root" component.
In apps fully built with React, **you will usually only do this once at startup**--to render the "root" component.
<Sandpack>
@ -118,11 +54,13 @@ export default function App() {
</Sandpack>
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. If you want to update the UI, your components can do this by [using state](/apis/usestate).
If you use ["sprinkles"](/learn/add-react-to-a-website) of React here and there, call `render` for each top-level piece of UI managed by React.
If your page [isn't fully built with React](/learn/add-react-to-a-website), call `render` for each top-level piece of UI managed by React.
<Sandpack>
@ -192,16 +130,19 @@ nav ul li { display: inline-block; margin-right: 20px; }
</Sandpack>
You can destroy the rendered trees with [`unmountComponentAtNode()`](TODO).
---
### Updating the rendered tree {/*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:
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 in this example are not destructive:
<Sandpack>
```js index.js active
import {render} from 'react-dom';
import './styles.css';
import App from './App.js';
let i = 0;
@ -227,4 +168,46 @@ export default function App({counter}) {
</Sandpack>
You can destroy the rendered tree with [`unmountComponentAtNode()`](TODO).
It is uncommon to call `render` multiple times. Usually, you'll [update state](/apis/usestate) inside one of the components instead.
Call `render` to display a React component inside a browser DOM element.
```js
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 examples above.](#usage)
#### Parameters {/*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()`](/TODO), 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*/}
`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*/}
* 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()`](/TODO) 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](/apis/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`](TODO) instead of `render`.
The convention is to name state variables like `[something, setSomething]` using [array destructuring](/learn/a-javascript-refresher#array-destructuring).
[See more examples below.](#examples-basic)
#### Parameters {/*parameters*/}
* `initialState`: The value you want the state to be initially. It can be a value of any type, but there is a special behavior for functions. This argument is ignored after the initial render.
* If you pass a function as `initialState`, it will be treated as an _initializer function_. It should be pure, should take no arguments, and should return a value of any type. React will call your initializer function when initializing the component, and store its return value as the initial state. [See an example below.](#avoiding-recreating-the-initial-state)
#### Returns {/*returns*/}
`useState` returns an array with exactly two values:
1. The current state. During the first render, it will match the `initialState` you have passed.
2. The [`set` function](#setstate) that lets you update the state to a different value and trigger a re-render.
#### Caveats {/*caveats*/}
* `useState` 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.
* In Strict Mode, React will **call your initializer function twice** in order to [help you find accidental impurities](#my-initializer-or-updater-function-runs-twice). This is development-only behavior and does not affect production. If your initializer function is pure (as it should be), this should not affect the logic of your component. The result from one of the calls will be ignored.
---
### `set` functions, like `setSomething(nextState)` {/*setstate*/}
`useState` returns an array with exactly two items:
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:
1. The <CodeStepstep={1}>current state</CodeStep> of this state variable, initially set to the <CodeStepstep={3}>initial state</CodeStep> you provided.
2. The <CodeStepstep={2}>`set` function</CodeStep> that lets you change it to any other value in response to interaction.
```js
const [name, setName] = useState('Edward');
To update what’s on the screen, call the `set` function with some next state:
```js [[2, 2, "setName"]]
function handleClick() {
setName('Taylor');
setAge(a => a + 1);
// ...
setName('Robin');
}
```
#### Parameters {/*setstate-parameters*/}
* `nextState`: The value that you want the state to be. It can be a value of any type, but there is a special behavior for functions.
* If you pass a function as `nextState`, 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 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 all of the queued updaters to the previous state. [See an example below.](#updating-state-based-on-the-previous-state)
#### Returns {/*setstate-returns*/}
`set` functions do not have a return value.
#### Caveats {/*setstate-caveats*/}
* The `set` function **only updates the state variable for the *next* render**. If you read the state variable after calling the `set` function, [you will still get the old value](#ive-updated-the-state-but-logging-gives-me-the-old-value) that was on the screen before your call.
* If the new value you provide is identical to the current `state`, as determined by an [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) comparison, React will **skip re-rendering the component and its children.** This is an optimization. Although in some cases React may still need to call your component before skipping the children, it shouldn't affect your code.
* React [batches state updates](/learn/queueing-a-series-of-state-updates). It updates the screen **after all the event handlers have run** and have called their `set` functions. This prevents multiple re-renders during a single event. In the rare case that you need to force React to update the screen earlier, for example to access the DOM, you can use [`flushSync`](/apis/flushsync).
* Calling the `set` function *during rendering* is only allowed from within the currently rendering component. React will discard its output and immediately attempt to render it again with the new state. This pattern is rarely needed, but you can use it to **store information from the previous renders**. [See an example below.](#storing-information-from-previous-renders)
* In Strict Mode, React will **call your updater function twice** in order to [help you find accidental impurities](#my-initializer-or-updater-function-runs-twice). This is development-only behavior and does not affect production. If your updater function is pure (as it should be), this should not affect the logic of your component. The result from one of the calls will be ignored.
---
## Usage {/*usage*/}
### Adding state to a component {/*adding-state-to-a-component*/}
First, declare the state variables you need. Then, update them on interaction and display them in your JSX.
<APIAnatomy>
<AnatomySteptitle="Declare a state variable">
Call `useState` and pass the initial state to it. React will store the state that you passed, and give it back to you.
React will store the next state, render your component again with the new values, and update the UI.
</AnatomyStep>
<Gotcha>
<AnatomySteptitle="Set state on interaction">
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):
To change the state, call the state setter function with the next state value. React will put that value into state instead.
Read [state as a component's memory](/learn/state-a-components-memory) to learn more.
---
### Updating state based on the previous state {/*updating-state-based-on-the-previous-state*/}
This code looks like it increments the counter three times, but it only increments once:
Suppose the `age` is `42`. This handler calls `setAge(age + 1)` three times:
```js
const [count, setCount] = useState(0);
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:
```js [[1, 2, "a", 0], [2, 2, "a + 1"], [1, 3, "a", 0], [2, 3, "a + 1"], [1, 4, "a", 0], [2, 4, "a + 1"]]
function handleClick() {
setCount(count + 1); // setCount(0 + 1)
setCount(count + 1); // setCount(0 + 1)
setCount(count + 1); // setCount(0 + 1)
setAge(a => a + 1); // setAge(42 => 43)
setAge(a => a + 1); // setAge(43 => 44)
setAge(a => a + 1); // setAge(44 => 45)
}
```
This is because calling `setCount` will not update the `count` until the next render, so each call becomes `setCount(0 + 1)`. **To make a series of state changes, each of which depends on the previous state,** pass an *updater function* to `setCount`. React will queue them and run them all to calculate state on next render.
Here, `a => a + 1` is your updater function. It takes the <CodeStepstep={1}>pending state</CodeStep> and calculates the <CodeStepstep={2}>next state</CodeStep> from it.
React puts your updater functions in a [queue](/learn/queueing-a-series-of-state-updates). Then, during the next render, it will call them in the same order:
<APIAnatomy>
1. `a => a + 1` will receive `42` as the pending state and return `43` as the next state.
1. `a => a + 1` will receive `43` as the pending state and return `44` as the next state.
1. `a => a + 1` will receive `44` as the pending state and return `45` as the next state.
<AnatomySteptitle="You receive: Pending state">
There are no other queued updates, so React will store `45` as the current state in the end.
You get the latest state with the previously queued updates applied to it. For example, if `count` was `0` and you call `setCount(c => c + 1)` three times in a row, then the pending `c` state will be `0` in the first updater, `1` in the second one, and `2` in the third one, and `3` is the final state.
By convention, it's common to name the pending state argument for the first letter of the state variable name, like `a` for `age`. However, you may also call it like `prevAge` or something else that you find clearer.
</AnatomyStep>
React may [call your updaters twice](#my-initializer-or-updater-function-runs-twice) in development to verify that they are [pure](/learn/keeping-components-pure).
<AnatomySteptitle="You return: Next state">
<DeepDivetitle="Is using an updater always preferred?">
You return the next state you want to see on the screen.
You might hear a recommendation to always write code like `setAge(a => a + 1)` if the state you're setting is calculated from the previous state. There is no harm in it, but it is also not always necessary.
</AnatomyStep>
In most cases, there is no difference between these two approaches. React always makes sure that for intentional user actions, like clicks, the `age` state variable would be updated before the next click. This means there is no risk of a click handler seeing a "stale" `age` at the beginning of the event handler.
However, if you do multiple updates within the same event, updaters can be helpful. They're also helpful if accessing the state variable itself is inconvenient (you might run into this when optimizing re-renders).
// 1 => 2
setCount(c => c + 1);
If you prefer consistency over slightly more verbose syntax, it's reasonable to always write an updater if the state you're setting is calculated from the previous state. If it's calculated from the previous state of some *other* state variable, you might want to combine them into one object and [use a reducer](/learn/extracting-state-logic-into-a-reducer).
// 2 => 3
setCount(c => c + 1);
}
```
</DeepDive>
<RecipestitleText="The difference between passing an updater and passing the next state directly"titleId="examples-updater">
### Passing the updater function {/*passing-the-updater-function*/}
</APIAnatomy>
This example passes the updater function, so the "+3" button works.
React may [call your updater function twice](#my-initializer-or-updater-function-runs-twice) in development.
<Solution/>
Read [state as a snapshot](/learn/state-as-a-snapshot) and [queueing a series of state changes](/learn/queueing-a-series-of-state-updates) to learn more.
### Passing the next state directly {/*passing-the-next-state-directly*/}
<DeepDivetitle="Is using an updater always preferred?">
This example **does not** pass the updater function, so the "+3" button **doesn't work as intended**.
You might hear a recommendation to always write code like `setCount(c => c + 1)` if the state you're setting is calculated from the previous state. There is no harm in it, but it is also not always necessary.
<Sandpack>
In most cases, there is no difference between these two approaches. React always makes sure that for intentional user actions, like clicks, the `count` state variable would be updated before the next click. This means there is no risk of a click handler seeing a "stale" `count` at the beginning of the event handler.
```js
import { useState } from 'react';
However, if you do multiple updates within the same event, updaters can be helpful. They're also helpful if accessing the state variable itself is inconvenient (you might run into this when optimizing re-renders).
export default function Counter() {
const [age, setAge] = useState(42);
If you prefer consistency over slightly more verbose syntax, it's reasonable to always write an updater if the state you're setting is calculated from the previous state. If it's calculated from the previous state of some *other* state variable, you might want to combine them into one object and [use a reducer](/learn/extracting-state-logic-into-a-reducer).
### Updating objects and arrays in state {/*updating-objects-and-arrays-in-state*/}
@ -401,6 +372,8 @@ setForm({
});
```
Read [updating objects in state](/learn/updating-objects-in-state) and [updating arrays in state](/learn/updating-arrays-in-state) to learn more.
<RecipestitleText="Examples of objects and arrays in state"titleId="examples-objects">
### Form (object) {/*form-object*/}
@ -844,40 +817,90 @@ function ItemList({ artworks, onToggle }) {
</Recipes>
Read [updating objects in state](/learn/updating-objects-in-state) and [updating arrays in state](/learn/updating-arrays-in-state) to learn more.
---
### Avoiding recreating the initial state {/*avoiding-recreating-the-initial-state*/}
The initial state that you pass to `useState` is only used for the initial render. For the next renders, this argument is ignored. If creating the initial state is expensive, it is wasteful to create and throw it away on every render. To avoid this, **you can pass an *initializer function* to `useState`.** React will only run it during the initialization to calculate the initial state, but won't run it for re-renders. This is a performance optimization.
React saves the initial state once and ignores it on the next renders.
<AnatomySteptitle="Initializing state with a value">
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.
Most often, you will provide the initial state during render.
To solve this, you may **pass it as an _initializer_ function** to `useState` instead:
<AnatomySteptitle="Initializing state with a function">
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.
But you can also give React a function that calculates the initial state instead. React will only call that function when initializing the component, and won't call it again.
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).
</AnatomyStep>
<RecipestitleText="The difference between passing an initializer and passing the initial state directly"titleId="examples-initializer">
### Passing the initializer function {/*passing-the-initializer-function*/}
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.
### Passing the initial state directly {/*passing-the-initial-state-directly*/}
This example **does not** pass the initializer function, so the `createInitialTodos` function runs on every render, such as when you type into the input. There is no observable difference in behavior, but this code is less efficient.
<Sandpack>
@ -889,30 +912,46 @@ function createInitialTodos() {
The convention is to name state variables like `[something, setSomething]` using [array destructuring](/learn/a-javascript-refresher#array-destructuring).
[See more examples above.](#examples-basic)
#### Parameters {/*parameters*/}
* `initialState`: The value you want the state to be initially. It can be a value of any type, but there is a special behavior for functions. This argument is ignored after the initial render.
* If you pass a function as `initialState`, it will be treated as an _initializer function_. It should be pure, should take no arguments, and should return a value of any type. React will call your initializer function when initializing the component, and store its return value as the initial state. [See an example above.](#avoiding-recreating-the-initial-state)
#### Returns {/*returns*/}
`useState` returns an array with exactly two values:
1. The current state. During the first render, it will match the `initialState` you have passed.
2. The [`set` function](#setstate) that lets you update the state to a different value and trigger a re-render.
#### Caveats {/*caveats*/}
* `useState` 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.
* In Strict Mode, React will **call your initializer function twice** in order to [help you find accidental impurities](#my-initializer-or-updater-function-runs-twice). This is development-only behavior and does not affect production. If your initializer function is pure (as it should be), this should not affect the logic of your component. The result from one of the calls will be ignored.
---
### `set` functions, like `setSomething(nextState)` {/*setstate*/}
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:
```js
const [name, setName] = useState('Edward');
function handleClick() {
setName('Taylor');
setAge(a => a + 1);
// ...
```
#### Parameters {/*setstate-parameters*/}
* `nextState`: The value that you want the state to be. It can be a value of any type, but there is a special behavior for functions.
* If you pass a function as `nextState`, 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 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 all of the queued updaters to the previous state. [See an example above.](#updating-state-based-on-the-previous-state)
#### Returns {/*setstate-returns*/}
`set` functions do not have a return value.
#### Caveats {/*setstate-caveats*/}
* The `set` function **only updates the state variable for the *next* render**. If you read the state variable after calling the `set` function, [you will still get the old value](#ive-updated-the-state-but-logging-gives-me-the-old-value) that was on the screen before your call.
* If the new value you provide is identical to the current `state`, as determined by an [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) comparison, React will **skip re-rendering the component and its children.** This is an optimization. Although in some cases React may still need to call your component before skipping the children, it shouldn't affect your code.
* React [batches state updates](/learn/queueing-a-series-of-state-updates). It updates the screen **after all the event handlers have run** and have called their `set` functions. This prevents multiple re-renders during a single event. In the rare case that you need to force React to update the screen earlier, for example to access the DOM, you can use [`flushSync`](/apis/flushsync).
* Calling the `set` function *during rendering* is only allowed from within the currently rendering component. React will discard its output and immediately attempt to render it again with the new state. This pattern is rarely needed, but you can use it to **store information from the previous renders**. [See an example above.](#storing-information-from-previous-renders)
* In Strict Mode, React will **call your updater function twice** in order to [help you find accidental impurities](#my-initializer-or-updater-function-runs-twice). This is development-only behavior and does not affect production. If your updater function is pure (as it should be), this should not affect the logic of your component. The result from one of the calls will be ignored.
---
## Troubleshooting {/*troubleshooting*/}
### I've updated the state, but logging gives me the old value {/*ive-updated-the-state-but-logging-gives-me-the-old-value*/}
@ -1160,4 +1274,28 @@ setTodos(prevTodos => {
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.
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*/}
You can't put a function into state like this:
```js
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.