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;
额外检查项
- 确认axios已配置正确的
baseURL,否则相对路径请求会指向当前前端域名,导致404错误。 - 查看浏览器控制台的Network和Console标签,确认请求是否成功、是否存在未捕获的错误。
内容的提问来源于stack exchange,提问作者Usifu Barrie M
相关产品推荐
相关产品推荐

