Skip to content

Commit 8e50692

Browse files
committed
Combine rules of jsx
1 parent ac8bd9b commit 8e50692

6 files changed

+67
-81
lines changed

src/content/reference/rules/components-and-hooks-must-be-pure.md

+43-7
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ title: Components and Hooks must be pure
33
---
44

55
<Intro>
6-
TODO
6+
[Purity](/learn/keeping-components-pure) makes your code easier to understand and debug.
77
</Intro>
88

99
<InlineToc />
@@ -76,7 +76,7 @@ function FriendList({ friends }) {
7676
7777
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.
7878
79-
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.
79+
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.
8080
8181
On the other hand, if `items` was created outside of the component, it holds on to its previous values and remembers changes:
8282
@@ -175,8 +175,7 @@ function Counter() {
175175
176176
## Return values and arguments to Hooks are immutable {/*return-values-and-arguments-to-hooks-are-immutable*/}
177177
178-
Once values are passed to a Hook, neither the calling code nor the Hook should
179-
modify them. Like props in JSX, values become immutable when passed to a Hook.
178+
Once values are passed to a Hook, you should not modify them. Like props in JSX, values become immutable when passed to a Hook.
180179
181180
```js {4}
182181
function useIconStyle(icon) {
@@ -201,8 +200,7 @@ function useIconStyle(icon) {
201200
}
202201
```
203202
204-
The custom Hook might have used the hook arguments as dependencies to memoize
205-
values inside it.
203+
The custom Hook might have used the hook arguments as dependencies to memoize values inside it.
206204
207205
```js {4}
208206
function useIconStyle(icon) {
@@ -232,4 +230,42 @@ icon = { ...icon, enabled: false }; // ✅ make a copy instead
232230
style = useIconStyle(icon); // new value of `style` is calculated
233231
```
234232
235-
Similarly, it's important to not modify the return values of hooks, as they have been memoized.
233+
Similarly, it's important to not modify the return values of hooks, as they may have been memoized.
234+
235+
## Values are immutable after being passed to JSX {/*values-are-immutable-after-being-passed-to-jsx*/}
236+
237+
Don't mutate values after they've been used in JSX. Move the mutation before the JSX is created.
238+
239+
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.
240+
241+
```js {4}
242+
function Page({ colour }) {
243+
const styles = { colour, size: "large" };
244+
const header = <Header styles={styles} />;
245+
styles.size = "small"; // ❌ styles was already used in the JSX above!
246+
const footer = <Footer styles={styles} />;
247+
return (
248+
<>
249+
{header}
250+
<Content />
251+
{footer}
252+
</>
253+
);
254+
}
255+
```
256+
257+
```js {4}
258+
function Page({ colour }) {
259+
const headerStyles = { colour, size: "large" };
260+
const header = <Header styles={headerStyles} />;
261+
const footerStyles = { colour, size: "small" }; // ✅ we created a new value
262+
const footer = <Footer styles={footerStyles} />;
263+
return (
264+
<>
265+
{header}
266+
<Content />
267+
{footer}
268+
</>
269+
);
270+
}
271+
```

src/content/reference/rules/index.md

+6-3
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,15 @@ We strongly recommend using Strict Mode alongside React's ESLint plugin to help
1717

1818
You can think of React's constraints like the grammatical rules and patterns of languages: they constrain what we can do with words, so that we can correctly and efficiently communicate our thoughts.
1919

20-
These rules have been used in the design of all of React's features over the years. React's Strict Mode enforces several of these rules at runtime in DEV mode, and with the release of React's upcoming compiler, more rules will now be statically checked to help you find more bugs as well as allow for correct optimization of your code.
20+
These rules have been used in the design of all of React's features over the years. Enabling Strict Mode catches bugs caused by breaking these rules, and with the release of React's upcoming compiler, more rules will now be statically checked to help you find more bugs as well as allow for correct optimization of your code.
21+
22+
<Note>
23+
Strict Mode checks are run in development mode only; they do not impact the production build.
24+
</Note>
2125

2226
The Rules of React are proven rules used at companies like Meta that help you maintain an application and codebase that scales with you. When followed, your codebase becomes easier to understand and maintain, is less buggy, and helps React ensure your code runs efficiently by default.
2327
</DeepDive>
2428

2529
* [Components and Hooks must be pure](/reference/rules/components-and-hooks-must-be-pure)
2630
* [React orchestrates Components and Hooks](/reference/rules/react-orchestrates-components-and-hooks)
27-
* [Rules of Hooks](/reference/rules/rules-of-hooks)
28-
* [Rules of JSX](/reference/rules/rules-of-jsx)
31+
* [Rules of Hooks](/reference/rules/rules-of-hooks)

src/content/reference/rules/react-orchestrates-components-and-hooks.md

+17-14
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ title: React orchestrates Components and Hooks
33
---
44

55
<Intro>
6-
TODO
6+
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.
77
</Intro>
88

99
<InlineToc />
@@ -13,17 +13,15 @@ TODO
1313
## Never call component functions directly {/*never-call-component-functions-directly*/}
1414
Components should only be used in JSX. Don't call them as regular functions.
1515

16-
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.
17-
18-
In order to do this, React must decide when your component function is called during rendering. In React, you do this using JSX.
16+
React must decide when your component function is called during rendering. In React, you do this using JSX.
1917

2018
```js {2}
2119
function BlogPost() {
2220
return <Layout><Article /></Layout>; // ✅ Only use components in JSX
2321
}
2422
```
2523

26-
```js {3}
24+
```js {2}
2725
function BlogPost() {
2826
return <Layout>{Article()}</Layout> // ❌ Never call them directly
2927
}
@@ -47,28 +45,32 @@ Hooks allow you to augment a component with React features. They should always b
4745

4846
Passing around hooks as regular values also inhibits the compiler at performing optimizations. Breaking this rule will de-optimize your component.
4947

48+
### Don't dynamically mutate a hook {/*dont-dynamically-mutate-a-hook*/}
49+
50+
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:
51+
5052
```js {2}
5153
function ChatInput() {
5254
const useDataWithLogging = withLogging(useData); //
5355
const data = useDataWithLogging();
5456
}
5557
```
5658

57-
```js {2}
59+
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.
60+
61+
```js {2,6}
5862
function ChatInput() {
5963
const data = useDataWithLogging(); //
6064
}
61-
```
62-
63-
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.
6465

65-
```js
6666
function useDataWithLogging() {
67-
// ... Logic should go in here
67+
// ... Create a new version of the Hook and inline the logic here
6868
}
6969
```
7070

71-
Hooks should also not be dynamically used: for example, instead of doing dependency injection in a component:
71+
### Don't dynamically use hooks {/*dont-dynamically-use-hooks*/}
72+
73+
Hooks should also not be dynamically used: for example, instead of doing dependency injection in a component by passing a hook as a value:
7274

7375
```js {2}
7476
function ChatInput() {
@@ -84,11 +86,12 @@ function ChatInput() {
8486
}
8587

8688
function Button() {
87-
const data = useDataWithLogging();
89+
const data = useDataWithLogging(); //
8890
}
8991

9092
function useDataWithLogging() {
91-
// conditional logic can live here
93+
// If there's any conditional logic to change the hook's behavior, it should be inlined into
94+
// the hook
9295
}
9396
```
9497

src/content/reference/rules/rules-of-hooks.md

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

55
<Intro>
6-
TODO
6+
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.
77
</Intro>
88

99
<InlineToc />
@@ -115,6 +115,3 @@ function setOnlineStatus() { // ❌ Not a component or custom hook!
115115
const [onlineStatus, setOnlineStatus] = useOnlineStatus();
116116
}
117117
```
118-
119-
## Return values and arguments to Hooks are immutable {/*return-values-and-arguments-to-hooks-are-immutable*/}
120-
TODO

src/content/reference/rules/rules-of-jsx.md

-49
This file was deleted.

src/sidebarReference.json

-4
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,6 @@
2525
{
2626
"title": "Rules of Hooks",
2727
"path": "/reference/rules/rules-of-hooks"
28-
},
29-
{
30-
"title": "Rules of JSX",
31-
"path": "/reference/rules/rules-of-jsx"
3228
}
3329
]
3430
},

0 commit comments

Comments
 (0)