在下面给出的react.js代码中,我在页面加载时获取一些数据。我使用
arePostsLoading
状态变量来跟踪数据是否已加载。我还添加了一个函数 handleScroll
,它跟踪滚动并在页面滚动到页面末尾时运行另一个函数 loadMorePosts
。现在我使用 console.log 检查 arePostsLoading
函数内 loadMorePosts
的值。
现在,当页面加载时,
arePostsLoading
最初为 true。然后加载内容并将值设置为 false。我可以确认该值设置为 false,因为当变量的值为 false 时,加载的内容在页面上可见,并且加载微调器被隐藏。之后,我将页面滚动到底部以触发 loadMorePosts
函数,该函数只是 console.log 的 arePostsLoading
值(用于测试)。我得到的记录值是 true
,这不是 arePostsLoading
的当前值。这让我很困惑,因为 arePostsLoading
的当前值应该是 false(这是由加载的内容和反应开发工具确认的)。
经过大量调试后,我发现了问题,我在页面加载开始时添加到事件侦听器的函数包含
arePostsLoading
的旧值。我通过添加 arePostsLoading
作为依赖项来修复此问题,以便在更改 arePostsLoading
值时创建新的事件侦听器。
问题已解决,但我不明白为什么会这样。我只是将函数传递给事件侦听器而不是
arePostsLoading
的值,那么为什么它采用旧值。另外,如果我在 loadMorePosts
中添加另一个函数,然后 console.log 该值会给出新值(下面的示例:例如)?
抱歉,问题的描述太长了。我只是想让它非常清楚地理解。
代码:
const [arePostsLoading, setArePostsLoading] = useState(true);
//load posts
const getAllPosts = async (newPageNo, newPageSize) => {
setArePostsLoading(true);
const [data, error] = await sendRequest(
//...fetch data code
);
if (error) {
console.log(error);
handleError(error);
return;
}
setArePostsLoading(false);
};
useEffect(() => {
function handleScroll() {
const scrollHeight = document.documentElement.scrollHeight;
const clientHeight = document.documentElement.clientHeight + 2;
const scrollTop =
window.pageYOffset || document.documentElement.scrollTop;
// Check if the user has scrolled to the bottom of the page
if (scrollHeight - scrollTop < clientHeight) {
// Perform your action here, such as loading more content
console.log("End of page reached!");
loadMorePosts();
}
}
// Attach the scroll event listener to the window object
window.addEventListener("scroll", handleScroll);
// Clean up the event listener when the component is unmounted
return () => {
window.removeEventListener("scroll", handleScroll);
};
}, []);
// }, [arePostsLoading]); // fix added later
//eg 1 : example code
function loadMorePosts(){
test1();
}
test1(){
console.log(arePostsLoading);
}
按照您编写代码的方式,每次渲染组件时都会重新创建
getAllPosts()
函数。而handleScroll()
函数是在useEffect()
时创建的,会记录组件挂载的状态;因此在处理程序中您将无法访问更新后的状态。
您应该将窗口监听器回调函数放在
useCallback()
钩子中。此外,正如您意识到的那样,没有理由将状态变量放入依赖项中。
请参阅此 StackOverflow 帖子了解示例