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

Next.js 14中React-Intersection-Observer无限循环问题修复

问题:Next.js 14使用React-Intersection-Observer触发无限更新循环错误

我的Next.js 14应用在使用React-Intersection-Observer库时出现以下错误:

超出最大更新深度。当组件在componentWillUpdate或componentDidUpdate中反复调用setState时可能会发生这种情况。React限制嵌套更新的次数以防止无限循环。

我的代码如下:

"use client"
import { useInView } from "react-intersection-observer";
import { useRouter } from "next/navigation";
import { useEffect } from "react";

interface Props{
   dark: boolean;
}
export const LoadMore = async ({dark}: Props) => {

  const { ref, inView } = useInView({
    threshold: 0
  })

  const router = useRouter();

  useEffect(() => {
    if(inView)
      router.push(`?page=${2}`, { scroll: false});
  }, [inView])

return (
<>
<div 
// 给这个div分配ref时就会出问题
ref={ref}
className={`${!dark ? "lds-ellipsis" : "lds-ellipsis dark"} `}><div></div><div></div><div></div><div></div></div>
</>
)
}

我尝试用useCallback钩子但无效,请问如何修复该问题避免应用崩溃?


解决方案

问题根源

  1. 客户端组件不能是异步函数:你给LoadMore组件加了async关键字,但Next.js的"use client"组件不能声明为异步(除非配合Suspense使用,但这里场景不需要),这会导致组件渲染逻辑异常,触发不必要的更新。
  2. 无限循环触发路由跳转:当元素进入视口时inView变为true,触发router.push修改URL参数,页面重新渲染后会重新创建useInView实例,元素再次被判定为进入视口,又触发跳转,形成无限循环。

修复步骤

  1. 移除组件的async关键字
  2. 添加状态标记是否已经执行过跳转,避免重复触发
  3. 可选:给useInView添加triggerOnce: true配置,让 intersection 事件只触发一次

修复后的代码示例

"use client"
import { useInView } from "react-intersection-observer";
import { useRouter } from "next/navigation";
import { useEffect, useState } from "react";

interface Props{
   dark: boolean;
}
export const LoadMore = ({dark}: Props) => {
  // 添加triggerOnce: true,让只触发一次视口检测
  const { ref, inView } = useInView({
    threshold: 0,
    triggerOnce: true
  })

  const router = useRouter();
  // 状态标记是否已经触发过加载
  const [hasLoaded, setHasLoaded] = useState(false);

  useEffect(() => {
    // 只有当元素在视口且未加载过时才执行跳转
    if(inView && !hasLoaded) {
      setHasLoaded(true);
      router.push(`?page=${2}`, { scroll: false});
    }
  }, [inView, hasLoaded, router])

return (
<>
<div 
ref={ref}
className={`${!dark ? "lds-ellipsis" : "lds-ellipsis dark"} `}>
  <div></div><div></div><div></div><div></div>
</div>
</>
)
}

内容的提问来源于stack exchange,提问作者Danish Siddiqui

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 09:43:28