function createIncrement(incBy) {
let value = 0;
function increment() {
value += incBy;
console.log(value);
}
const message = `Current value is ${value}`; function log() { console.log(message); }
return [increment, log];
}
const [increment, log] = createIncrement(1);
increment(); // 1
increment(); // 2
increment(); // 3
// 不能正确工作!
log(); // "Current value is 0"
[increment, log] = createIncrement(1)返回一个函数元组:一个函数增加内部值,另一个函数记录当前值。然后,increment()的3次调用将 value递增到3。最后,log()调用打印消息是 Current value is 0,这有点出乎意料的,因为此时 value 为 3 了。 4 h, g8 e. _6 I/ I) I L log()是一个过时的闭包。闭包 log()捕获了值为 "Current value is 0"的 message 变量。即使 value 变量在调用increment()时被增加多次,message变量也不会更新,并且总是保持一个过时的值 "Current value is 0"。过时的闭包捕获具有过时值的变量。" Q \/ w! ?$ G2 X 2.修复过时的闭包 & h* M' ?2 E% b 修复过时的log()问题需要关闭实际更改的变量:value的闭包。我们将语句 const message = ...; 移动到 log() 函数内部: 0 r. u* s; G$ ~, p$ ~! W, y
正确设置依赖项后,一旦count发生变化,useEffect()就会更新闭包。3 u' G2 ?5 p, H
3.2 useState() 9 ?+ W4 S7 l5 L/ I) h <DelayedCount>组件有1个button ,以1秒延迟异步增加计数器:) e R9 I9 b m) S0 ]
打开演示(https://codesandbox.io/s/use-state-fixed-zz78r)。再次快速单击按钮2次。计数器显示正确的值2。 ! C! t e6 t% \% ^ ^- o- \" v! p 当一个返回基于前一个状态的新状态的回调函数被提供给状态更新函数时,React确保将最新的状态值作为该回调函数的参数提供: 8 R, f$ z. l V: |( d' c9 b) ?