当由 EventListener 调用时,useState 挂钩设置器仅运行一次

Posted

技术标签:

【中文标题】当由 EventListener 调用时,useState 挂钩设置器仅运行一次【英文标题】:useState hook setter is running only once when called by an EventListener 【发布时间】:2020-07-31 09:40:25 【问题描述】:

在我的功能组件中,我使用 useState 挂钩存储状态。每次我的用户到达页面底部时,我都想添加内容。所以我在 useEffect 挂钩内的“滚动”上添加了一个 EventListener。 问题是它在我第一次到达底部时被触发,我的新内容出现并且我的页面长度增加了,所以我可以进一步滚动。但是,没有任何附加内容。 通过console.log,我检查了我的事件是否被很好地触发了!

好像给事件监听器的回调函数卡在了过去,我的setter返回的状态和第一次一样!

gameTeasersToShow 函数有 12 个元素,我知道如果它有效,如果我向下滚动一段时间会崩溃,因为数组不会包含足够的元素。这是一个测试。

function Index ( gameTeasersToShow ) 
  console.log(useScrollToBottomDetec())
  const [state, setState] = React.useState([gameTeasersToShow[0], gameTeasersToShow[1], gameTeasersToShow[2]])

  function handleScrollEvent (event) 
    if (window.innerHeight + window.scrollY >= (document.getElementById('__next').offsetHeight)) 
      setState([...state, gameTeasersToShow[state.length]])
    
  

  React.useEffect(() => 
    window.addEventListener('scroll', handleScrollEvent)
    return () => 
      window.removeEventListener('scroll', handleScrollEvent)
    
  , [])

  return (
    <>
      
        state.map(item => 
          const  title, data  = item
          return (
            <GameTeasers key=title title=title data=data />
          )
        )
      
    </>
  )

【问题讨论】:

你的 useEffect 钩子看起来不错,不过我对 handleScrollEvent 函数有疑问。我认为确定你是否已经滚动到最后一个元素的逻辑是有缺陷的。 __next id 的元素是什么? 这是我的主要元素,我将所有组件都插入其中。他的高度是我页面的最大高度。 handleScrollEvent 应该在使用它的useEffect 中定义 【参考方案1】:

你可以试试吗?

function handleScrollEvent (event) 
    if (window.innerHeight + window.scrollY >= (document.getElementById('__next').offsetHeight)) 
      setState(oldState => [...oldState, gameTeasersToShow[oldState.length]])
    
  

【讨论】:

非常感谢,它成功了!这个二传手和通常的二传手有什么区别? 显然state 变量没有跟踪当前值。可能是因为下面的异步事情。以旧状态为参数的 lambda 确保您将根据旧状态更新状态。

以上是关于当由 EventListener 调用时,useState 挂钩设置器仅运行一次的主要内容,如果未能解决你的问题,请参考以下文章

从外部 window.EventListener 调用函数

ActionScript 3 直接使用参数调用函数形成EventListener

当由 series.columns.template.propertyFields.fill 设置时,图例不遵循系列的颜色,就像使用 series.fill 时一样

当由另一个在堆上分配的对象创建时,对象在哪里分配? [复制]

如何在foreach中调用函数?

需要从代码隐藏中调用 Javascript 方法