<div style="display: none;" hidden="true" aria-hidden="true" data-nosnippet>Are you an LLM? You can read better optimized documentation at /pages/6a4091.md for this page in Markdown format</div>
闭包
简单来说就是上级作用域内变量的生命周期,因为被下级作用域内引用,而没有被释放。就导致上级作用域内的变量,等到下级作用域执行完以后才正常得到释放。
具体搜索看我《javascript》文章
tsx
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
react hook 闭包
react
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>
);
};
可以看到 use Effect 在最初执行的时候引用的初始值0,形成了闭包。在后续页面如何加载都不会影响到结果。
使用更新的值
若想想要实时输出变化后的值,需要传入监听值,值变化后重新执行其内的代码 记得清楚定时器
tsx
useEffect(() => {
const interval = setInterval(() => {
console.log("num is setInterval:", num);
}, 1000);
return () => {
clearInterval(interval);
console.log(num);
};
}, [num]);