React+Redux博客项目:按ID查询文章触发TypeError报错求助
问题解决:Cannot read properties of undefined (reading 'posts')
错误原因分析
你的错误出在Redux selector的两个核心问题上:
- 状态访问路径不一致:
selectAllPosts等selector使用state.post访问切片状态,但selectPostById错误地用了state.posts,导致state.posts为undefined,读取posts属性时直接抛出错误。 - 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
相关产品推荐
相关产品推荐

