【问题标题】:How do I reload a page with react-router?如何使用 react-router 重新加载页面?
【发布时间】:2018-03-30 22:44:46
【问题描述】:

我可以在这个文件 (https://github.com/ReactTraining/react-router/blob/v0.13.3/modules/createRouter.js) 中看到有一个刷新功能,但我不知道如何调用它。我对 react-router 还很陌生,我只使用 hashHistory 在某些页面之间移动了几次。

现在我正在尝试使用它,以便在安装失败时为用户提供“重试”选项,我计划通过刷新安装发生的页面(用户当前所在的页面)来执行该选项)。任何帮助将不胜感激。

这是一个在电子上运行的节点应用程序,而不是网络应用程序。

【问题讨论】:

    标签: javascript reactjs react-router electron


    【解决方案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 (
                      ...
                    );
                  };
                  
                  

                  【讨论】:

                  • 请添加更多详细信息以扩展您的答案,例如工作代码或文档引用。
                  猜你喜欢
                  • 2020-07-04
                  • 2018-01-13
                  • 2018-10-21
                  • 2021-08-16
                  • 2022-07-31
                  • 2022-12-11
                  • 2017-02-27
                  • 1970-01-01
                  • 2018-05-16
                  相关资源
                  最近更新 更多