- 每次渲染都有独立的状态(State)
`function Demo() {
const initCount = 0
const [count, setCount] = useState(initCount)
return (
<div>
<h2>{count}</h2>
<button onClick={() => setCount(count + 1)}>count++</button>
</div>
)
}
`
每当用户点击一次按钮 都会从新触发render函数,每次render拿到的都是独立的状态
因为咱们生命count的值时应用const,所以每次渲染拿到的count值是一个独立的常量。
- 每次渲染都有不同且独立的函数(Effect函数)
`function Demo() {
const initCount = 0
const [count, setCount] = useState(initCount)
// 假如在1s内屡次点击按钮 这里打印的count值是什么?
useEffect(() => {
setTimeout(() => {
console.log(count) // 这里打印的会是以后这一次的count值,并不是最新的count值
}, 1000)
})
return (
<div>
<h2>{count}</h2>
<button onClick={() => setCount(count + 1)}>count++</button>
</div>
)
}
`
每次count值扭转,都会触发render,组件从新渲染,所以每次都会生成对应的useEffect函数
而且咱们发现每次打印count的值拿到的都是以后轮次的count值(并不是最新的count)
- useEffect到底是怎么拿到最新的状态值的?
咱们晓得每次渲染都会触发render,每次更新就会生成一个新的Effect函数,并且每一个Effect函数外面都有独立的State,且只能拜访本人本次更新的State。
所以用下面的例子,得出的论断就是:count值其实不是在同一个Effect函数外面产生扭转,而是每一次的组件更新,都会生成一个保护着本次更新的Effect函数,在这个最新的Effect函数里就能够拜访到最新的count值。
- useEffect返回的函数是如何进行清理工作的?
`function Demo() {
const initCount = 0
const [count, setCount] = useState(initCount)
useEffect(() => {
let timer = setTimeout(() => {
console.log(count)
}, 1000)
// 清理工作
return () => {
clearTimeout(timer)
}
})
return (
<div>
<h2>{count}</h2>
<button onClick={() => setCount(count + 1)}>count++</button>
</div>
)
}
`
假如用户点击了两次次按钮 当第一次点击的时候 count + 1 = 1,而后执行clearTimout革除本次的定时器? 接着持续count + 1 = 2 而后执行clearTimeout革除本次的定时器?
正确的程序应该是:当第一次点击 count + 1 = 1,而后clearTimeout会被提早执行,等到第二次点击的时候 count + 1 = 2 再执行上一次的clearTimeout 而后以此类推...问题来了 不是说effect函数只能拜访本次的State吗?那它怎么拿到上一次的clearTimeout并执行的?
其实很简略,就是React会帮你记住每次effect函数的State(包含革除函数),它的确是只能读取本次更新的State,只不过是提早执行了(把革除函数的执行机会放在DOM渲染实现后,在下一次render触发之前)
剩下的内容下期见吧,我累了,当初要去吃麦当劳补充一下能量...
下期预报:useEffect的第二个参数具体解析及应用,在开发中正当应用依赖(防止死循环、性能优化...)