React点击事件中history.push传id后useParams返回undefined如何解决
核心问题排查及修复方案
问题1:路由配置与跳转逻辑不匹配
你在路由路径前加了#,而#是HashRouter的默认锚点标识,不属于路由路径的配置内容,会导致路由参数无法被正确解析。同时你使用history.push跳转时也加了#,和路由配置的规则冲突。
问题2:Post组件未通过路由渲染,无法获取路由上下文
你当前是在TrainingsWakeupRebirth组件内直接写死了<Post />组件,点击帖子仅切换两个区块的display属性,Post组件没有被Route组件包裹,自然无法通过useParams拿到路由参数。
推荐修复方案(成本最低,符合你现有切换显示的逻辑)
无需依赖路由传参,直接通过组件状态传递id即可,修改逻辑如下:
- 修改
TrainingsWakeupRebirth组件:- 新增选中帖子id的状态
- 点击帖子时直接把id存入状态,不需要调用
history.push - 把id通过props传给Post组件
代码修改参考:
const TrainingsWakeupRebirth = (props) => { // 新增状态存选中的帖子id const [selectedPostId, setSelectedPostId] = useState(null); // 原有代码... const displayPosts = listOfPosts.slice(pagesVisited, pagesVisited + postsPerPage).map((value, key) => { const executeAll = () => { // 直接存id,不需要history.push setSelectedPostId(value.id); showPost(); } return ( <div key={key}> <div className="topic-row" onClick={() => {executeAll()}}> <div className="topic-title">{value.title}</div> <div className="topic-image"> <img src={value.image} alt=""></img> </div> <div className="topic-message">{value.postText}</div> </div> </div> ); }); // 渲染Post时传id return ( // 原有代码... <div className="post-section" id="post-section"> <div className="fluid-grid"> <div className="row"> <div className="col-12"> <Post id={selectedPostId} /> </div> </div> </div> </div> // 原有代码... ) } - 修改Post组件,直接从props取id,不需要用
useParams:const Post = (props) => { // 去掉useParams,从props拿id const id = props.id; const [postObject, setPostObject] = useState({}); const [comments, setComments] = useState([]); const [newComment, setNewComment] = useState(""); // 剩余逻辑保持不变即可 }
可选方案(需要路由传参的场景)
如果你确实需要用路由参数实现前进后退等功能,按以下步骤修改:
- 修改App路由配置,去掉路径前的
#:<Route path='/forum' exact component={TrainingsWakeupRebirth} /> <Route path='/forum/:id' exact component={Post} /> - 删掉
TrainingsWakeupRebirth组件内的<Post />渲染代码,Post组件将由路由直接渲染 - 修改跳转逻辑,
history.push路径去掉#:history.push(`/forum/${value.id}`)
额外优化建议
不要直接用document.getElementById获取DOM元素, React组件挂载前DOM还未生成,容易拿到null,建议改用useRef绑定元素。
内容的提问来源于stack exchange,提问作者ana_m
相关产品推荐
相关产品推荐

