gpt4 book ai didi

javascript - React Hooks - 设置最后一个值?

转载 作者:行者123 更新时间:2023-12-02 22:11:58 26 4
gpt4 key购买 nike

我正在尝试编写基本的钩子(Hook)来在滚动时获取 currentScroll、lastScroll、scrollSpeed。

function useDocScroll() {
const isClient = typeof window === "object"

function getScroll() {
return isClient
? window.pageYOffset || document.documentElement.scrollTop
: undefined
}

const [docScroll, setDocScroll] = useState(getScroll)
const [lastScroll, setLastScroll] = useState(null)
const [scrollSpeed, setScrollSpeed] = useState(Math.abs(docScroll - lastScroll))

useEffect(() => {
if (!isClient) {
return false
}

function handleScroll() {
setDocScroll(getScroll())
setLastScroll(getScroll()) // <-- why is this working?
// setLastScroll(docScroll) // <-- why is this not working?

setScrollSpeed(Math.abs(docScroll - lastScroll)) // <-- why is this not working?
}

window.addEventListener("scroll", handleScroll)
}, [])

return [docScroll, lastScroll, scrollSpeed]
}

似乎当我执行setLastScroll(getScroll())时,它很好地保存了最后一个滚动值。

但我不明白,因为当 handleScroll() 触发时,getScroll() 值不应该保持不变吗?我不明白为什么 setDocScroll(getScroll()) 和 setLastScroll(getScroll()) 具有不同的值。

此外,我认为我可以执行 setLastScroll(docScroll),意思是“用当前 docScroll 值设置 lastScroll 值”,但在 docScroll 值更改时它只打印“0”。

这是为什么呢?我想更好地理解。

+) 我无法获得由 docScrolllastScroll 计算的 scrollSpeed,但我不知道如何获得这些值。

Edit distracted-golick-c89w3

最佳答案

我认为您的代码不起作用的原因有以下两个:

  1. setDocScroll 之后直接使用 docScroll 不起作用,因为 setState 是异步任务。无法保证 docScroll 在执行下一条语句之前更新
  2. 您得到 0 因为滚动发生在某个特定元素内(可能)。由于 document.documentElement 指向 html 元素并且其中没有滚动。所以你会收到 0

解决方案:

您不需要多个 useState。由于滚动事件发出得太频繁,我认为使用 useReducer 来减少渲染次数是个好主意。重要的是要了解滚动发生的位置,无论是在根级别还是在某个元素内部。

对于我提出的以下解决方案:

如果滚动发生在根级别(html 元素),则无需将元素传递给 useDocScroll。如果滚动发生在特定元素内,则需要传递元素引用。

const initState = {
current: 0,
last: 0,
speed: 0,
};

function reducer(state, action) {
switch (action.type) {
case "update":
return {
last: state.current,
current: action.payload,
speed: Math.abs(action.payload - state.current) || 0,
};
default:
return state;
}
}

const isClient = () => typeof window === "object";
function useDocScroll(element = document.documentElement) {
const [{ current, last, speed }, dispatch] = useReducer(reducer, initState);

function getScroll() {
return isClient() ? element.scrollTop : 0;
}

function handleScroll() {
dispatch({ type: "update", payload: getScroll() });
}

useEffect(() => {
if (!isClient()) {
return false;
}

element.addEventListener("scroll", handleScroll);

return () => element.removeEventListener("scroll", handleScroll);
}, []);

return [current, last, speed];
}

示例:

如果滚动发生在窗口内

const {current, last, speed} = useDocScroll()

如果滚动发生在特定元素

const {current, last, speed} = useDocScroll(document.getElementById("main"))

关于javascript - React Hooks - 设置最后一个值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59528571/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com