@@ -38,7 +38,7 @@ React 是声明式的,即你告诉 React 你想要渲染的内容,React 会
38
38
39
39
``` js {2}
40
40
function Dropdown () {
41
- const selectedItems = new Set (); // created during render
41
+ const selectedItems = new Set (); // 在渲染过程中创建
42
42
// ...
43
43
}
44
44
```
@@ -49,7 +49,7 @@ function Dropdown() {
49
49
function Dropdown () {
50
50
const selectedItems = new Set ();
51
51
const onSelect = (item ) => {
52
- // this code is in an event handler, so it's only run when the user triggers this
52
+ // 这段代码位于事件处理器中,因此只有在用户触发这个事件时才会运行。
53
53
selectedItems .add (item);
54
54
}
55
55
}
@@ -59,7 +59,7 @@ function Dropdown() {
59
59
function Dropdown () {
60
60
const selectedItems = new Set ();
61
61
useEffect (() => {
62
- // this code is inside of an Effect, so it only runs after rendering
62
+ // 这段代码位于 Effect 内部,因此它只在渲染完成后运行。
63
63
logForAnalytics (selectedItems);
64
64
}, [selectedItems]);
65
65
}
@@ -76,7 +76,7 @@ function Dropdown() {
76
76
77
77
``` js {2}
78
78
function Clock () {
79
- const time = new Date (); // 🔴 Bad: always returns a different result!
79
+ const time = new Date (); // 🔴 错误的:总是返回不同的结果!
80
80
return < span> {time .toLocaleString ()}< / span>
81
81
}
82
82
```
@@ -91,17 +91,17 @@ function Clock() {
91
91
import { useState , useEffect } from ' react' ;
92
92
93
93
function useTime () {
94
- // 1. Keep track of the current date's state. `useState` receives an initializer function as its
95
- // initial state. It only runs once when the hook is called, so only the current date at the
96
- // time the hook is called is set first.
94
+ // 1. 跟踪当前日期的状态。 `useState` 接受一个初始化函数作为其
95
+ // 初始状态。它只在调用 Hook 时运行一次,因此只有调用 Hook 时的
96
+ // 当前日期才被首先设置。
97
97
const [time , setTime ] = useState (() => new Date ());
98
98
99
99
useEffect (() => {
100
- // 2. Update the current date every second using `setInterval`.
100
+ // 2. 使用 `setInterval` 每秒更新当前日期。
101
101
const id = setInterval (() => {
102
- setTime (new Date ()); // ✅ Good: non-idempotent code no longer runs in render
102
+ setTime (new Date ()); // ✅ Good:非幂等代码不再在渲染中运行。
103
103
}, 1000 );
104
- // 3. Return a cleanup function so we don't leak the `setInterval` timer.
104
+ // 3. 返回一个清理函数,这样我们就不会忘记清理 `setInterval` 定时器,导致内存泄漏。
105
105
return () => clearInterval (id);
106
106
}, []);
107
107
@@ -141,12 +141,12 @@ export default function Clock() {
141
141
142
142
``` js {2,7}
143
143
function FriendList ({ friends }) {
144
- const items = []; // ✅ Good: locally created
144
+ const items = []; // ✅ 正确的:在局部创建
145
145
for (let i = 0 ; i < friends .length ; i++ ) {
146
146
const friend = friends[i];
147
147
items .push (
148
148
< Friend key= {friend .id } friend= {friend} / >
149
- ); // ✅ Good: local mutation is okay
149
+ ); // ✅ 正确的:局部修改是可以的。
150
150
}
151
151
return < section> {items}< / section> ;
152
152
}
@@ -159,13 +159,13 @@ function FriendList({ friends }) {
159
159
另一方面,如果 ` items ` 是在组件外部创建的,那么它会保留其之前的值,并记住所做的更改:
160
160
161
161
``` js {1,7}
162
- const items = []; // 🔴 Bad: created outside of the component
162
+ const items = []; // 🔴 错误的:在组件外部创建
163
163
function FriendList ({ friends }) {
164
164
for (let i = 0 ; i < friends .length ; i++ ) {
165
165
const friend = friends[i];
166
166
items .push (
167
167
< Friend key= {friend .id } friend= {friend} / >
168
- ); // 🔴 Bad: mutates a value created outside of render
168
+ ); // 🔴 错误的:修改了一个在渲染之外创建的值。
169
169
}
170
170
return < section> {items}< / section> ;
171
171
}
@@ -179,7 +179,7 @@ function FriendList({ friends }) {
179
179
180
180
``` js {2}
181
181
function ExpenseForm () {
182
- SuperCalculator .initializeIfNotReady (); // ✅ Good: if it doesn't affect other components
182
+ SuperCalculator .initializeIfNotReady (); // ✅ 正确的:如果它对其他组件没有影响。
183
183
// Continue rendering...
184
184
}
185
185
```
@@ -190,7 +190,7 @@ function ExpenseForm() {
190
190
191
191
``` js {2}
192
192
function ProductDetailPage ({ product }) {
193
- document .window .title = product .title ; // 🔴 Bad: Changes the DOM
193
+ document .window .title = product .title ; // 🔴 错误的:改变 DOM
194
194
}
195
195
```
196
196
@@ -211,14 +211,14 @@ props 是不可变的,因为如果你改变了它们,应用程序可能会
211
211
212
212
``` js {2}
213
213
function Post ({ item }) {
214
- item .url = new Url (item .url , base); // 🔴 Bad: never mutate props directly
214
+ item .url = new Url (item .url , base); // 🔴 错误的:永远不要直接修改 props
215
215
return < Link url= {item .url }> {item .title }< / Link> ;
216
216
}
217
217
```
218
218
219
219
``` js {2}
220
220
function Post ({ item }) {
221
- const url = new Url (item .url , base); // ✅ Good: make a copy instead
221
+ const url = new Url (item .url , base); // ✅ 正确的:创建一个新的副本替代
222
222
return < Link url= {url}> {item .title }< / Link> ;
223
223
}
224
224
```
@@ -237,7 +237,7 @@ function Counter() {
237
237
const [count , setCount ] = useState (0 );
238
238
239
239
function handleClick () {
240
- count = count + 1 ; // 🔴 Bad: never mutate state directly
240
+ count = count + 1 ; // 🔴 错误的:永远不要直接修改 state
241
241
}
242
242
243
243
return (
@@ -253,7 +253,7 @@ function Counter() {
253
253
const [count , setCount ] = useState (0 );
254
254
255
255
function handleClick () {
256
- setCount (count + 1 ); // ✅ Good: use the setter function returned by useState
256
+ setCount (count + 1 ); // ✅ 正确的:使用由 useState 返回的 setter 函数来修改 state。
257
257
}
258
258
259
259
return (
@@ -274,7 +274,7 @@ function Counter() {
274
274
function useIconStyle (icon ) {
275
275
const theme = useContext (ThemeContext);
276
276
if (icon .enabled ) {
277
- icon .className = computeStyle (icon, theme); // 🔴 Bad: never mutate hook arguments directly
277
+ icon .className = computeStyle (icon, theme); // 🔴 错误的:永远不要直接修改 Hook 的参数。
278
278
}
279
279
return icon;
280
280
}
@@ -283,7 +283,7 @@ function useIconStyle(icon) {
283
283
``` js {3}
284
284
function useIconStyle (icon ) {
285
285
const theme = useContext (ThemeContext);
286
- const newIcon = { ... icon }; // ✅ Good: make a copy instead
286
+ const newIcon = { ... icon }; // ✅ 正确的:创建一个新的副本替代
287
287
if (icon .enabled ) {
288
288
newIcon .className = computeStyle (icon, theme);
289
289
}
@@ -310,15 +310,15 @@ function useIconStyle(icon) {
310
310
如果你改变了 Hook 的参数,那么自定义 Hook 的缓存(memoization)就会变得不正确,因此避免这样做非常重要。
311
311
312
312
``` js {4}
313
- style = useIconStyle (icon); // `style` is memoized based on `icon`
314
- icon .enabled = false ; // Bad: 🔴 never mutate hook arguments directly
315
- style = useIconStyle (icon); // previously memoized result is returned
313
+ style = useIconStyle (icon); // `style` 是基于 `icon` 进行记忆化的
314
+ icon .enabled = false ; // 错误的: 🔴 永远不要直接修改 Hook 的参数
315
+ style = useIconStyle (icon); // 返回之前记忆化的结果
316
316
```
317
317
318
318
``` js {4}
319
- style = useIconStyle (icon); // `style` is memoized based on `icon`
320
- icon = { ... icon, enabled: false }; // Good : ✅ make a copy instead
321
- style = useIconStyle (icon); // new value of `style` is calculated
319
+ style = useIconStyle (icon); // `style` 是基于 `icon` 进行记忆化的
320
+ icon = { ... icon, enabled: false }; // 正确的 : ✅ 创建一个新的副本替代
321
+ style = useIconStyle (icon); // 计算 `style` 的新值
322
322
```
323
323
324
324
同样重要的是不要修改 Hook 的返回值,因为这些值可能已经被缓存了。
@@ -335,7 +335,7 @@ style = useIconStyle(icon); // new value of `style` is calculated
335
335
function Page ({ colour }) {
336
336
const styles = { colour, size: " large" };
337
337
const header = < Header styles= {styles} / > ;
338
- styles .size = " small" ; // 🔴 Bad: styles was already used in the JSX above
338
+ styles .size = " small" ; // 🔴 错误的: styles 已经在上面的 JSX 中使用了。
339
339
const footer = < Footer styles= {styles} / > ;
340
340
return (
341
341
<>
@@ -351,7 +351,7 @@ function Page({ colour }) {
351
351
function Page ({ colour }) {
352
352
const headerStyles = { colour, size: " large" };
353
353
const header = < Header styles= {headerStyles} / > ;
354
- const footerStyles = { colour, size: " small" }; // ✅ Good: we created a new value
354
+ const footerStyles = { colour, size: " small" }; // ✅ 正确的:我们创建了一个新的值。
355
355
const footer = < Footer styles= {footerStyles} / > ;
356
356
return (
357
357
<>
0 commit comments