You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中使用Intersection Observer如何获取最新的state状态值

问题原因

这是React的闭包陷阱导致的:useEffect 仅在 infiniteLoadingRef 变化时执行一次,初始化 IntersectionObserver 时传入的 handleObserver 捕获的是首次渲染时的 someState 快照,后续组件重渲染、someState 更新后,旧的回调函数依旧引用的是初始值,所以读不到最新状态。
你之前把someState加入依赖后触发无限循环,是因为没有在useEffect的清理函数中销毁旧的观察者实例,每次state更新都会新建一个观察者,重复触发回调导致循环。

解决方案

方案1:用useRef存储最新状态(最推荐,无额外性能开销)

用ref同步最新的state值,ref是引用类型,回调中直接读取ref.current就能拿到最新值,不需要修改observer的初始化逻辑:

const [someState, setSomeState] = useState(someVal);
// 新建ref同步state
const someStateRef = useRef(someState);
// 监听state变化更新ref
useEffect(() => {
  someStateRef.current = someState;
}, [someState]);

const handleObserver = (entries: IntersectionObserverEntry[], observer: IntersectionObserver) => {
  if (entries[0].isIntersecting) {
    // 读取ref的current属性获取最新值
    console.log(someStateRef.current);
  }
};

useEffect(() => {
  if (!isInfinite || !infiniteLoadingRef || !infiniteLoadingRef.current)
    return;
  const options = {
    root: null,
    rootMargin: "0px",
    threshold: 0,
  };
  const observer = new IntersectionObserver(handleObserver, options);
  observer.observe(infiniteLoadingRef.current);
  // 加清理函数避免内存泄漏
  return () => {
    observer.disconnect();
  };
}, [infiniteLoadingRef]);

方案2:将state加入依赖数组,增加清理逻辑

如果需要每次state更新都重新创建观察者,可以把someState加入依赖,同时在清理函数中销毁旧的观察者,就不会出现无限循环:

useEffect(() => {
  if (!isInfinite || !infiniteLoadingRef || !infiniteLoadingRef.current)
    return;
  const options = {
    root: null,
    rootMargin: "0px",
    threshold: 0,
  };
  const observer = new IntersectionObserver(handleObserver, options);
  observer.observe(infiniteLoadingRef.current);
  // 组件卸载/依赖变化时销毁旧观察者
  return () => {
    observer.disconnect();
  };
// 把someState加入依赖数组
}, [infiniteLoadingRef, someState]);

内容的提问来源于stack exchange,提问作者Nyi Nyi Hmue Aung

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 04:54:09