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

React项目使用useFetch调用后端API时出现白屏问题求助

解决自定义useFetch Hook导致页面白屏问题

问题根源分析

你的useFetch Hook存在几个关键问题,直接引发了页面白屏:

  • 状态初始化错误:loading和error被初始化为数组[false],但后续赋值用的是布尔值,状态类型不一致会触发React渲染异常。
  • 错误处理不规范:catch中直接把Error对象存入状态,React无法正常渲染Error对象,会抛出未捕获错误导致白屏。
  • 缺失组件卸载时的请求中断:组件卸载后如果请求还未完成,更新状态会触发警告甚至报错。

修改后的useFetch Hook

import { useEffect, useState } from "react"
import axios from "axios";

const useFetch = (url) => {
    const [data, setData] = useState([])
    // 修正:初始化为布尔值而非数组
    const [loading, setLoading] = useState(false)
    const [error, setError] = useState(null)

    useEffect(()=>{
        // 创建取消令牌,防止组件卸载后更新状态
        const source = axios.CancelToken.source();
        
        const fetchData = async ()=>{
            setLoading(true)
            setError(null) // 重置错误状态
            try{
                const res = await axios.get(url, {
                    cancelToken: source.token
                });
                setData(res.data);
            }catch(err){
                // 排除取消请求的情况,避免误判为错误
                if(!axios.isCancel(err)){
                    // 存储错误信息而非整个Error对象
                    setError(err.message || '请求失败')
                }
            }finally{
                setLoading(false)
            }
        };
        fetchData();

        // 组件卸载时取消请求
        return () => source.cancel('组件已卸载,取消请求');
    },[url])

    const reFetch = async ()=>{
        setLoading(true)
        setError(null)
        try{
            const res = await axios.get(url);
            setData(res.data);
        }catch(err){
            setError(err.message || '请求失败')
        }finally{
            setLoading(false)
        }
    };

    return { data, loading, error, reFetch}
};

export default useFetch;

优化Featured组件的渲染逻辑

在组件中添加加载和错误状态的处理,避免请求出错时直接白屏:

import useFetch from "../../hooks/useFetch";
import "./featured.css";

const Featured = () => {
  const { data, loading, error } =  useFetch(
    "/hotels/countByCity?cities=freetown,makeni,bo"
  );

  // 加载状态时显示加载提示
  if(loading) return <div className="loading">加载中...</div>;
  
  // 错误状态时显示错误信息
  if(error) return <div className="error">获取数据失败:{error}</div>;

  return (
    <div className="featured">
      {/* 可根据接口返回的data动态渲染数据,示例保留静态兜底值 */}
      <div className="featuredItem">
        <img
          src="https://tourismsierraleone.com/wp-content/uploads/2021/08/Freetown2.jpg"
          alt="Freetown"
          className="featuredImg"
        />
        <div className="featuredTitles">
          <h1>Freetown</h1>
          <h2>{data?.[0] || 20} properties</h2>
        </div>
      </div>
      
      <div className="featuredItem">
        <img
          src="https://upload.wikimedia.org/wikipedia/commons/c/c0/Makeni_Wusum.JPG"
          alt="Makeni"
          className="featuredImg"
        />
        <div className="featuredTitles">
          <h1>Makeni</h1>
          <h2>{data?.[1] || 50} properties</h2>
        </div>
      </div>
      <div className="featuredItem">
        <img
          src="https://www.visitsierraleone.org/wp-content/uploads/2021/08/doha-1.jpg"
          alt="Bo"
          className="featuredImg"
        />
        <div className="featuredTitles">
          <h1>Bo</h1>
          <h2>{data?.[2] || 35} properties</h2>
        </div>
      </div>
    </div>
  );
};

export default Featured;

额外检查项

  1. 确认axios已配置正确的baseURL,否则相对路径请求会指向当前前端域名,导致404错误。
  2. 查看浏览器控制台的Network和Console标签,确认请求是否成功、是否存在未捕获的错误。

内容的提问来源于stack exchange,提问作者Usifu Barrie M

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 15:55:28