将这三行代码放入组件中,您将看到它们的优先顺序。
useEffect(() => {
console.log('useEffect')
return () => {
console.log('useEffect cleanup')
}
})
window.requestAnimationFrame(() => console.log('requestAnimationFrame'))
useLayoutEffect(() => {
console.log('useLayoutEffect')
return () => {
console.log('useLayoutEffect cleanup')
}
})
useLayoutEffect > requestAnimationFrame > useEffect
您遇到的问题是由执行loopRaf
清理功能之前请求另一个动画帧引起的useEffect
。
进一步的测试表明,该useLayoutEffect
操作始终在之前被调用,requestAnimationFrame
并且其清理功能在下一次执行之前被调用,以防止重叠。
更改useEffect
为useLayoutEffect
,它应该可以解决您的问题。
useEffect
并useLayoutEffect
按照它们在代码中出现的顺序调用,就像useState
调用一样。
您可以通过运行以下几行来查看:
useEffect(() => {
console.log('useEffect-1')
})
useEffect(() => {
console.log('useEffect-2')
})
useLayoutEffect(() => {
console.log('useLayoutEffect-1')
})
useLayoutEffect(() => {
console.log('useLayoutEffect-2')
})