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

React+Redux博客项目:按ID查询文章触发TypeError报错求助

问题解决:Cannot read properties of undefined (reading 'posts')

错误原因分析

你的错误出在Redux selector的两个核心问题上:

  1. 状态访问路径不一致:selectAllPosts等selector使用state.post访问切片状态,但selectPostById错误地用了state.posts,导致state.posts为undefined,读取posts属性时直接抛出错误。
  2. Selector缺少返回值:selectPostById函数没有返回查找结果,即便修复路径,最终也会返回undefined引发后续报错。

具体修复步骤

1. 统一状态访问路径

先确认你的Redux Store中post切片的注册键名,再统一所有selector的访问路径:

情况1:Store中切片键名为posts

如果你的Store配置是这样:

import { configureStore } from '@reduxjs/toolkit'
import postReducer from './post-slice'

export const store = configureStore({
  reducer: {
    posts: postReducer
  }
})

则修正post-slice.js中的所有selector:

// 修正全局状态访问路径
export const selectAllPosts = (state) => state.posts.posts;
export const getPostStatus = (state) => state.posts.status;
export const getPostError = (state) => state.posts.error;

// 修正单篇文章查询的selector,添加return
export const selectPostById = (state, postId) => {
  return state.posts.posts.find(post => post.id === postId)
}

情况2:Store中切片键名为post

如果你的Store配置是这样:

reducer: {
  post: postReducer
}

则统一使用state.post访问:

export const selectAllPosts = (state) => state.post.posts;
export const getPostStatus = (state) => state.post.status;
export const getPostError = (state) => state.post.error;

export const selectPostById = (state, postId) => {
  return state.post.posts.find(post => post.id === postId)
}

2. 简化Selector写法(可选)

用箭头函数隐式返回简化代码,避免遗漏return:

export const selectPostById = (state, postId) => 
  state.posts.posts.find(post => post.id === postId)

3. 额外优化:处理加载状态

在SinglePostPage组件中添加加载状态判断,避免数据未加载完成时的异常:

export default function SinglePostPage() {
  const {postId} = useParams();
  const post = useSelector((state) => selectPostById(state, Number(postId)))
  const postStatus = useSelector(getPostStatus);

  if(postStatus === 'loading') {
    return <section>加载中...</section>
  }

  if(!post){
    return <section>post not found</section>
  }

  return (
    <article>
        <h2>{post.title}</h2>
        <p>{post.body}</p>
        <p className=''>
            <PostAuthor userId={post.userId}/>
            <TimeAgo timestamp={post.date}/>
        </p>
        <ReactionButton post={post}/>
    </article>
  )
}

内容的提问来源于stack exchange,提问作者Aderoba Dayo Jerry

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 05:10:26