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

react-router-dom第二次触发history.push返回undefined问题求解

问题根因
  • 路由配置错误:react-router-dom v5的Route组件path属性仅匹配URL的pathname部分,不会对查询参数(?后面的内容)做匹配校验,你定义的<Route path="/?datas=:datas" exact component={App} />是无效规则。两个路由实际都匹配/路径,当你第一次调用history.push更新查询参数时,会触发路由重新匹配,导致App组件被销毁后重新挂载。
  • Antd Modal挂载特性冲突:Antd Modal默认会将DOM结构挂载到document.body下,而非父组件的DOM树内。App第一次挂载时渲染的Modal,在App重新挂载后,旧的Modal DOM不会被自动销毁,其绑定的handleInput事件还是来自已经卸载的旧App组件实例,该实例的history属性已经随组件销毁被回收,第二次调用时自然就找不到push方法。
修复方案
  1. 修正路由配置,删除无效的带查询参数的路由规则,只保留基础路由即可,查询参数可直接在组件内通过location.search读取,不需要在Route的path中定义:
<Switch>
  <Route path="/" exact component={App} />
</Switch>
  1. 给Modal添加destroyOnClose属性,保证Modal关闭时会自动销毁对应的DOM和绑定的事件,避免残留旧实例的事件引用:
<Modal 
  visible={visible} 
  onOk={handleOk} 
  onCancel={handleCancel}
  destroyOnClose
>
  <MyForm onSubmit={handleOpenUrl}>
      <CustomInput
        name="input"
        onChange={(event: React.ChangeEvent<HTMLInputElement>) =>
          handleInput(event, "input")
        }
      />
      <Button type="submit" >
        Submit
      </Button>
  </MyForm>
</Modal>
  1. 优先使用react-router提供的API获取history实例,避免props丢失问题:
    如果是函数组件,使用useHistory Hook获取实例:
import { useHistory } from 'react-router-dom';

// 组件内部调用
const history = useHistory();

const handleInput = (event: React.SyntheticEvent) => {
  event.preventDefault();
  // other operation where checked is handled...
  history.push({
    pathname: "/",
    search: "?" + new URLSearchParams({ datas: checked }).toString(),
  });
};

如果是类组件,用withRouter高阶组件包裹App组件,确保props里的history始终是最新的有效实例。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 03:39:02