react函数组件
# 函数组件特性
React 中的函数组件是通过函数来实现的,函数组件的公式上: f(state)=>UI
, 即:数据到视图的映射
函数组件
因为是通过函数实现的,所以在使用函数组件时就会有函数的特性
- 对于函数组件来说,每次状态更新后,组件都会重新渲染
- 每次组件更新都会记录某个特定时刻的状态,快照
- 组件每次特定渲染,都有自己的
props/state/事件处理程序
快照
,从代码层面来说,是通过JS
中函数的闭包机制来实现的
function App(){
const [count,setCount] =useState(0)
const showCount = ()=>{
setTimeout(()=>{
console.log('count:',count)
},3000)
}
return (
<div>
<h4>{count}</h4>
<button onClick = {()=>{setCount(count+1)}}>+1</button>
<button onClick = {showCount}>获取3秒后count值</button>
</div>
)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
因为闭包机制作用下,在获取 3s
的count值获取到的值为 0
因为是异步操作,所以在获取其 count
值还是修改其 count
值都是拿到依赖的原始值
在 react
项目中
setTimes(60)
setInterval(() => {
// 闭包下times拿到的数据为函数外部记录的0值
setTimes(times - 1)
}, 1000)
1
2
3
4
5
2
3
4
5
因为不是同步的,每次执行的定时器任务拿取到的 times
值都是0
setTimes(60)
这个函数执行机制也类似于异步,所以拿到的数据可能还是初始值
# 解决方案
# 一
setTimes((times) => times - 1)
1
使用 setTimes
函数的一种写法 ,保证每次获取到的 times
是最新值,而不是外部依赖
# 二
使用外部全局变量
let num = 0
function App() {
const [count, setCount] = useState(0)
const showCount = () => {
setTimeout(() => {
console.log('count:', num)
}, 3000)
}
return (
<div>
<h4>{num}</h4>
<button
onClick={() => {
setCount(count + 1)
num = count + 1
}}
>
+1
</button>
<button onClick={showCount}>获取3秒后count值</button>
</div>
)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
缺点是两个相同组件作用下,会有影响(两个组件会使用同一个全局变量)
**使用 useRef() **
function App() {
const aRef = useRef(0)
const [count, setCount] = useState(0)
const showCount = () => {
setTimeout(() => {
console.log('count:', aRef.current)
}, 3000)
}
return (
<div>
<h4>{aRef.current}</h4>
<button
onClick={() => {
setCount(count + 1)
aRef.current = count + 1
}}
>
+1
</button>
<button onClick={showCount}>获取3秒后count值</button>
</div>
)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
编辑 (opens new window)
上次更新: 2023/02/07, 14:51:48