除非重新加载页面,否则 React 应用程序路由不会加载内容
Posted
技术标签:
【中文标题】除非重新加载页面,否则 React 应用程序路由不会加载内容【英文标题】:React app routing doesn't load content unless page reloaded 【发布时间】:2020-12-28 08:48:42 【问题描述】:我一直在开发一个 React 单页应用程序,并一直在尝试让路由正常工作。
我相信路由本身确实有效,但是除非手动重新加载页面,否则页面不会加载正确的内容。向后和向前浏览器箭头也可以使用。
例如,我可以很好地导航到localhost:3000
,并且内容已正确加载,但是当我按下按钮导航到localhost:3000/contacts
时,除非我刷新页面,否则不会显示任何内容。手动刷新后,会显示联系人页面。什么给了?
index.tsx
import React from 'react'
import ReactDOM from 'react-dom'
import BrowserRouter as Router from 'react-router-dom';
// Import App component
import App from './App'
// Import service workers
import * as serviceWorker from './serviceWorker'
// Render App component in the DOM
ReactDOM.render(
<Router>
<App />
</Router>
, document.getElementById('root')
)
serviceWorker.unregister()
App.tsx
// Import necessary dependencies
import React from 'react'
import Routes from './Routes'
// Create App component
function App()
return (
<div className="App">
<Routes />
</div>
)
export default App
history.tsx
import createBrowserHistory as history from 'history';
export default history();
Home/Home.tsx
import React, Component from "react";
import history from './../history';
import "./Home.css";
export default class Home extends Component
render()
return (
<div className="Home">
hello home
<button onClick=() => history.push('/Contact') value='click here'>Get Started</button>
</div>
);
联系人/Contact.tsx
import React, Component from 'react';
class Contact extends Component
render()
return (
<div>
hello world
</div>
);
export default Contact;
Routes.tsx
import React, Component from "react";
import BrowserRouter, Router, Switch, Route from "react-router-dom";
import Contact from "./Contact/Contact";
import Home from "./Home/Home"
import history from './history'
export default class Routes extends Component
render()
return (
<div>
<Router history=history>
<Switch>
<Route path="/" exact component=Home />
<Route path="/Contact" component=Contact />
</Switch>
</Router>
</div>
)
非常感谢任何帮助
【问题讨论】:
【参考方案1】:我认为有一些额外的代码可能会导致冲突。您从react-router-dom
定义了路由器两次:
曾经在这里,index.tsx
ReactDOM.render(
<Router> // here
<App />
</Router>
, document.getElementById('root')
)
然后又在Routes.tsx
<Router history=history> // here
<Switch>
<Route path="/" exact component=Home />
<Route path="/Contact" component=Contact />
</Switch>
</Router>
你必须放弃其中一个,它们可能相互冲突
更新
除此之外,我认为您不应直接从导出中使用 history
对象,而应通过 HOC withRouter
访问它。然后,你会包装
所以你会做这样的事情
import React, Component from "react";
import withRouter from 'react-router-dom'
import "./Home.css";
class Home extends Component
const history = this.props
render()
return (
<div className="Home">
hello home
<button onClick=() => history.push('/Contact') value='click here'>Get Started</button>
</div>
);
export default withRouter(Home)
【讨论】:
我在关注这个人的教程,我不是 100% 知道我哪里出错了。 github.com/minioncoder/ReactButtonExample/tree/master/… 除了使用 typescript 而不是简单的 javascript 所以我可以将history=history
部分移动到 index.tsx 文件中并删除 Routes.tsx 中的路由器标签,但我仍然得到相同的结果
是的,听起来不对,您只需要一个路由器。关于错误的其余部分,也许您应该从 HOC withRouter
检索历史记录,而不是导入您正在导出的那个。类似于this response,但现在history
将在您的道具中可用;作为this.history.props
我将 Home 类更改为函数并删除了 extends Component
位,因为这似乎是添加变量的唯一方法。我无法让const history = this.props
工作而不抛出';'预期的错误。 TL; DR 我让它工作了,但我一生都无法弄清楚为什么它现在可以工作。它一定是在快递server.js
文件中搞砸了。如果我弄清楚了,我会更新答案。【参考方案2】:
我认为这里的问题是你需要像这样用withRouter()
包装你的页面:
import React, Component from "react";
import history from './../history';
import "./Home.css";
import withRouter from 'react-router-dom'; //<---------- add this
class Home extends Component
render()
return (
<div className="Home">
hello home
<button onClick=() => history.push('/Contact') value='click here'>Get Started</button>
</div>
);
default export withRouter(Home); //<-------------- and add this
您也需要在 Contact
页面上执行相同操作。
【讨论】:
【参考方案3】:为什么你有两个路由器?
我猜你只需要在 index.tsx 或 Routes.tsx 中删除路由器
根据您的文件命名,我将删除 Routes.tsx 中的路由器
【讨论】:
【参考方案4】:您似乎正在使用history
包进行导航。如果您使用的是react-router v5
,那么您可能必须将history
包降级为4.10.1
,直到history
包开发人员发布带有修复程序的新版本。在撰写本文时,history
软件包的最新版本是v5.0.1
,如果您看到比这更新的版本,您可以先尝试使用该版本,看看它是否有效,然后再降级到4.10.1
问题链接->https://github.com/remix-run/history/issues/804
【讨论】:
以上是关于除非重新加载页面,否则 React 应用程序路由不会加载内容的主要内容,如果未能解决你的问题,请参考以下文章
除非刷新页面,否则React loadable无法在每个新构建上加载组件
除非使用 turbolinks 和 rails 4 重新加载页面,否则 javascript 不会执行