setup
函数仅被调用一次,这在性能上比较占优。函数prop
给子组件的引用变化,导致无必要的重新渲染。Hooks 严重依赖于 JS 闭包,但是闭包有时很棘手,当咱们使用一个有多种副作用和状态管理的 React 组件时,可能会遇到的一个问题是过时的闭包
。
function createIncrement(i) {
let value = 0;
function increment() {
value += i;
console.log(value);
const message = `Current value is ${value}`;
return function logValue() {
console.log(message);
};
}
return increment;
}
const inc = createIncrement(1);
const log = inc(); // 打印 1
inc(); // 打印 2
inc(); // 打印 3
// 无法正确工作
log(); // 打印 "Current value is 1"
解决过时闭包的第一种方法是找到捕获最新变量的闭包。
找到捕获了最新 message
变量的闭包,就是从最后一次调用 inc() 返回的闭包。
const inc = createIncrement(1);
inc(); // 打印 1
inc(); // 打印 2
const latestLog = inc(); // 打印 3
// 正常工作
latestLog(); // 打印 "Current value is 3"
latestLog
捕获的 message
变量具有最新的的值 “Current value is 3”。
Hooks 实现假设在组件重新渲染之间,作为 Hook 回调提供的最新闭包(例如 useEffect(callback)
) 已经从组件的函数作用域捕获了最新的变量。
第二种方法是让logValue()
直接使用 value
:
function createIncrementFixed(i) {
let value = 0;
function increment() {
value += i;
console.log(value);
return function logValue() {
const message = `Current value is ${value}`;
console.log(message);
};
}
return increment;
}
const inc = createIncrementFixed(1);
const log = inc(); // 打印 1
inc(); // 打印 2
inc(); // 打印 3
// 正常工作
log(); // 打印 "Current value is 3"
logValue()
关闭 createIncrementFixed()
作用域内的 value
变量。log()
现在打印正确的消息“Current value is 3
”。
// 正确设置 Hook 的依赖项
const [count, setCount] = useState(0);
useEffect(function() {
const id = setInterval(function log() {
console.log(`Count is: ${count}`);
}, 2000);
return function() {
clearInterval(id);
}
}, [count]);
// 函数方式更新状态
const [count, setCount] = useState(0);
function handleClickAsync() {
setTimeout(function delay() {
setCount(count => count + 1);
}, 1000);
}
function handleClickSync() {
setCount(count + 1);
}
.
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。