React项目中如何修正代码实现博客详情页内容展示?
问题描述
我是React新手,离开技术领域许久后正在学习Java,非常感谢您的帮助。请问如何修正我提供的代码,使博客详情页能够按预期展示文章的标题、作者、正文、日期等内容?
现有代码
BlogDetail.js
import React, { useState, useEffect } from "react"; import axios from "axios"; import { Link } from "react-router-dom"; function BlogDetail() { const [setBlogs] = useState([]); useEffect(() => { const fetchBlogs = async () => { try { const res = await axios.get(`http://localhost:8000/api/blog/`); setBlogs(res.data); } catch (err) {} }; fetchBlogs(); }, []); return (BlogPost) => ( <div className="container-m-3"> <article> <Link to={`/blog/${BlogPost.slug}`} className="stretched-link"> {BlogPost.title} </Link> <h1 className="display-2">{BlogPost.title}</h1> <h2 className="text-muted mt-3"> Category: {capitalizeFirstLetter(BlogPost.category)} </h2> <h4> {BlogPost.month} {BlogPost.day} </h4> <p>Written by {BlogPost.author}</p> <div>{BlogPost.body}</div> <hr /> <p className="lead mb-5"> <Link to="http://localhost:8000/api/blog/" className="font-weight-bold" > Front Page </Link> </p> </article> </div> ); } const capitalizeFirstLetter = (word) => { if (word) return word.charAt(0).toUpperCase() + word.slice(1); return ""; }; export default BlogDetail;
App.js
import React from 'react'; import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'; import Layout from './hocs/Layout'; import Home from './components/Home'; import Blog from './components/Blog'; import BlogDetail from './components/BlogDetail'; import Category from './components/Category'; const App = () => ( <Router> <Layout> <Routes> <Route path='/' element={<Home/>} /> <Route path='/blog' element={<Blog/>} /> <Route path='/blog/:id' element={<BlogDetail/>} /> <Route path='/category/:id' element={<Category/>} /> </Routes> </Layout> </Router> ); export default App;
修正方案
你的代码存在几个核心问题,直接修改如下:
1. 修正BlogDetail.js
import React, { useState, useEffect } from "react"; import axios from "axios"; import { Link, useParams } from "react-router-dom"; // 新增useParams导入 function BlogDetail() { // 改为单个博客的状态,初始值为null const [blog, setBlog] = useState(null); // 获取URL中的id参数 const { id } = useParams(); useEffect(() => { const fetchBlog = async () => { try { // 请求单个博客的接口,替换为你后端实际的单篇博客接口 const res = await axios.get(`http://localhost:8000/api/blog/${id}`); setBlog(res.data); } catch (err) { console.error('获取博客详情失败:', err); // 新增错误日志 } }; if (id) { // 确保id存在再请求 fetchBlog(); } }, [id]); // 依赖项添加id,参数变化时重新请求 // 处理加载状态 if (!blog) { return <div className="container mt-3">加载中...</div>; } // 直接返回JSX,而非返回函数 return ( <div className="container mt-3"> {/* 修正class名:container-m-3 → container mt-3 */} <article> <h1 className="display-2">{blog.title}</h1> <h2 className="text-muted mt-3"> Category: {capitalizeFirstLetter(blog.category)} </h2> <h4> {blog.month} {blog.day} </h4> <p>Written by {blog.author}</p> {/* 如果body是HTML内容,用dangerouslySetInnerHTML渲染,否则直接输出 */} <div dangerouslySetInnerHTML={{ __html: blog.body }} /> <hr /> <p className="lead mb-5"> <Link to="/blog" className="font-weight-bold"> {/* 改为前端路由,而非直接跳转到API地址 */} Front Page </Link> </p> </article> </div> ); } const capitalizeFirstLetter = (word) => { if (word) return word.charAt(0).toUpperCase() + word.slice(1); return ""; }; export default BlogDetail;
2. 调整App.js(可选,根据后端接口决定)
如果你的后端用slug而非id来标识单篇博客,需要把路由改为:
<Route path='/blog/:slug' element={<BlogDetail/>} />
同时在BlogDetail.js中把const { id } = useParams();改为const { slug } = useParams();,请求接口改为http://localhost:8000/api/blog/${slug}。
关键修改点说明
- 状态管理修正:详情页只需要单个博客数据,所以把数组状态改为单个对象,初始值设为null。
- 获取URL参数:通过
useParams获取路由中的id/slug,用于请求对应博客。 - 接口请求修正:请求单篇博客的接口,而非所有博客列表。
- 组件返回值修正:React组件直接返回JSX,不能返回函数。
- 加载状态处理:在博客数据未加载完成时显示加载提示,避免渲染undefined属性报错。
- 路由跳转修正:把跳转到API地址的链接改为前端路由
/blog,保持单页应用的跳转逻辑。 - HTML内容渲染:如果博客正文是HTML格式,用
dangerouslySetInnerHTML渲染,否则直接输出即可。
内容的提问来源于stack exchange,提问作者Ben
相关产品推荐
相关产品推荐

