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

React项目中Blog.js与PostDetails.js渲染异常及路由问题咨询

博客页面渲染异常与跳转功能修复方案

一、Blog页面仅显示Navbar和Footer的原因及修复

核心问题1:react-router-dom v6路由写法错误

你使用的是react-router-dom v6,但App.js中Route组件仍沿用v5的component属性,v6中必须用element属性指定渲染组件,这直接导致Blog和PostDetails组件无法被正确渲染。

核心问题2:Blog组件内嵌套路由写法错误

v6中不能在组件内直接使用Route标签,嵌套路由需要通过Outlet配合父路由的children配置实现,原Blog.js里的Route写法完全无效。

核心问题3:静态文件路径错误

create-react-app中静态资源需放在public文件夹下,原fetch('./data/posts.json')的相对路径会导致文件找不到,最终posts数组为空,PostList无内容。

修复代码:

修改App.js:

import Layout from "./components/layout/Layout";
import Blog from "./Blog";
import Home from "./pages/Home";
import Contact from "./pages/Contact";
import Navbar from "./components/layout/Navbar";
import { BrowserRouter as Router, Route, Routes } from "react-router-dom";
import PostDetails from "./components/PostDetails";

function App() {
  return (
    <Router>
      <div>
        <h1>SME Analyst</h1>
        <div className="App">
          <Navbar />
          <Routes>
            <Route path="/" element={<Home />}/>
            {/* 改用element属性,同时配置嵌套路由 */}
            <Route path="/blog" element={<Blog />}>
              <Route path=":postId" element={<PostDetails />} />
            </Route>
            <Route path="/contact" element={<Contact />}/>
          </Routes>
          <Layout />
        </div>
      </div>
    </Router>
  );
}

export default App;

修改Blog.js:

import React, { useState, useEffect } from 'react';
import { Outlet } from 'react-router-dom'; // 引入Outlet渲染嵌套路由
import PostList from './components/PostList';

const Blog = () => {
  const [posts, setPosts] = useState([]);

  useEffect(() => {
    // 改用绝对路径,确保public/data/posts.json存在
    fetch('/data/posts.json')
      .then(response => {
        if (!response.ok) throw new Error('加载文章列表失败');
        return response.json();
      })
      .then(data => setPosts(data))
      .catch(err => console.error(err));
  }, []);

  return (
    <div>
      <h1>My Blog</h1>
      <PostList posts={posts} />
      {/* 用Outlet渲染嵌套的PostDetails组件 */}
      <Outlet />
    </div>
  );
};

export default Blog;

二、Post跳转功能的代码问题及修复

问题1:useNavigate用法错误

react-router-dom v6中,useNavigate返回的是直接调用的函数,不需要.push()方法,且原跳转路径posts.json/${post.id}与路由配置不匹配,应该跳转到/blog/:postId。

问题2:PostDetails获取参数方式错误

v6中无法直接通过props获取postId,需要用useParams钩子获取URL参数,同时要处理文章加载的异步状态和不存在的情况。

修复代码:

修改Post.js:

import { useNavigate } from 'react-router-dom';

const Post = ({ post }) => {
  const navigate = useNavigate();

  const handleClick = () => {
    // 跳转到正确的路由路径
    navigate(`/blog/${post.id}`);
  };

  return (
    <div onClick={handleClick} style={{ cursor: 'pointer' }}>
      <h2>{post.title}</h2>
      <p>{post.summary}</p>
    </div>
  );
};

export default Post;

修改PostDetails.js:

import React, { useState, useEffect } from 'react';
import { useParams } from 'react-router-dom';

const PostDetails = () => {
  const { postId } = useParams(); // 用useParams获取URL参数
  const [post, setPost] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    fetch('/data/posts.json')
      .then(response => {
        if (!response.ok) throw new Error('无法获取文章数据');
        return response.json();
      })
      .then(data => {
        const foundPost = data.find(item => item.id === parseInt(postId));
        if (foundPost) {
          setPost(foundPost);
        } else {
          setError('文章不存在');
        }
        setLoading(false);
      })
      .catch(err => {
        setError(err.message);
        setLoading(false);
      });
  }, [postId]);

  if (loading) return <div>加载中...</div>;
  if (error) return <div>错误:{error}</div>;
  if (!post) return <div>未找到该文章</div>;

  return (
    <div>
      <h1>{post.title}</h1>
      <p>发布日期:{post.date}</p>
      <p>{post.body}</p>
    </div>
  );
};

export default PostDetails;

修改PostList.js:

移除无用的onPostClick参数,跳转逻辑已在Post组件内处理:

import React from 'react';
import Post from './Post';

const PostList = ({ posts }) => (
  <div>
    {posts.map(post => (
      <Post key={post.id} post={post} />
    ))}
  </div>
);

export default PostList;

内容的提问来源于stack exchange,提问作者Sren94

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 22:11:03