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

React与react-router动态路由无法渲染组件问题求助

React Router 详情页跳转空白及报错问题

使用React与react-router时,从Blogs页面跳转至路由<Route path="/blogs/:id" element={<Blog/>} />后,Blog页面完全空白,控制台出现大量错误。

相关代码

App.jsx

import Footer from "./components/Footer"
import Navbar from "./components/Navbar"
import Blogs from "./pages/Blogs"
import Cart from "./pages/Cart"
import Home from "./pages/Home"
import Shop from "./pages/Shop"
import { Routes, Route } from 'react-router-dom'
import './App.css'
import Blog from "./pages/Blog"

const App = () => {
  return (
    <>
      <Navbar />
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/shop" element={<Shop />} />
        <Route path="/cart" element={<Cart />} />
        <Route path="/blogs" element={<Blogs />} />
        <Route path="/blogs/:id" element={<Blog/>} />
      </Routes>
      <Footer />
    </>
  )
}

export default App

Blogs.jsx

import { Link } from "react-router-dom"
import PageTitle from "../components/PageTitle"
import Data from '../data/Data.json'

const Blogs = () => {
  return (
    <section>
      <PageTitle title={'Blogs'} />

      <div className="container my-5">
        <div className="row">
          {Data.blogs.map((blog, i) => {
            const { id, title, author, image, publishedDate, views } = blog
            const truncatedTitle = title.length > 60 ? title.substring(0, 60) + '...' : title;
            return (
              <Link to={`/blogs/${id}`} key={i} className="col-12 col-sm-6 col-md-4 my-3" style={{ textDecoration: 'none' }}>
                <div>
                  <div className="post-entry">
                    <div className="post-thumbnail">
                      <img src={image} alt="Image" className="img-fluid" />
                    </div>
                    <div className="post-content-entry">
                      <h6 className="my-2">{truncatedTitle}</h6>
                      <div className="meta">
                        <div>by {author}</div>
                        <div>on {publishedDate}</div>
                        <div><i className="fa-solid fa-eye ms-5"></i> {views}</div>
                      </div>
                    </div>
                  </div>
                </div>
              </Link>
            )
          })}
        </div>
      </div>
    </section>
  )
}

export default Blogs

Blog.jsx(原出错代码)

import { useEffect, useState } from "react"
import { useParams } from "react-router-dom"
import Data from '../data/Data.json'

const Blog = () => {
  const { id } = useParams()
  const [blog, setBlog] = useState(null);
  const { title, author, image, content, publishedDate, views } = blog
  
  useEffect(() => {
    const singleBlog = Data.blogs.find(item => item.id === parseInt(id))

    if (singleBlog) {
      setBlog(singleBlog)
    }
  }, []);
  
  return (
    <section>
      <div className="container pt-5">
        {blog ? (
          <div className="blog">
            <img src={image} height={'300px'}/>
            <h2>{title}</h2>
            <div>
              <span>by {author}</span>
              <span className="mx-5">on {publishedDate}</span>
              <span><i className="fa-solid fa-eye ms-5"></i> {views}</span>
            </div>
            <p>{content}</p>
          </div>
        ) : 'not found blog'}
      </div>
    </section>
  )
}

export default Blog

错误原因分析

  1. 顶层解构空值报错:组件初始化时blog为null,直接执行const { title, ... } = blog会抛出Cannot destructure property 'title' of 'null'错误,导致组件渲染失败,页面空白。
  2. useEffect依赖缺失:依赖数组为空,当路由参数id变化时(如从/blogs/1跳转到/blogs/2),不会重新执行博客查找逻辑,数据无法更新。

修复方案

修改Blog.jsx如下:

import { useEffect, useState } from "react"
import { useParams } from "react-router-dom"
import Data from '../data/Data.json'

const Blog = () => {
  const { id } = useParams()
  const [blog, setBlog] = useState(null);
  
  useEffect(() => {
    // 根据id类型调整比较逻辑,若Data中id为字符串则去掉parseInt
    const singleBlog = Data.blogs.find(item => item.id === parseInt(id))
    setBlog(singleBlog)
  }, [id]); // 添加id到依赖,参数变化时重新查询
  
  return (
    <section>
      <div className="container pt-5">
        {blog ? (
          <div className="blog">
            <img src={blog.image} height={'300px'}/>
            <h2>{blog.title}</h2>
            <div>
              <span>by {blog.author}</span>
              <span className="mx-5">on {blog.publishedDate}</span>
              <span><i className="fa-solid fa-eye ms-5"></i> {blog.views}</span>
            </div>
            <p>{blog.content}</p>
          </div>
        ) : <div>未找到该博客</div>}
      </div>
    </section>
  )
}

export default Blog

修复要点

  • 移除顶层的blog解构,改为在条件渲染内部直接通过blog.xxx访问属性,避免空值解构错误。
  • 将id添加到useEffect的依赖数组,确保路由参数变化时重新获取对应博客数据。
  • 可选:检查Data中id的类型,若为字符串则无需parseInt(id),直接使用item.id === id比较,避免类型转换问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 01:52:05