因此,我一直在尝试React Hooks进行更改,但是有些事情我还无法理解,它在功能组件中使用多个状态并在它们之间进行交互。假设我想获取窗口滚动位置及其高度的百分比,然后像这样显示它:
import React, { useState, useLayoutEffect } from 'react'
const Page = () => {
const [scrollPos, setScrollPos] = useState(window.pageYOffset || document.documentElement.scrollTop)
const [windowSize, setWindowSize] = useState(window.innerHeight)
const [percent, setPercent] = useState(0)
useLayoutEffect(() => {
const handleScroll = () => {
const y = window.pageYOffset || document.documentElement.scrollTop
setScrollPos(y)
// windowSize is always its initial value, not its latest
console.log("handleScroll: " + y + " / " + windowSize + " = " + y / windowSize)
setPercent(y / windowSize)
}
window.addEventListener('scroll', handleScroll)
return () => window.removeEventListener('scroll', handleScroll)
}, [])
useLayoutEffect(() => {
const handleResize = () => {
const height = window.innerHeight
setWindowSize(height)
// scrollPos is always its initial value, not its latest
console.log("handleScroll: " + scrollPos + " / " + height + " = " + scrollPos / height)
setPercent(scrollPos / windowSize)
}
window.addEventListener('resize', handleResize)
return () => window.removeEventListener('resize', handleResize)
}, [])
return (
<div>
{/* Calculates percentage correctly upon scrolling and resizing */}
<p>{scrollPos} / {windowSize} = {scrollPos / windowSize}</p>
{/* Incorrect once I scroll after resizing and vice versa */}
<p>!= {percent}</p>
</div>
)
}
export default Page
如果运行此命令,则控制台将不会显示scrollPos
和windowSize
的最新值,而是显示初始值。渲染它们时会显示其最新值。 percent
与此混为一谈,因为它在调整窗口大小或滚动窗口时会抓住其中之一的初始值。
我认为这是因为它异步而引起的那些事情之一,但是很高兴对此有一个更清晰的答案。一个人将如何处理多个“本地”状态,或者在这种情况下使一个合并状态更好呢?