如何使用 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】:

如果你想使用&lt;Link/&gt;重新加载一些路由,或者只是单条历史推送,你可以在&lt;Switch/&gt;下设置&lt;Redirect/&gt;路由,如下:

<Switch>
    <Route exact path="/some-route" component=SomeRoute />
    <Redirect exact from="/some-route/reload" to="/some-route" />
</Switch>

然后是&lt;Link to="/some-route/reload" /&gt;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(); 
&lt;input type="button" onClick= reloadPage   value="reload"/&gt;

【讨论】:

【参考方案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-route 链接刷新页面

如何在不刷新页面的情况下在 ReactJS 中重新加载?

react-router:如何在不导致导航/重新加载的情况下更新 url?

(通用 React + redux + react-router)如何避免在初始浏览器加载时重新获取路由数据?

背景图像仅在重新加载页面后显示

在页面重新加载之前执行 http 请求