Skip to content

Commit 3e047ed

Browse files
committed
More updates
1 parent 5a9d032 commit 3e047ed

7 files changed

+80
-40
lines changed

src/content/reference/rules/components-must-be-idempotent.md

+4-2
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@ React components are assumed to always return the same output with respect to th
1010

1111
Put simply, idempotence means that you [always get the same result everytime](learn/keeping-components-pure) you run that piece of code.
1212

13-
```js
13+
```js {3}
1414
function NewsFeed({ items }) {
15+
// ✅ Array.filter doesn't mutate `items`
1516
const filteredItems = items.filter(item => item.isDisplayed === true);
1617
return (
1718
<ul>
@@ -25,7 +26,8 @@ This means that _all_ code that runs during render must also be idempotent in or
2526
2627
```js {2}
2728
function Clock() {
28-
return <div>{new Date()}</div> // ❌ always returns a different result!
29+
const date = new Date(); // ❌ always returns a different result!
30+
return <div>{date}</div>
2931
}
3032
```
3133

src/content/reference/rules/index.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ title: Rules of React
33
---
44

55
<Intro>
6-
JavaScript rendering libraries and frameworks like React have constraints or "rules" to make the programming model cohesive and easy to reason about, while also helping you prevent bugs in your code. The rules also have the added benefit of creating a safe space for React to optimise and run your code more efficiently. This page lists all the Rules of React.
6+
JavaScript rendering libraries and frameworks like React have constraints or "rules" to make the programming model cohesive and easy to reason about, while also helping you prevent bugs in your code. The rules also have the added benefit of creating a safe space for React to optimize and run your code more efficiently. This page lists all the Rules of React.
77
</Intro>
88

99
---
@@ -29,8 +29,8 @@ If the Rules of React are broken, at best the upcoming compiler will skip optimi
2929
## Rules {/*rules*/}
3030
* [Side effects must run outside of render](/reference/rules/side-effects-must-run-outside-of-render): React can start and stop rendering components multiple times to create the best possible user experience.
3131
* [Components must be idempotent](/reference/rules/components-must-be-idempotent): React components are assumed to always return the same output with respect to their props.
32-
* [Props and State are immutable](/reference/rules/props-and-state-are-immutable): A component's props and state are immutable "snapshots" with respect to a single render.
33-
* [Never call component functions directly](/reference/rules/never-call-component-functions-directly): TODO React must orchestrate rendering
32+
* [Props and state are immutable](/reference/rules/props-and-state-are-immutable): A component's props and state are immutable "snapshots" with respect to a single render.
33+
* [Never call component functions directly](/reference/rules/never-call-component-functions-directly): Components should only be used in JSX. Don't call them as regular functions.
3434
* [Never pass around Hooks as regular values](/reference/rules/never-pass-around-hooks-as-regular-values): TODO
3535
* [Only call Hooks at the top level](/reference/rules/only-call-hooks-at-the-top-level): TODO
3636
* [Only call Hooks from React functions](/reference/rules/only-call-hooks-from-react-functions): TODO

src/content/reference/rules/never-call-component-functions-directly.md

+31-2
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,34 @@ title: Never call component functions directly
33
---
44

55
<Intro>
6-
TODO
7-
</Intro>
6+
Components should only be used in JSX. Don't call them as regular functions.
7+
</Intro>
8+
9+
---
10+
11+
React takes care of _when_ your code runs for you so that your application has a great 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.
12+
13+
In order to do this, React must decide when your component function is called during rendering. In React, you do this using JSX.
14+
15+
```js {2}
16+
function BlogPost() {
17+
return <Layout><Article /></Layout>; // ✅ Only use components in JSX
18+
}
19+
```
20+
21+
```js {3}
22+
function BlogPost() {
23+
ReactDOM.render(
24+
Layout({ children: Article() }), // ❌ Never call them directly
25+
/* ... */
26+
);
27+
}
28+
```
29+
30+
Letting React orchestrate rendering allows a number of benefits:
31+
32+
* **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.
33+
* **Component types participate in reconcilation.** 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.
34+
* **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.
35+
* **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.
36+
* **More efficient reconcilation.** 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.

src/content/reference/rules/never-pass-around-hooks-as-regular-values.md

+6-2
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,9 @@ title: Never pass around hooks as regular values
33
---
44

55
<Intro>
6-
TODO
7-
</Intro>
6+
Hooks should only be called inside of components. Never pass it around as a regular value.
7+
</Intro>
8+
9+
---
10+
11+
Hooks ...

src/content/reference/rules/props-and-state-are-immutable.md

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
---
2-
title: Props and State are immutable
2+
title: Props and state are immutable
33
---
44

55
<Intro>
6-
A component's props and state are immutable [snapshots](learn/state-as-a-snapshot) with respect to a single render.
6+
A component's props and state are immutable [snapshots](learn/state-as-a-snapshot) with respect to a single render. Never mutate them directly.
77
</Intro>
88

99
---
1010

11-
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 use the setter function provided to you to tell React that state needs to update the next time the component is rendered.
11+
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.
1212

1313
## Props {/*props*/}
14-
When followed, this rule allows React to understand that values that flow from props aren't mutated when they're passed as arguments to functions. Mutating props may also indicate a bug in your app – changing values on the props object doesn't cause the component to update, leaving your users with an outdated UI.
14+
When followed, this rule allows React to understand that values that flow from props aren't mutated when they're passed as arguments to functions, allowing certain optimizations to be made. Mutating props may also indicate a bug in your app – changing values on the props object doesn't cause the component to update, leaving your users with an outdated UI.
1515

1616
```js {2}
1717
function Post({ item }) {
@@ -28,7 +28,7 @@ function Post({ item }) {
2828
```
2929

3030
## State {/*state*/}
31-
`useState` returns an immutable tuple of the state variable and a setter to update that state.
31+
`useState` returns the state variable and a setter to update that state.
3232

3333
```js
3434
const [stateVariable, setter] = useState(0);

src/content/reference/rules/side-effects-must-run-outside-of-render.md

+30-25
Original file line numberDiff line numberDiff line change
@@ -8,30 +8,23 @@ Side effects should not run in render, as React can render components multiple t
88

99
---
1010

11-
While render must be kept pure, side effects are necessary at some point in order for your app to do anything interesting, like showing something on the screen! The key point of this rule is that side effects should not run in render, as React can render components multiple times. In most cases, you'll use event handlers to handle side effects. For example, you might have an event handler that displays a confirmation dialog after the user clicks a button. Using an event handler explicitly tells React that this code doesn't need to run during render, keeping render pure. If you've exhausted all options – and only as a last resort – you can also handle side effects using `useEffect`.
11+
While render must be kept pure, side effects are necessary at some point in order for your app to do anything interesting, like showing something on the screen! The key point of this rule is that side effects should not run in render, as React can render components multiple times. In most cases, you'll use [event handlers](learn/responding-to-events) to handle side effects.
12+
13+
For example, you might have an event handler that displays a confirmation dialog after the user clicks a button. Using an event handler explicitly tells React that this code doesn't need to run during render, keeping render pure. If you've exhausted all options – and only as a last resort – you can also handle side effects using `useEffect`.
1214

1315
<DeepDive>
1416
#### Why does render need to be pure? {/*why-does-render-need-to-be-pure*/}
15-
UI libraries like React take care of when your code runs for you so that your application has great user experience. React 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!
17+
UI libraries like React take care of when your code runs for you so that your application has a great user experience. React 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!
1618

17-
When render is kept pure, React can understand how to prioritise which updates are most important for the user to see first. This is made possible because of render purity: since components don't have side effects in render, React can pause rendering components that aren't as important to update, and only come back to them later when it's needed.
19+
When render is kept pure, React can understand how to prioritize which updates are most important for the user to see first. This is made possible because of render purity: since components don't have side effects in render, React can pause rendering components that aren't as important to update, and only come back to them later when it's needed.
1820

1921
Concretely, this means that rendering logic can be run multiple times in a way that allows React to give your user a pleasant user experience. However, if your component has an untracked side effect – like modifying the value of a global variable during render – when React runs your rendering code again, your side effects will be triggered in a way that won't match what you want. This often leads to unexpected bugs that can degrade how your users experience your app.
2022
</DeepDive>
2123

22-
For example, values that aren't created inside of a component shouldn't be mutated:
23-
24-
```js
25-
let items = []; // created outside of the component
26-
function MyComponent({ seen }) {
27-
items.push(seen); // ❌ mutated inside the component
28-
}
29-
```
30-
24+
## When is it okay to have mutation? {/*mutation*/}
25+
One common example of a side effect is mutation, which refers to changing the value of a non-[primitive](https://developer.mozilla.org/en-US/docs/Glossary/Primitive) value. In general, while mutation is not idiomatic in React, _local_ mutation is absolutely fine:
3126

32-
In general, mutation is not idiomatic in React. However, local mutation is absolutely fine:
33-
34-
```js
27+
```js {2}
3528
function FriendList({ friends }) {
3629
let items = []; // ✅ locally created and mutated
3730
for (let i = 0; i < friends.length; i++) {
@@ -44,25 +37,37 @@ function FriendList({ friends }) {
4437
}
4538
```
4639

47-
We created `items` while rendering and no other component "saw" it so we can mutate it as much as we like before handing it off as part of the render result. This component has no observable side effects, even though it mutates `items`. There is no need to contort your code to avoid local mutation.
40+
There is no need to contort your code to avoid local mutation. In particular, [`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.
41+
42+
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 returns the same result.
43+
44+
On the other hand, if `items` was created outside of the component, it holds on to its previous values and remembers changes:
45+
46+
```js {1}
47+
let items = []; // ❌ created outside of the component
48+
function FriendList({ friends }) {
49+
// Push `friends` into `items`...
50+
return <section>{items}</section>;
51+
}
52+
```
53+
54+
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 and **breaks the rule**.
4855

4956
Similarly, lazy initialization is fine despite not being fully "pure":
5057

51-
```js
58+
```js {2}
5259
function ExpenseForm() {
53-
// Fine if it doesn't affect other components:
54-
SuperCalculator.initializeIfNotReady();
55-
60+
SuperCalculator.initializeIfNotReady(); // ✅ Fine if it doesn't affect other components
5661
// Continue rendering...
5762
}
5863
```
5964

60-
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.
61-
62-
That said, 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.
65+
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.
6366

64-
```js
67+
```js {2}
6568
function ProductDetailPage({ product }) {
6669
document.window.title = product.title; //
6770
}
68-
```
71+
```
72+
73+
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-must-be-idempotent).

src/sidebarReference.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
"path": "/reference/rules/components-must-be-idempotent"
2424
},
2525
{
26-
"title": "Props and State are immutable",
26+
"title": "Props and state are immutable",
2727
"path": "/reference/rules/props-and-state-are-immutable"
2828
},
2929
{

0 commit comments

Comments
 (0)