React中Redirect跳转后,mapStateToProps获取match.params.id失败问题
看起来你遇到的核心问题是路由参数没有正确传递到嵌套的Details组件,导致在mapStateToProps里拿不到id,进而无法从Redux Store中取出对应的数据。下面一步步给你拆解解决方案:
1. 先确认路由配置是否正确
首先要确保你的路由结构支持动态参数传递,尤其是Details作为Article的嵌套组件时:
如果用的是React Router v5:
父路由(Article)的配置应该是类似这样,并且要渲染子组件的占位:<Route path="/notes" component={Article}> <Route path="/notes/:id" component={Details} /> </Route>同时在Article组件里要渲染
{this.props.children},这样嵌套的Details组件才能接收到路由参数。如果用的是React Router v6:
父路由需要用<Outlet />来渲染子路由组件,路由配置类似:<Routes> <Route path="/notes" element={<Article />}> <Route path=":id" element={<Details />} /> </Route> </Routes>并且在Article组件中加入
<Outlet />,让子路由的Details组件能挂载并获取到params。
2. 确保Article组件传递路由参数给Details
如果你的Details是作为Article的子组件(不是通过路由嵌套,而是手动引入的),那Article必须主动把路由参数传递过去:
- React Router v5中,Article可以通过
this.props.match.params拿到id(如果父路由也包含:id的话),或者如果Article是父路由,Details是子路由,那只要正确渲染children就自动传递了; - React Router v6中,Article可以用
useParams()钩子获取id,然后作为props传给Details:// Article组件 import { useParams } from 'react-router-dom'; import Details from './Details'; const Article = () => { const { id } = useParams(); return <Details id={id} />; }
3. 修正mapStateToProps的参数获取逻辑
如果上面两步都没问题,但ownProps还是没有id,可以换一种方式获取路由参数:
方式一:用React Router的钩子直接在组件内获取(推荐函数组件)
在Details组件里直接用useParams拿到id,再从Redux Store中筛选数据:
import { useParams } from 'react-router-dom'; import { useSelector } from 'react-redux'; const Details = () => { const { id } = useParams(); // 从Redux Store中获取对应id的笔记/文章 const item = useSelector(state => state.notes.find(note => note.id === id) ); if (!item) return <div>加载中...</div>; return ( <div> <h1>{item.title}</h1> <p>{item.content}</p> </div> ); } export default Details;
方式二:用withRouter包裹组件(类组件适用)
如果是类组件,需要用withRouter把组件包裹起来,这样ownProps里就会包含match对象,从而拿到params:
import React from 'react'; import { connect } from 'react-redux'; import { withRouter } from 'react-router-dom'; class Details extends React.Component { render() { const { item } = this.props; if (!item) return <div>加载中...</div>; return ( <div> <h1>{item.title}</h1> <p>{item.content}</p> </div> ); } } const mapStateToProps = (state, ownProps) => { // 现在ownProps.match.params里就能拿到id了 const { id } = ownProps.match.params; return { item: state.notes.find(note => note.id === id) }; } // 一定要用withRouter包裹connect后的组件 export default withRouter(connect(mapStateToProps)(Details));
最后检查Redirect的跳转逻辑
确保你在Card组件里的Redirect路径是正确的动态路径,比如:
<Redirect to={`/notes/${note.id}`} />
这样跳转后的URL才会包含正确的id参数,路由才能识别并传递给Details组件。
内容的提问来源于stack exchange,提问作者plkpiotr

