【问题标题】:React functional component state always logs initial valueReact 功能组件状态总是记录初始值
【发布时间】:2021-05-28 04:40:36
【问题描述】:

当我滚动一个 div 的底部时,我将更新状态。 我已成功检测到用户滚动的 div 底部,但更新状态总是记录初始值。 这是我的代码。

const ExampleApp = () => {
  const [value, setValue] = useState(0);
  useEffect(() => {
        document.addEventListener('scroll', trackScrolling);
        return () => {
            document.removeEventListener('scroll', trackScrolling);
        }
    }, []);
  const trackScrolling = () => {
    const wrappedElement = document.getElementById('vContainer');
    if (isBottom(wrappedElement)) {
        // Here user scrolled to bottom of a div
        console.log('Log Value: ', value); // I want to see the increased value, but always logs 0 every time I scrolled bottom.
        setValue(value + 1);
    }
  }
}

我很好奇为什么每次检测到视图底部时值都没有增加。 当我检测到底部时增加状态值的解决方案是什么。 提前致谢。

【问题讨论】:

  • 嗯...函数isBottom 在其他地方定义,我确信底部检测效果很好。当我检测到视图的底部时,我正在尝试增加状态值。但每次我到达视图底部时它总是记录 0。
  • 我刚刚尝试了你的示例代码,但它总是记录 0。它记录了你这边增加的价值吗?
  • 嗯...是的。但是你能看到控制台日志吗?每次我向上滚动并触底时,它总是记录值 0。而且浏览器中的值总是1。为什么它没有增加?
  • 应用这个方法也可能会排队。

标签: reactjs react-hooks react-functional-component


【解决方案1】:

因为关闭而发生。

使用document.addEventListener('scroll', trackScrolling),函数属性trackScrolling 与侦听器关联,并与初始value 绑定,即0

检查这个 sn-p: (尝试 sn-p 时不要单击整页,否则您将看不到滚动)

function App() {

  const [value, setValue] = React.useState(0)

  function isBottom(e) { return true }

  React.useEffect(() => {
    document.addEventListener('scroll', trackScrolling)
    return () => {
      document.removeEventListener('scroll', trackScrolling)
    }
  }, [])

  const trackScrolling = () => {
    const wrappedElement = document.getElementById('vContainer')

    if (isBottom(wrappedElement)) {
      console.log('Log Value1: ', value)
      setValue(prev => { 
        console.log('Log Value2: ', prev + 1);
        return prev + 1;
       })
    }
  }
  return <div id="vContainer" style={{height: 500,background: 'yellow', overflow: 'scroll'}}>{value}</div>
}

ReactDOM.render(<App />, document.getElementById('mydiv'))
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<body>
<div id="mydiv"></div>
</body>

【讨论】:

  • 嗯.. 谢谢 Ajeet。我试过你的解决方案。但 Log Value1 始终为 0,而 Log Value2 增加值。 1, 2,3 ...
  • @daniels 是的。我保留了它以查看差异。 Log Value1 将始终为 0
  • 为什么总是0而不是增加值?我们调用了setValue 函数。
  • 因为初始值被绑定在闭包中。更多关于关闭的信息:MDNW3Schoolsthis SO post
  • 谢谢。 useRef 是我一直在寻找的。 +1
【解决方案2】:

您的console 语句发生在您设置新值之前,只需将两行切换为:

 setValue(value + 1);
 console.log('Log Value: ', value);

【讨论】:

  • 嗯.. 但是如果我试图在几秒钟后到达视图底部,它仍然会记录 0 而不是 1。
  • 我不确定我是否遵循,你能提供一个工作示例吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-05-28
  • 2020-11-01
  • 2023-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-04
相关资源
最近更新 更多