我正在处理一个Next.js项目,其中有一个使用axiosuseEffect钩子获取数据的组件.基于router.query对象来获取数据以实现动态路由.然而,我面临的问题是,更改链接不会更新获取的数据,它会返回前router.query中的旧数据.

以下是我的代码的简化版本:

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(() => {
    const fetchData = async () => {
      try {
        const response = await axios.get(`/api/data/${router.query.id}`);
        setData(response.data);
      } catch (error) {
        console.error('Error fetching data:', error);
      }
    };

    fetchData();

    return () => {
      // Optional cleanup function if needed
    };
  }, [router.query]);

  return (
    <div>
      {/* Render data here */}
    </div>
  );
};

export default MyComponent;

为了解决这个问题,当useEffect使用新的router.Query值运行时,我try 使用AbortController取消上一次提取.然而,这种方法似乎并没有解决问题,我仍然从前面的查询中获得过时的数据.

以下是try 的代码:

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(() => {
    const fetchData = async () => {
      const abortController = new AbortController();

      try {
        const response = await axios.get(`/api/data/${router.query.id}`, {
          signal: abortController.signal,
        });
        setData(response.data);
      } catch (error) {
        if (error.name === 'AbortError') {
          console.log('Fetch aborted');
        } else {
          console.error('Error fetching data:', error);
        }
      }
    };

    fetchData();

    return () => {
      abortController.abort();
    };
  }, [router.query]);

  return (
    <div>
      {/* Render data here */}
    </div>
  );
};

export default MyComponent;

推荐答案

我认为你面临的问题是,当路由改变时,useEffect号列车再次运行,但新数据不能立即获得(因为它需要首先加载).因此,由路由改变触发的第一次重新渲染仍然具有处于data状态的先前数据.

我会保留AbortController(因为如果您在多个页面上导航太快而无法完成任何请求,它可能会很有用),但您还应该在请求新数据之前重置data状态:

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(() => {
    const fetchData = async () => {
      setData(null) // <= HERE!

      const abortController = new AbortController();

      try {
        const response = await axios.get(`/api/data/${router.query.id}`, {
          signal: abortController.signal,
        });

        setData(response.data);
      } catch (error) {
        if (error.name === 'AbortError') {
          console.log('Fetch aborted');
        } else {
          console.error('Error fetching data:', error);
        }
      }
    };

    fetchData();

    return () => {
      abortController.abort();
    };
  }, [router.query]);

  return (
    <div>
      {/* Render data here */}
    </div>
  );
};

export default MyComponent;

Javascript相关问答推荐

如何将元素排列得彼此靠近?

如何在pixi js中画一条简单的线

Vue v模型检测父参考更改

我可以在useState中调用函数并使用其数据吗

订阅操作顺序

使用ReactJS对Ant Design表中的空值进行排序

我不明白这个react 组件有什么问题

nPM审计始终发现0个漏洞

在HTML中使用脚本变量作为背景图像源

JavaScript文本区域阻止KeyDown/KeyUp事件本身上的Alt GR +键组合

用JS从平面文件构建树形 struct 的JSON

Eval vs函数()返回语义

查询参数中的JAVASCRIPT/REACT中的括号

Webpack在导入前混淆文件名

按下单键和多值

使用Ace编辑器对子组件实例的native-element 进行Angular 获取时面临的问题

AJAX POST在控制器中返回空(ASP.NET MVC)

Docent.cloneNode(TRUE)不克隆用户输入

在Java脚本中录制视频后看不到曲目

将Singleton实例设置为未定义后的Angular 变量引用持久性行为