成因:
setInterval形成了一个闭包
react中的hook是以链表的形式存在,且执行逻辑依赖于deps
解法:
state以函数的形式执行
使用ref作为全局变量去处理
useState闭包解决办法尝试用函数形式
setTimeout(() => {
setNum( num + 1);
}, 1000);
变成这种
setTimeout(() => {
setNum((num) => num + 1);
}, 1000);
import React from "react";
import { useState, useEffect } from "react";
export default function Closure() {
return (
<div>
闭包陷阱
<UseState />
</div>
);
}
const UseState = () => {
const [num, setNum] = useState(0);
const handleClick = () => {
setTimeout(() => {
setNum((num) => num + 1);
}, 1000);
};
return (
<div>
<span>{num}</span>
<button onClick={handleClick}>+</button>
</div>
);
};
useEffect闭包解决办法常使用ref
import React from "react";
import { useState, useEffect } from "react";
export default function Closure() {
return (
<div>
闭包陷阱
<UseEffect />
</div>
);
}
const UseEffect = () => {
const [num, setNum] = useState(0);
const numRef = React.useRef(0);
useEffect(() => {
setInterval(() => {
console.log(numRef.current);
}, 1000);
}, []);
return (
<div>
<span>{num}</span>
<button
onClick={() => {
numRef.current = num + 1;
setNum(num + 1);
}}
>
+
</button>
</div>
);
};