react hooks 中使用 addEventListener 监听事件无法访问到最新的 state?

862 阅读1分钟

要点:数据变化重新设置监听事件

思考:那么window上的监听事件会爆炸么?还是会覆盖,重新设置后触发时机是怎么样的?

const Exposure = (props: IExposure) => {
  const [hasAsyncData, SetHasAsyncData] = useState(false);

  useEffect(() => {
    if (props.asyncData) {
      SetHasAsyncData(true);
    }
  }, [props.asyncData]);

  useEffect(() => {
    window.addEventListener("touchmove", handleMove, false);
    window.addEventListener("scroll", handleMove, false);
    return () => {
      window.removeEventListener("touchmove", handleMove);
      window.removeEventListener("scroll", handleMove);
    };
  }, []);

  function handleMove() {
    console.log(hasAsyncData);
  }
  return <div ref={measuredRef}></div>;
};

export default Exposure;

如上述代码所示,props.asyncData 变化之后 hasAsyncData 设置为 true,然后滚动页面,handleMove 中的 hasAsyncData 仍然为初始值 false。 所以这时要在 hasAsyncData 变化后,重新绑定 addEventListener 事件

const Exposure = (props: IExposure) => {
  const [hasAsyncData, SetHasAsyncData] = useState(false);

  useEffect(() => {
    if (props.asyncData) {
      SetHasAsyncData(true);
    }
  }, [props.asyncData]);

  useEffect(() => {
    window.addEventListener("touchmove", handleMove, false);
    window.addEventListener("scroll", handleMove, false);
    return () => {
      window.removeEventListener("touchmove", handleMove);
      window.removeEventListener("scroll", handleMove);
    };
  }, [hasAsyncData]); //改动了这里

  function handleMove() {
    console.log(hasAsyncData);
  }
  return <div ref={measuredRef}></div>;
};

export default Exposure;