useState和addEventListener挂载事件问题

我想监听滚动事件进行一些判断,于是设置了一个state。
const [count,seTCount]=useState(0)
用addEventListener监听滚动事件时发现,滚动事件触发的函数执行多次后setU的事件只触发一次,后来百度发现在一次事件里对同个state进行增加的话,只会执行最后一个setU。
于是采用了setCount((count)=>u+1);setCount((count)=>count+1)这个方法,发现可以后便增加判断语句 if(count<3){setCount((count)=>count+1)},然后继续测试。
此时发现判断语句没有生效,他还是在哗啦哗啦的增加,输出count发现,还是为0.
这时候分别在按钮、滚动事件里面输出count,发现两个值不是同一个。
代码如下:

function App(){
    const [count,setCount]=useState(0)
    const scrollHander=()=>{
        console.log(count)
        if(count<3){
            setCount(count+1)
        }
    }
    useEffect(()=>{
        document.addEventListener('scroll',scrollHander)
    },[])
    return (
        <div>
          <h1>{count}</h1>
          <button onClick={()=>{
            // scrollHander()
              setCount(count+1)
              console.log(count)
              }}>+1</button>
          {
            [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(item => (
              <div>
                <h1>{count}</h1>
                <button>{item}</button>
              </div>
            ))
          }
        </div>
    );
}
ReactDOM.render(<App />, document.getElementById('root'));

这是怎么回事?

阅读 5k
2 个回答

第一,你依赖了state却加了空数组
image.png

第二,你需要销毁scroll,否则每次更新都会累计scroll绑定

useEffect 中引用了 scrollHander 却没有声明依赖,所以滚动事件只会绑定第一次渲染组件时创建的 scrollHander

一个方案供参考

 import React, { useState,useEffect  } from "react";
 import ReactDOM from "react-dom";
 
 function App(){
   const [count, setCount]=useState(0)
   
+  useEffect(() => {
+    let scrollCount = 0
+    const scrollHander = () => {
+      console.log('scroll total count', scrollCount)
+      if (++scrollCount < 3) {
+        setCount(scrollCount)
+      }
+    }
+    document.addEventListener('scroll',scrollHander)
+    return () => {
+      document.removeEventListener('scroll', scrollHander)
+    }
+  }, [])
 
   return (
       <div>
         <h1>{count}</h1>
         <button onClick={()=>{
           // scrollHander()
+            setCount(count => count + 1)
             console.log(count)
             }}>+1</button>
         {
           [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(item => (
+            <div key={item}>
               <h1>{count}</h1>
               <button>{item}</button>
             </div>
           ))
         }
       </div>
   );
 }
 ReactDOM.render(<App />, document.getElementById('root'));
推荐问题