URL变更时如何更新single-spa中已注册应用的history历史位置
问题解决方案
根因说明
你创建的history是全局单例对象,single-spa切换应用卸载React应用时,该history实例不会被销毁,会一直保留上次访问的路径状态。其他应用修改浏览器地址栏时,单例history无法感知到外部的URL变化,因此切回React应用时仍然沿用旧的路径记录,导致路由匹配错误。
可行解决方案
方案1:每次React应用激活时同步URL状态(保留单例history)
在React应用的挂载生命周期中,主动读取当前浏览器的真实URL,同步到history实例中即可。
修改你的App.js代码,新增componentDidMount生命周期逻辑:
import React, {Component} from 'react'; import { Router, Switch, Route } from 'react-router-dom'; import history from '../history.js'; class App extends Component { constructor(props){ super(props); } componentDidMount() { // 去掉basename前缀,拿到react应用内的真实路径 const currentFullPath = window.location.pathname + window.location.search + window.location.hash; const appInnerPath = currentFullPath.replace(history.basename, '') || '/'; // 如果history记录的路径和当前真实路径不一致,替换为最新路径 if (history.location.pathname !== appInnerPath) { history.replace(appInnerPath); } } render(){ return ( <Router history={history}> <Switch> <Route exact path="/user" component={User} /> <Route exact path="/" component={Home} /> </Switch> </Router> ) } }
注意:你原代码中Router的闭合标签写为
<Router />属于语法错误,需要修正为</Router>。
方案2:每次挂载重建history实例(更推荐,避免单例状态污染)
放弃使用全局单例history,每次React应用实例化时创建新的history实例,新实例会自动读取当前浏览器的URL,从根源上避免旧状态残留。
第一步,修改history.js,导出创建history的函数而非直接导出实例:
import { createBrowserHistory } from 'history' export const createAppHistory = () => createBrowserHistory({ basename: '/myapp', forceRefresh: true })
第二步,修改App.js,每次组件实例化时创建新的history:
import React, {Component} from 'react'; import { Router, Switch, Route } from 'react-router-dom'; import { createAppHistory } from '../history.js'; class App extends Component { constructor(props){ super(props); // 每次新建实例自动同步当前浏览器URL this.history = createAppHistory(); } render(){ return ( <Router history={this.history}> <Switch> <Route exact path="/user" component={User} /> <Route exact path="/" component={Home} /> </Switch> </Router> ) } }
内容的提问来源于stack exchange,提问作者Athira Sreekumar
相关产品推荐
相关产品推荐

