我有非 SPA 服务器端应用程序和仅限于当前页面的 React 应用程序, /some/static/page
。 该应用程序在所有页面上都有 <base href="/">
in <head>
并依赖它,无法更改。
这是 React 16、React Router 4 和 <HashRouter>
的基本示例:
export class App extends React.Component {
render() {
return (
<HashRouter>
<div>
<Route exact path="/" component={Root} />
</div>
</HashRouter>
);
}
}
出于测试目的,可以禁用所有路由,但这不会改变行为。
这是显示问题的 create-react-app
项目。复制它的步骤是:
npm i
npm start
- 导航到
http://localhost:3000/some/static/page
HashRouter 显然受 <base>
影响。 It redirects from /some/static/page
to /#/
on initialization, while I expect it to be /some/static/page#/
or /some/static/page/#/
(works as intended only in IE 11 ).
Root
组件在重定向到 /#/
之前快速启动。
It redirects to /foo/#/
in case of <base href="/foo">
, and it redirects to /some/static/page/#/
when <base>
tag is removed.
该问题影响 Chrome 和 Firefox(最新版本),但不影响 Internet Explorer (IE 11)。
为什么 <HashRouter>
受 <base>
影响?它在这里使用正是因为它不应该影响位置路径,只会影响哈希。
这怎么能解决?
原文由 Estus Flask 发布,翻译遵循 CC BY-SA 4.0 许可协议
实际上这来自
history
。如果您看到 他们的代码,他们只使用createHashHistory
并设置children
。所以它等同于:它将显示您遇到的相同问题。然后,如果您更改
history
代码如下:那么你的问题就会消失但绝对不能使用
hash
。所以问题不是来自HashRouter
而是来自history
。因为这来自
history
,让我们看看这个 线程。阅读该线程后,我们可以得出结论,这是来自history
的 特征。so, if you set
<base href="/">
, because you are usinghash
(#), when browser loaded ( actually aftercomponentDidMount
) it will appendhash
(#) in your casesome/static/page
=>some/static/page
+/
=>/
+#/
= >/#/
。您可以签入componentDidMount
设置debugger
在附加路由之前捕获。解决方案
简单地说,只需删除元素
<base href>
或不使用HashRouter
。如果仍然需要但想避免特定的
component
,只需将其放在class
之前:更新
因为你想保留
base
标签以保持持久链接并使用hash
路由器,这里是我认为的关闭解决方案。1. 将标签
base
设置为空。将该代码放在
App
组件(根包装组件)中调用一次。2.当
componentDidMount
设置回来使用超时等待反应完成渲染虚拟 dom。
我认为这非常接近(已测试)。因为您使用的是
hash
路由器,来自索引 html 的链接将是安全的(不会被反应覆盖,但保留base
标签)。它也适用于 css 链接<link rel="stylesheet" href="styles.css">
。