react hook 与 闭包
# 闭包
简单来说就是上级作用域内变量的生命周期,因为被下级作用域内引用,而没有被释放。就导致上级作用域内的变量,等到下级作用域执行完以后才正常得到释放。
具体搜索看我《javascript》文章
import React, { useEffect, useState } from "react";
const testClosure = () => {
let num = 0;
const effect = () => {
num += 1;
const message = `num value in message:${num}`;
return function unmount() {
console.log(message);
};
};
return effect;
};
// 执行test,返回effect函数
const add = testClosure();
// 执行effect函数,返回引用了message1的unmount函数
const unmount = add();
// 再一次执行effect函数,返回引用了message2的unmount函数
add();
// message3
add();
// message4
add();
// message5
add();
unmount(); // 在这里会打印什么呢?按照直觉似乎应该打印3,实际上打印了1
// react hook 与 闭包,hook 与 闭包经典的坑
export const Test = () => {
const [num, setNum] = useState(0);
const add = () => setNum(num + 1);
useEffect(() => {
const id = setInterval(() => {
console.log("num in setInterval:", num);
}, 1000);
return () => clearInterval(id);
}, [num]);
useEffect(() => {
return () => {
console.log("卸载值:", num);
};
}, [num]);
return (
<div>
<button onClick={add}>add</button>
<p>number: {num}</p>
</div>
);
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
结果始终输出的为1
# react hook 闭包
import React, { useEffect, useState } from "react";
export const Test = () => {
const [num, setNum] = useState(0);
const add = () => {
console.log("num is addEvent:", num);
setNum(num + 1);
};
useEffect(() => {
setInterval(() => {
console.log("num is setInterval:", num);
}, 1000);
return () => {
console.log(num);
};
}, []);
return (
<div>
<button onClick={add}>add</button>
<p>{num}</p>
</div>
);
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
可以看到 use Effect 在最初执行的时候引用的初始值0,形成了闭包。在后续页面如何加载都不会影响到结果。
# 使用更新的值
若想想要实时输出变化后的值,需要传入监听值,值变化后重新执行其内的代码 记得清楚定时器
useEffect(() => {
const interval = setInterval(() => {
console.log("num is setInterval:", num);
}, 1000);
return () => {
clearInterval(interval);
console.log(num);
};
}, [num]);
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# 使用useRef 使用初始值
上次更新: 2022/08/14, 18:25:44