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

React自定义Hook useFetch报错且无法获取数据求助

React自定义Hook useFetch报错且无法获取数据求助

嘿,我仔细看了你的代码,发现几个关键问题导致你拿不到数据,咱们一步步来修复:

1. 最致命的错误:解构方式不对

你的useFetch Hook返回的是单个data值,但你在App组件里用了数组解构const [data] = useFetch(...),这会导致data变成undefined——因为单个值无法被数组解构出第一个元素,正确的做法是直接赋值或者改成返回对象后用对象解构。

2. 缺少请求状态管理与错误处理

你的Hook里没有处理请求加载中、请求失败的情况,也没处理HTTP错误(比如404、500这类状态码,fetch不会自动把它们当成reject),这会让你不知道请求到底是在加载还是真的失败了。

3. 未处理组件卸载后的请求泄漏

如果组件在请求完成前卸载,fetch请求还会继续,可能导致内存泄漏和控制台警告。


修改后的完整代码

useFetch Hook:

import { useEffect, useState } from "react";

const useFetch = (url) => {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    // 创建AbortController用于取消请求
    const controller = new AbortController();

    fetch(url, { signal: controller.signal })
      .then((res) => {
        // 检查HTTP响应是否正常
        if (!res.ok) {
          throw Error("请求数据失败,请检查网络或URL是否有效");
        }
        return res.json();
      })
      .then((responseData) => {
        setData(responseData);
        setLoading(false);
        setError(null);
      })
      .catch((err) => {
        // 忽略取消请求的错误
        if (err.name !== "AbortError") {
          setError(err.message);
          setLoading(false);
        }
      });

    // 组件卸载时取消请求
    return () => controller.abort();
  }, [url]);

  // 返回包含状态的对象,方便组件解构使用
  return { data, loading, error };
};

export default useFetch;

App组件:

import React from 'react';
import useFetch from './useFetch';

const App = () => {
  // 用对象解构获取返回的状态
  const { data, loading, error } = useFetch("https://jsonplaceholder.typicode.com/todos");

  console.log(data);

  // 处理加载中状态
  if (loading) return <div>数据加载中...</div>;
  // 处理错误状态
  if (error) return <div>出错了:{error}</div>;

  return (
    <div>
      {data && data.map((item)=>(<p key={item.id}>{item.title}</p>))}
    </div>
  )
}

export default App;

关键修改点说明:

  • 把useFetch的返回值改成包含data、loading、error的对象,用对象解构更灵活,也避免了之前的解构错误
  • 添加loading状态,让你能看到请求还在进行中,不会误以为拿不到数据
  • 处理HTTP错误:通过res.ok判断响应状态,抛出错误后进入catch块
  • 用AbortController取消组件卸载后的请求,避免内存泄漏
  • 错误处理时排除AbortError,因为取消请求属于正常操作,不需要展示给用户

这样修改后,你应该就能正常获取并渲染数据了,如果还是有问题,可以打开浏览器控制台看看有没有具体的错误提示,再针对性排查~

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.08 14:04:35