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

Next.js 12.3.0使用router.push()偶现浏览器标签页冻结问题求助

Next.js 12.3.0 同页跳转偶尔导致标签页冻结问题

使用Next.js 12.3.0时,点击按钮调用API接口后,通过router.push()跳转至当前页面,该操作85%的情况下正常,但偶尔会出现浏览器标签页完全冻结,无法进行任何操作,只能关闭标签页。浏览器控制台与终端均无报错,应用其他功能正常。已排查无无限渲染或循环问题,当前开启了StrictMode,连续点击按钮8-9次后易触发该问题,怀疑与getServerSideProps被多次调用有关。

相关版本信息

"next": "12.3.0",

按钮点击逻辑代码

<Button                                      
onClick={async() => {              
 await axios
   .patch('url', updateTrackDto)
   .then((res) => { 
       router.push(`/tracks`); // 跳转至当前页面路径
  }).catch((error) => {
       console.log(error);
  });
}>update</Button>

getServerSideProps代码

export async function getServerSideProps(context) {
  const trackId = context.params.trackId;
  const track = await axios.get(`http://127.0.0.1:5000/track/get/${trackId}`);
  return {
    props: {
      track: track.data,
    },
  };
}

排查方向与解决方案

1. 阻止重复请求与跳转堆积

连续点击按钮会触发多次API请求和页面跳转,导致客户端与服务端请求堆积,阻塞主线程。给按钮添加点击禁用状态,在请求完成前禁止重复操作:

const [isLoading, setIsLoading] = useState(false);

<Button                                      
  onClick={async() => {
    if (isLoading) return;
    setIsLoading(true);             
    try {
      await axios.patch('url', updateTrackDto);
      router.push(`/tracks`);
    } catch (error) {
      console.log(error);
    } finally {
      setIsLoading(false);
    }
  }}
  disabled={isLoading}
>
  {isLoading ? '更新中...' : 'update'}
</Button>

2. 优化同页跳转逻辑

使用router.push跳转当前页面时,Next.js会重新触发getServerSideProps,多次连续触发可能导致服务端请求排队,进而阻塞客户端渲染:

  • 若仅需刷新数据,直接在API请求成功后重新获取数据并更新本地状态,避免页面跳转:
    // 组件内维护track状态
    const [track, setTrack] = useState(props.track);
    
    // 点击逻辑中替换跳转为状态更新
    await axios.patch('url', updateTrackDto);
    const freshTrack = await axios.get(`http://127.0.0.1:5000/track/get/${trackId}`);
    setTrack(freshTrack.data);
    
  • 若必须跳转,添加shallow: true参数减少不必要的服务端请求(getServerSideProps仍会执行,但仅更新客户端路由):
    router.push(`/tracks`, undefined, { shallow: true });
    

3. 处理StrictMode的重复调用影响

StrictMode在开发环境下会重复调用getServerSideProps等数据获取方法,可能加剧请求堆积。可临时关闭StrictMode验证问题是否消失,但更推荐从请求控制层面解决,而非长期关闭StrictMode。

4. 给服务端请求添加超时

getServerSideProps中的axios请求未设置超时,若服务端响应缓慢,多次请求会占用资源。添加超时配置避免请求长时间阻塞:

const track = await axios.get(`http://127.0.0.1:5000/track/get/${trackId}`, {
  timeout: 5000 // 设置5秒超时
});

内容的提问来源于stack exchange,提问作者Ahmed Sbai

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 20:35:30