@@ -4,36 +4,39 @@ layout: doc
4
4
---
5
5
6
6
``` jsx
7
- function example (){
8
- let count = 0
9
- function handleClick (){
10
- ++ count
11
- }
12
- return (<>
13
- < div> {count}< / div>
14
- < button onClick= {handleClick}> add< / button>
15
- < / >
16
- )
7
+ function example () {
8
+ let count = 0 ;
9
+ function handleClick () {
10
+ ++ count;
11
+ }
12
+ return (
13
+ <>
14
+ < div> {count}< / div>
15
+ < button onClick= {handleClick}> add< / button>
16
+ < / >
17
+ );
17
18
}
18
19
```
19
20
20
21
不会有任何变化
21
22
22
23
handleClick() 事件处理函数正在更新局部变量 count
23
24
24
- * 更新局部变量react不会触发渲染 , React 没有意识到它需要使用新数据再次渲染组件。
25
- * 就算react重新渲染 ,再次执行这个函数,之前修改的局部变量修改已经丢失,渲染的结果都是一样的
25
+ - 更新局部变量 react 不会触发渲染 , React 没有意识到它需要使用新数据再次渲染组件。
26
+ - 就算 react 重新渲染 ,再次执行这个函数,之前修改的局部变量修改已经丢失,渲染的结果都是一样的
26
27
27
28
要使用新数据更新组件,需要做两件事:
28
29
29
- * 保留 渲染之间的数据。
30
- * 触发 React 使用新数据渲染组件(重新渲染)。
30
+ - 保留 渲染之间的数据。
31
+ - 触发 React 使用新数据渲染组件(重新渲染)。
31
32
32
33
useState Hook 提供了这两个功能:
33
34
34
- * State 变量 用于保存渲染间的数据。
35
- * State setter 函数 更新变量并触发 React 再次渲染组件。
36
- ## useState
35
+ - State 变量 用于保存渲染间的数据。
36
+ - State setter 函数 更新变量并触发 React 再次渲染组件。
37
+
38
+ ## useState
39
+
37
40
``` js
38
41
const [index , setIndex ] = useState (0 );
39
42
```
@@ -43,6 +46,18 @@ const [index, setIndex] = useState(0);
43
46
3 . 组件进行第二次渲染。React 仍然看到 useState(0),但是因为 React 记住 了你将 index 设置为了 1,它将返回 [ 1, setIndex] 。
44
47
4 . 以此类推!
45
48
49
+ ## 赋予一个组件多个 state 变量
50
+
51
+ useState 在调用时没有任何关于它引用的是哪个 state 变量的信息。没有传递给 useState 的“标识符”,它是如何知道要返回哪个 state 变量呢
52
+
53
+ 相反,为了使语法更简洁,在同一组件的每次渲染中,Hooks 都依托于一个稳定的调用顺序
54
+
55
+ 在 React 内部,为每个组件保存了一个数组,其中每一项都是一个 state 对。它维护当前 state 对的索引值,在渲染之前将其设置为 “0”。每次调用 useState 时,React 都会为你提供一个 state 对并增加索引值。
56
+
57
+ [ React Hooks: not magic, just arrays] ( https://medium.com/@ryardley/react-hooks-not-magic-just-arrays-cd4f1857236e )
58
+
59
+ 这个例子没有使用 React,但它让你了解 useState 在内部是如何工作的:
60
+
46
61
<iframe src="https://codesandbox.io/embed/magical-meitner-hcs52m?fontsize=14&hidenavigation=1&theme=dark"
47
62
style="width:100%; height:500px; border:0; border-radius: 4px; overflow:hidden;"
48
63
title="magical-meitner-hcs52m"
@@ -52,4 +67,48 @@ const [index, setIndex] = useState(0);
52
67
53
68
:::tip :thinking :
54
69
Hooks ——以 use 开头的函数——只能在组件或自定义 Hook 的最顶层调用。 你不能在条件语句、循环语句或其他嵌套函数内调用 Hook。
55
- :::
70
+ :::
71
+
72
+ 再看这个例子
73
+
74
+ <iframe src="https://codesandbox.io/embed/g7f575?view=editor+%2B+preview"
75
+ style="width:100%; height: 500px; border:0; border-radius: 4px; overflow:hidden;"
76
+ title="一次性三次set"
77
+ allow="accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr; xr-spatial-tracking"
78
+ sandbox="allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts"
79
+ > </iframe >
80
+ :::details :rocket : DEEP DIVE
81
+
82
+ 设置 state 只会为下一次渲染变更 state 的值
83
+
84
+ 以下是这个按钮的点击事件处理函数通知 React 要做的事情:
85
+
86
+ 1 . setNumber(number + 1):number 是 0 所以 setNumber(0 + 1)。
87
+
88
+ - React 准备在下一次渲染时将 number 更改为 1。
89
+
90
+ 2 . setNumber(number + 1):number 是 0 所以 setNumber(0 + 1)。
91
+
92
+ - React 准备在下一次渲染时将 number 更改为 1。
93
+
94
+ 3 . setNumber(number + 1):number 是 0 所以 setNumber(0 + 1)。
95
+
96
+ - React 准备在下一次渲染时将 number 更改为 1。
97
+
98
+ 尽管你调用了三次 setNumber(number + 1),但在 这次渲染的 事件处理函数中 number 会一直是 0,所以你会三次将 state 设置成 1。
99
+ :::
100
+
101
+ 再看这个
102
+
103
+ <iframe src="https://codesandbox.io/embed/x9692v?view=editor+%2B+preview&module=%2Fsrc%2FApp.js"
104
+ style="width:100%; height: 500px; border:0; border-radius: 4px; overflow:hidden;"
105
+ title="随时间变化的state"
106
+ allow="accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr; xr-spatial-tracking"
107
+ sandbox="allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts"
108
+ > </iframe >
109
+
110
+ :::details :rocket : DEEP DIVE
111
+ state 的值在渲染过程中永远不会改变
112
+
113
+ 即使其事件处理程序的代码是异步的。在该渲染 中,即使在调用之后,onClick的值number仍然保持不变。当 React 通过调用您的组件“拍摄 UI 快照”时,其值已“固定”
114
+ :::
0 commit comments