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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 01:45:30