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

React点击事件中history.push传id后useParams返回undefined如何解决

核心问题排查及修复方案

问题1:路由配置与跳转逻辑不匹配

你在路由路径前加了#,而#是HashRouter的默认锚点标识,不属于路由路径的配置内容,会导致路由参数无法被正确解析。同时你使用history.push跳转时也加了#,和路由配置的规则冲突。

问题2:Post组件未通过路由渲染,无法获取路由上下文

你当前是在TrainingsWakeupRebirth组件内直接写死了<Post />组件,点击帖子仅切换两个区块的display属性,Post组件没有被Route组件包裹,自然无法通过useParams拿到路由参数。


推荐修复方案(成本最低,符合你现有切换显示的逻辑)

无需依赖路由传参,直接通过组件状态传递id即可,修改逻辑如下:

  1. 修改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>
            // 原有代码...
        )
    }
    
  2. 修改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("");
        // 剩余逻辑保持不变即可
    }
    

可选方案(需要路由传参的场景)

如果你确实需要用路由参数实现前进后退等功能,按以下步骤修改:

  1. 修改App路由配置,去掉路径前的#:
    <Route path='/forum' exact component={TrainingsWakeupRebirth} />
    <Route path='/forum/:id' exact component={Post} />
    
  2. 删掉TrainingsWakeupRebirth组件内的<Post />渲染代码,Post组件将由路由直接渲染
  3. 修改跳转逻辑,history.push路径去掉#:
    history.push(`/forum/${value.id}`)
    

额外优化建议

不要直接用document.getElementById获取DOM元素, React组件挂载前DOM还未生成,容易拿到null,建议改用useRef绑定元素。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.16 18:45:05