setState()后state并未更新
闭包
当函数可以记住并访问所在的词法作用域时,就产生了闭包,即使函数是在当前词法作用域之外执行。
打包了当前作用域,且超越了当前作用域,在此之外也可以执行。
有状态函数
有状态函数就是利用闭包,使得函数拥有内部状态,这样每一次调用函数会基于上一次的结果产生不一样的结果。
setState 为什么调用“失效”
- 调用时我们确实改变了state,但是并不持续追踪state变化。
- 函数在每次渲染时也是独立的。
如何拿到state最新值
- useEffect()
[]中监听state改变。在useEffect中,组件dom已经挂载更新完毕,可以拿到state的最新值
import React, {useEffect, useRef, useState} from "react";
export default function Vendor() {
const [count, setCount] = useState(0);
useEffect(()=>{
//需要使用最新值进行的操作
console.log(count)
},[count])
return (
<div>
<p>点击了 {count} 次</p>
<button onClick={() => {
setCount(count+1)
} }>
点
</button>
</div>
);
}
- setState中写成回调函数形式,可以取到最新的state, 回调函数中return的返回值即最新的state值
export default function Vendor() {
const [count, setCount] = useState(0);
return (
<div>
<p>点击了 {count} 次</p>
<button onClick={() => {
setCount(preCount=> {
console.log('更新前的state'+preCount)
//const newCount=1000
const newCount=preCount+1
console.log('更新后的state'+newCount)
return newCount
})
} }>
点我
</button>
</div>
);
}
– 或者,setState后刷新页面refresh,进行state更新
- useRef保存值。
直接写在组件内部的对象,组件每次渲染都会生成一个和之前不一样的对象,useRef对象,可以确保组件每次渲染取到的都是同一个对象
export default function Vendor() {
const countRef = useRef(null)
const [count, setCount] = useState(0);
useEffect(() => {//组件每次挂载完,countRef.current会存储上最新的值
countRef.current = count
}, [count])
return (
<div>
<p>点击了 {count} 次</p>
<button onClick={() => {
countRef.current=count+1//countRef.current不随着组件每次渲染变化,先把新值存在这里
setCount(count+1)
console.log(countRef.current)//使用新值的逻辑
} }>
点我
</button>
</div>
);
}