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

Next.js中useEffect+axios+router.query切换路由返回旧数据问题

Next.js动态路由切换时数据未更新的问题解决

问题场景

开发Next.js项目时,组件通过axios结合useEffect钩子获取数据,依赖router.query实现动态路由。但切换路由链接时,页面展示的数据并未更新,依然返回上一个router.query对应的旧数据。尝试用AbortController取消旧请求的方案也未生效。

原因分析

  1. AbortController作用域错误:之前的代码里,abortController定义在fetchData函数内部,useEffect的清理函数无法访问到这个变量,导致旧请求无法被中止。当旧请求延迟返回时,依然会更新state覆盖新数据。
  2. 未处理router.query初始空状态:Next.js路由切换过程中,router.query可能在初始阶段是空对象,直接发起请求会导致无效的API调用(比如请求/api/data/undefined)。
  3. 依赖不够精准:依赖数组使用整个router.query对象,可能因对象内部无关属性变化触发不必要的重渲染,也可能因对象引用未变化导致useEffect不执行。

修复后的代码

import { useEffect, useState } from 'react';
import { useRouter } from 'next/router';
import axios from 'axios';

const MyComponent = () => {
  const router = useRouter();
  const [data, setData] = useState(null);

  useEffect(() => {
    // 将AbortController提升到useEffect顶层,确保清理函数能访问到
    const abortController = new AbortController();
    const { id } = router.query;

    // 先判断id是否存在,避免无效请求
    if (!id) return;

    const fetchData = async () => {
      try {
        const response = await axios.get(`/api/data/${id}`, {
          signal: abortController.signal,
        });
        setData(response.data);
      } catch (error) {
        // 仅在非中止错误时打印日志
        if (error.name !== 'AbortError') {
          console.error('Error fetching data:', error);
        }
      }
    };

    fetchData();

    // 清理函数:中止当前未完成的请求
    return () => abortController.abort();
  }, [router.query.id]); // 直接依赖id,而非整个router.query对象,触发时机更精准

  return (
    <div>
      {data ? (
        <pre>{JSON.stringify(data, null, 2)}</pre>
      ) : (
        <p>加载中...</p>
      )}
    </div>
  );
};

export default MyComponent;

关键优化点

  • 调整AbortController的作用域到useEffect顶层,让清理函数能正常中止旧请求,避免旧数据覆盖新数据。
  • 依赖数组改用router.query.id,仅当id变化时才触发useEffect,减少不必要的请求和重渲染。
  • 增加id空值检查,避免路由切换初期发起无效API请求。
  • 简化错误处理逻辑,过滤掉中止请求的报错,减少日志冗余。

内容的提问来源于stack exchange,提问作者Brandon Han

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 00:01:22