useState
反直觉异步更新问题
function UseStateDemo() {
const [num,setNum] = useState(0)
const addNumber = ()=>{
setTimeout(()=>{
setNum(()=> num + 1)
},2000)
}
return {num}
}
复制代码
先说结论:setTimeout里访问的num是闭包里的变量,这在一开始函数执行后就被保存下来了,下一次state更新后,再次render是生成了一个新的函数作用域,所以在这里延时后setTimeout依然会使用旧值去更新。
function preserveNum(){
let num = 0
setTimeout(()=>{
num++
},1000)
return function(){
console.log(num)
}
}
const printNum = preserveNum()
setTimeout(()=>{
printNum() // 1
const newPrintNum = preserveNum()
newPrintNum() //0
},2000)
复制代码
从这个demo上就很好理解了,新执行的preserveNum下,创建了一个新的内部作用域,这当然与第一次执行返回的函数是毫无关联的了。
你或许可以试试下面的奇怪代码
function printAge() {
const [state,setState] = useState(0)
const Kent = {
age: 0
}
const add = ()=>{
setTimeout(()=>{
setState(Kent.age ++)
})
}
return
{state + 'Kent的年龄是' + Kent.age}
}
复制代码
这些问题在诸如使用useMemo
、useCallback
上也是常见的,他们会缓存一些值或函数,这并不是什么高深的东西,就是依靠闭包所完成的。
事实上React hook的抽象是在业务上很符合直觉的,这只取决于如何正确的使用他们。
本文如有错误的地方,欢迎指正和交流
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END