页面加载且需查询参数的函数执行后,如何移除URL中的查询参数
问题根因
你使用的是哈希路由模式,查询参数拼接在hash片段之后。首次从页面A跳转到页面B时,React路由(如react-router)的初始路由校验、渲染逻辑还未完全执行完成,此时你调用pushState修改hash后,路由后续的初始化逻辑会将hash还原为跳转时的初始值,所以首次跳转后URL没有变化。而刷新页面时,路由初始化直接读取当前浏览器URL的hash值,你修改hash后路由不会再触发重置操作,因此修改可以生效。
解决方案
原生history实现(不依赖路由API)
修改代码如下,解决URL不更新问题同时优化逻辑:
componentDidMount() { const hashFragment = window.location.hash; const [hashPath, queryStr] = hashFragment.split('?'); const qParams = new URLSearchParams(queryStr || ''); if (qParams.has('id')) { this.initiateCall(new DiallerRoomUser( DiallerRoomUserType.matrix, getLocalUserIdFromUserId(qParams.get('id')), )); qParams.delete('id'); // 保留其余查询参数 const newQuery = qParams.toString() ? `?${qParams.toString()}` : ''; const newHash = `${hashPath}${newQuery}`; const url = new URL(window.location); url.hash = newHash; // 延迟执行修改,等路由初始化逻辑完成后再更新URL setTimeout(() => { // 用replaceState避免新增多余历史记录,防止用户点后退再次触发呼叫 window.history.replaceState({}, document.title, url); }, 0); } }
基于React Router API实现(更稳定)
如果项目使用React Router,直接调用路由提供的replace方法,不需要额外延迟即可生效:
React Router v5 写法
componentDidMount() { const { history, location } = this.props; const qParams = new URLSearchParams(location.search); if (qParams.has('id')) { this.initiateCall(new DiallerRoomUser( DiallerRoomUserType.matrix, getLocalUserIdFromUserId(qParams.get('id')), )); qParams.delete('id'); history.replace({ pathname: location.pathname, search: qParams.toString() }) } }
React Router v6 类组件适配写法
import { withRouter } from 'react-router-dom'; class CallPage extends React.Component { componentDidMount() { const { navigate, location } = this.props; const qParams = new URLSearchParams(location.search); if (qParams.has('id')) { this.initiateCall(new DiallerRoomUser( DiallerRoomUserType.matrix, getLocalUserIdFromUserId(qParams.get('id')), )); qParams.delete('id'); navigate(`${location.pathname}?${qParams.toString()}`, { replace: true }); } } } // 用withRouter包裹组件注入路由属性 export default withRouter(CallPage);
内容的提问来源于stack exchange,提问作者Onyx
相关产品推荐
相关产品推荐

