当函数添加到事件监听器时,状态变量给出旧值

问题描述 投票:0回答:1

在下面给出的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);
  }
reactjs react-hooks
1个回答
0
投票

按照您编写代码的方式,每次渲染组件时都会重新创建

getAllPosts()
函数。而
handleScroll()
函数是在
useEffect()
时创建的,会记录组件挂载的状态;因此在处理程序中您将无法访问更新后的状态。

您应该将窗口监听器回调函数放在

useCallback()
钩子中。此外,正如您意识到的那样,没有理由将状态变量放入依赖项中。

请参阅此 StackOverflow 帖子了解示例

© www.soinside.com 2019 - 2024. All rights reserved.