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

React自定义useFetch Hook返回两次数据含null引发报错如何修复

问题原因

你遇到的报错和多次打印属于正常的React渲染逻辑,核心问题有两个:

  1. useFetch的loading初始值设置错误,默认是false,导致组件第一次渲染时,请求还未发起就直接进入表格渲染逻辑,此时data初始值为null,调用data.data.map直接触发空值报错
  2. 多次打印是正常的多轮渲染输出:第一次是组件初始化渲染,请求未返回时data为null;后续请求状态更新、数据返回时都会触发重渲染,输出对应状态的data值。如果项目开启了React严格模式,会多一次重复渲染,属于正常情况。
修复方案

分两步修改即可解决问题:

第一步:修正useFetch的初始加载状态

将loading初始值设为true,避免请求未开始时就进入内容渲染逻辑:

import { useState, useEffect } from "react";
import axios from "axios";
const useFetch = (url) => {
  const [data, setData] = useState(null);
  // 初始设为true,组件挂载后默认处于加载状态
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    setLoading(true);
    axios
      .get(url)
      .then((response) => {
        setData(response.data);
      })
      .catch((err) => {
        setError(err);
      })
      .finally(() => {
        setLoading(false);
      });
  }, [url]);

  return { data, loading, error };
};

export default useFetch;

第二步:给表格组件增加异常分支处理和空值保护

补充错误状态的 fallback UI,同时增加data非空判断做双重保险,还要给循环的元素加key属性避免React报警告:

import React from "react";
import Table from "@mui/material/Table";
import TableBody from "@mui/material/TableBody";
import TableCell from "@mui/material/TableCell";
import TableContainer from "@mui/material/TableContainer";
import TableHead from "@mui/material/TableHead";
import TableRow from "@mui/material/TableRow";
import useFetch from "./custom_hooks/useFetch";

const TableComponent = () => {
  const { data, loading, error } = useFetch(
    "https://gorest.co.in/public/v1/users?page=1"
  );

  if (loading) return <h1> LOADING...</h1>;

  // 错误状态返回提示UI
  if (error) return <h1>数据加载失败,请稍后重试</h1>;

  // 双重非空判断,避免异常场景下data为空
  if (!data?.data) return null;

  console.log(data);

  return (
    <TableContainer>
      <Table>
        <TableHead>
          <TableRow>
            <TableCell>User Names</TableCell>
            <TableCell align="right">Email</TableCell>
            <TableCell align="right">Status</TableCell>
            <TableCell align="right">Gender</TableCell>
            <TableCell align="right">ID</TableCell>
          </TableRow>
        </TableHead>
        <TableBody>
          {data.data.map((user) => {
            return (
              <TableRow key={user.id}>
                <TableCell>{user.name}</TableCell>
              </TableRow>
            );
          })}
        </TableBody>
      </Table>
    </TableContainer>
  );
};

export default TableComponent;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 02:27:03