如何使用 react-router 重新加载页面?
Posted
技术标签:
【中文标题】如何使用 react-router 重新加载页面?【英文标题】:How do I reload a page with react-router? 【发布时间】:2018-03-30 22:44:46 【问题描述】:我可以在这个文件 (https://github.com/ReactTraining/react-router/blob/v0.13.3/modules/createRouter.js) 中看到有一个刷新功能,但我不知道如何调用它。我对 react-router 还很陌生,我只使用 hashHistory 在某些页面之间移动了几次。
现在我正在尝试使用它,以便在安装失败时为用户提供“重试”选项,我计划通过刷新安装发生的页面(用户当前所在的页面)来执行该选项)。任何帮助将不胜感激。
这是一个在电子上运行的节点应用程序,而不是网络应用程序。
【问题讨论】:
【参考方案1】:首先,添加 react-router 作为依赖
`yarn add react-router` or `npm install react-router`
import useHistory from 'react-router'
const history = useHistory()
/////then add this to the function that is called for re-rendering
history.go(0)
这会导致您的页面自动重新呈现
【讨论】:
如果您在处理身份验证状态的 onClick 事件中删除了 cookie,则此方法有效,history.go()
我按预期注销并推送到登录屏幕。其他答案对我来说没有按预期工作..
不是真正的 SPA 方法。我认为这个建议应该受到批评
我正在使用 React 和 Express.js 构建一个 Web 应用程序,这个建议对我来说就像一个魅力。干杯【参考方案2】:
您可以使用它来刷新当前路线:
import createHistory from 'history/createBrowserHistory'
const history = createHistory();
history.go(0)
【讨论】:
这会导致整个页面重新加载 如果你使用钩子,类似的东西 - 这适用于 react-router-dom 中的 useHistory。但是,是的,完全重新加载页面【参考方案3】:您实际上并不需要 react-router
。你可以使用location.reload
:
location.reload();
您链接到的那个 react-router 版本也很旧,我认为它当前在 v4 上时正在链接到 v1。
【讨论】:
嗯是有道理的。问题是当它调用location.reload()
时,它会在我的浏览器上打开文件,但我正在开发一个电子应用程序,因此它需要在应用程序中重新加载。
不是真正的 SPA 方法。我认为这个建议应该受到批评
此处的其他答案,例如 history.pushState(null, '/');更好,恕我直言
与使用路由器方法相比,使用此方法会丢失任何缓存数据(例如 Apollo)。
@SashaKos 有时应该采用这种方法,例如当我们部署新版本的 SPA 应用程序并且我们希望维护模式离线组件(我们向用户展示) 导致整页刷新并获取新版本的 SPA 应用程序(一旦我们将维护模式设置为关闭)。请注意,为了使用此代码解决 no-restricted-globals
错误(例如,使用 Create React App 时),它应为 window.location.reload()
。【参考方案4】:
我猜你正在使用 react-router。 我将从另一篇文章中复制我的答案。 所以你几乎没有可能这样做,目前我最喜欢的方法是在组件属性中使用匿名函数:
<Switch>
<Route exact path="/" component=()=><HomeContainer/> />
<Route exact path="/file/:itemPath/:refHash" component=()=><File/> />
<Route exact path="/:folderName" component =()=><Folder/>/>
</Switch>
或者,如果您想使用当前的 url 参数进行刷新,您将需要额外的路由(重新加载),并使用路由器堆栈进行一些操作:
reload = ()=>
const current = props.location.pathname;
this.props.history.replace(`/reload`);
setTimeout(() =>
this.props.history.replace(current);
);
<Switch>
<Route path="/reload" component=null key="reload" />
<Route exact path="/" component=HomeContainer />
<Route exact path="/file/:itemPath/:refHash" component=File />
<Route exact path="/:folderName" component =Folder/>
</Switch>
<div onClick=this.reload>Reload</div>
【讨论】:
这里为什么需要setTimeout
?
@DawsonB 我不知道,但没有它就不行。哈哈【参考方案5】:
反应
window.location.reload();
工作
【讨论】:
这可以变成无限循环,小心【参考方案6】:如果你想使用<Link/>
重新加载一些路由,或者只是单条历史推送,你可以在<Switch/>
下设置<Redirect/>
路由,如下:
<Switch>
<Route exact path="/some-route" component=SomeRoute />
<Redirect exact from="/some-route/reload" to="/some-route" />
</Switch>
然后是<Link to="/some-route/reload" />
或push("/some-route/reload")
【讨论】:
有趣的方法,非常适合我的用例。谢谢!【参考方案7】:此解决方案不会导致不需要的整页重新加载,但需要您对需要刷新的每个页面进行此修改:
export const Page = () =>
const location = useLocation();
return <PageImpl key=location.key />
所以想法是:在页面周围创建一个包装器,并让 React 在每次位置键更改时重新创建实际页面。
现在只需再次调用history.push(/this-page-route)
即可刷新页面。
【讨论】:
感谢您注意到 histry.push(..) 触发刷新【参考方案8】:您可以尝试this 解决方法:
// I just wanted to reload a /messages page
history.pushState(null, '/');
history.pushState(null, '/messages');
【讨论】:
由于某种原因,这仍然会在我的浏览器中打开文件,但如果我删除第二行并只是推送到第一页,它会将我带到那里。为了澄清,我使用hashHistory.push('/somewhere')
【参考方案9】:
如果您不想再次重新加载所有脚本,您可以将当前路径替换为假/空路径,然后再次将其替换为当前路径,如下所示
// ...
let currentPath = window.location.pathname;
history.replace('/your-empty-route');
setTimeout(() =>
history.replace(currentPath)
, 0)
// ...
更新:
如果地址栏的变化很麻烦,你可以像这样添加一个带图案的路由:
<Route path="/*/reload" component=null/>
并将/replace
添加到currentPath
的末尾以将路由器替换为空组件。像这样:
// ...
let currentPath = window.location.pathname;
history.replace(`$currentPath/replace`);
setTimeout(() =>
history.replace(currentPath)
, 0)
// ...
这样,reload
关键字将添加到您当前路径的末尾,我认为它对用户更友好。
注意:如果你已经有一个以replace结尾的路由会引起冲突。为了解决这个问题,您应该将模式化路线的路径更改为其他内容。
【讨论】:
【参考方案10】:可能你正试图推入历史对象,然后用withrouter
绑定你的组件或使用window.location.href = url
重定向..
【讨论】:
【参考方案11】:你可以使用这个功能。
function reloadPage()
window.location.reload();
<input type="button" onClick= reloadPage value="reload"/>
【讨论】:
【参考方案12】:我知道这是旧的,但我根据react-router的文档找到了一个简单的解决方案。
只需将该属性放在您的路由器上,每当您在新路径上时,它都会强制页面重新加载自身。
<Router forceRefresh=true>
来源: https://reactrouter.com/web/api/BrowserRouter/forcerefresh-bool
【讨论】:
【参考方案13】:更新 webpacker.yml
devServer:
historyApiFallback: true,
【讨论】:
请添加解释以提高洞察力并为 OP 提供更多信息【参考方案14】:嗯,最简单的方法是首先确定要重新加载的路由,然后在该路由上调用window.location.reload()
函数,如下所示:
<Switch>
<Route exact exact path="/" component=SomeComponent />
<Route path="/reload" render= (props)=>window.location.reload() />
</Switch>
【讨论】:
【参考方案15】:我最近遇到了同样的问题并创建了这个(https://github.com/skt-t1-byungi/react-router-refreshable)。
<Refreshable>
<Switch>
<Route path="/home">
<HomePage />
</Route>
<Route path="/post">
<PostPage />
</Route>
/* ... */
</Switch>
</Refreshable>
【讨论】:
【参考方案16】:如果您想重新获取数据,只需执行以下操作:
import useLocation from 'react-router'
const location = useLocation()
useEffect(() =>
fetchData()
, [location.key])
【讨论】:
【参考方案17】:如果您需要异步重新加载,请使用history.go(0)
(它包装了History.go() 方法)。
如果您需要同步重新加载页面,请使用history.push(location.pathname)
(它包装了History.pushState()方法)。
由于这里已经有使用history.go(0)
的示例,所以这里有一个使用history.push(location.pathname)
的示例:
import React from 'react';
import useHistory, useLocation from 'react-router-dom';
const Component = () =>
const history = useHistory();
const location = useLocation();
const reload = () =>
history.push(location.pathname);
;
return (
...
);
;
【讨论】:
请添加更多详细信息以扩展您的答案,例如工作代码或文档引用。以上是关于如何使用 react-router 重新加载页面?的主要内容,如果未能解决你的问题,请参考以下文章
react-router:如何在不导致导航/重新加载的情况下更新 url?