React.js控制台有数据但UI不显示,按ID查看博客空白求助
问题修复方案:React数据获取后UI不渲染+单博客页面空白
一、useFetch Hook的核心错误分析
- Signal参数错误:
fetch配置中误用AbortController.signal,正确应该使用当前实例的abortCont.signal,否则中止控制器逻辑失效,可能导致状态更新异常。 - setTimeout语法错误:延迟参数
1000被错误放在catch块的括号内,属于语法错误,导致定时器无法正常生效。 - 错误处理逻辑漏洞:
catch块中,即使是AbortError也会执行setError,干扰UI的错误状态判断。 - 不支持动态请求地址:Hook固定请求
/blogs列表,无法传入单个博客的ID请求路径,导致按ID查看时无法获取对应数据,页面空白。
二、修复后的完整useFetch代码
import { useEffect, useState } from "react"; const useFetch = (url) => { // 新增url参数,支持动态请求地址 const [data, setData] = useState(null); const [isPending, setIsPending] = useState(true); const [error, setError] = useState(null); useEffect(() => { const abortCont = new AbortController(); setTimeout(() => { fetch(url, { signal: abortCont.signal }) // 使用当前控制器的signal .then(res => { if (!res.ok) { throw Error('无法获取该资源的数据'); } return res.json(); }) .then(data => { setData(data); setIsPending(false); setError(null); }) .catch(err => { if (err.name === 'AbortError') { console.log('请求已取消'); } else { // 仅处理非取消类错误 setIsPending(false); setError(err.message); } }); }, 1000); // 延迟参数移至正确位置 return () => abortCont.abort(); }, [url]); // 添加url为依赖项,地址变化时自动重新请求 return { data, isPending, error }; }; export default useFetch;
三、UI渲染与单博客页面的修复建议
1. 博客列表页面渲染
确保判断加载状态、错误状态,仅在数据存在时渲染内容:
import useFetch from './useFetch'; function BlogList() { const { data: blogs, isPending, error } = useFetch('http://localhost:3000/blogs'); return ( <div className="blog-list"> {error && <div className="error">{error}</div>} {isPending && <div className="loading">加载中...</div>} {blogs && blogs.map(blog => ( <div key={blog.id} className="blog-preview"> <h2>{blog.title}</h2> <p>作者:{blog.author}</p> </div> ))} </div> ); }
2. 单博客详情页面
通过路由参数获取ID,传入对应请求地址:
import { useParams } from 'react-router-dom'; import useFetch from './useFetch'; function BlogDetails() { const { id } = useParams(); const { data: blog, isPending, error } = useFetch(`http://localhost:3000/blogs/${id}`); return ( <div className="blog-details"> {error && <div className="error">{error}</div>} {isPending && <div className="loading">加载中...</div>} {blog && ( <article> <h2>{blog.title}</h2> <p>作者:{blog.author}</p> <div>{blog.body}</div> </article> )} </div> ); }
内容的提问来源于stack exchange,提问作者Sebbie Chanzu
相关产品推荐
相关产品推荐

