当前位置: 首页 > 知识库问答 >
问题:

无法使用react router 4以编程方式重定向

扈昀
2023-03-14

我已经阅读了很多关于这个主题的文档和软件问题,我用了很多方法来做这些,但是没有一个能以我需要的方式工作。我想我错过了一些重要的事情。很难就我使用的每个导航方法提供详细和相关的代码,我会试试。

这里有一些指间信息。我有react redux应用程序,我需要从服务器获取状态并根据此状态重定向到页面。

my App类渲染方法的简化版本:

 render() {
    console.log("App.render");
    console.log(this.state);
    return (

      <div id='game-container' width="1126" height="634">
        <Router>
        <div>
          <Route exact path="/" component={Page1}/>
          <Route path="/bets" component={Page2}/>
          <Route path="/games" component={Page3}/>
          <Route path="/newpage" component={Page4}/>
          <Route path="/info" component={ Info }/>
        </div>
        </Router>
        <Overlay/>
      </div>
    );
  }
} 

在index.js文件中用BrowserRouter包装的应用程序组件

ReactDOM.render(
  <Provider store={myStore}>
    <BrowserRouter>
      <App assets={ assets } locale={ qs['locale']} token={ qs['token']} sounds={ sounds } />
    </BrowserRouter>
  </Provider>
  , document.querySelector('.game-wrapper'));

方法1。带路由器

为了实现这一点,我添加了以下代码:

  App.propTypes = {
      history: React.PropTypes.shape({
      push: React.PropTypes.func.isRequired,
      }).isRequired,
      location: React.PropTypes.object.isRequired,
    };


function mapStateToProps(state) {
    console.log("app#mapStateToProps");
    console.log(state.session);
    return { session:  state.session }
}

function mapDispatchToProps(dispatch) {
    return bindActionCreators({ fetchInitialSession }, dispatch);
}

export default withRouter(connect(mapStateToProps, { fetchInitialSession })(App));

当我获取会话信息时,我会尝试:

 this.props.history.push("/newpage");

浏览器中的URL正在更改,但视觉页面没有更改。

方法2。使用上下文路由器

对于这个刚刚加了

App.contextTypes = {
  router: React.PropTypes.object
};

当我获取会话信息时,我会尝试:

 this.context.router.history.push("/newpage");

与第一个方法的结果相同(url已更改,但页面未更改)。

方法三。重定向(在这里找到使用响应路由器V4编程导航)

因此,我的渲染方法如下所示:

render() {
    console.log("App.render");
    console.log(this.state);
    return (

      <div id='game-container' width="1126" height="634">
        <Router>
        <div>
      <Redirect to={{ pathname: this.state.redirectTo }}/>
          <Route exact path="/" component={Page1}/>
          <Route path="/bets" component={Page2}/>
          <Route path="/games" component={Page3}/>
          <Route path="/newpage" component={Page4}/>
          <Route path="/info" component={ Info }/>
        </div>
        </Router>
        <Overlay/>
      </div>
    );
  }
} 

当我想更改页面时,我会设置新状态:

this.setState({ redirectTo: "/newpage" });

这种方法产生了奇怪的结果。当我在构造函数中设置初始状态时,它会重定向到任何页面。但当我在代码中的任何地方使用这个方法时,我在调试中看到用我的新状态调用的render方法,但重定向从未发生!

共有1个答案

闻人博
2023-03-14

在v4中,方法3应该是正确的方法(使用重定向组件)。您遇到的问题似乎是因为Redirect只在第一次挂载时生效,但您将Redirect放在路由器的顶层,它只挂载一次。

因此,如果渲染

this.setState({ redirectTo: "/newpage" });

这就是为什么只有当您在构造函数中设置了重定向到时,它才对您起作用,但此后不再重定向。

相反,您可能必须在您想要触发重定向的每个组件/路由中使用重定向,这并不像听起来那么乏味,因为您可以创建一个自定义路由组件来使用,而不是典型的路由在自定义组件中处理所有重定向逻辑。

您可以在这里找到一个示例,其中使用privaterroutePublicRoute而不是正常的Route来检查用户是否登录并相应重定向:https://github.com/tylermcginnis/react-router-firebase-auth/blob/master/src/components/index.js

以下是只有登录用户才能访问的私人路由:

function PrivateRoute ({component: Component, authed, ...rest}) {
  return (
    <Route
      {...rest}
      render={(props) => authed === true
        ? <Component {...props} />
        : <Redirect to={{pathname: '/login', state: {from: props.location}}} />}
    />
  )
}

 类似资料:
  • 问题内容: 我的目的是为Java Source File中的方法以编程方式调用Eclipse命令。重命名这样的方法还应该将更改应用于使用/引用此方法的所有实例。 我相信JDT具有Refactoring API,但无法找到相同的任何文档或教程。 有人能指出我正确的方向吗? 编辑:运行时不需要更改。 问题答案: 我认为您最有前途的方法是使用Eclipse源代码。 下载带有源代码的所需版本。特别是,您需

  • 使用 lavas init 创建的模板项目中,在以下场景下都会以编程方式使用 Lavas: server.dev.js 开发环境下的 SPA/SSR 模式。 server.prod.js 生产环境下的 SSR 模式。 可见以编程方式使用 Lavas 的主要场景就是 SSR 模式,而在 SPA 模式下仅仅是供开发服务器使用。因此,如果开发者选择了 SSR 模式,阅读下面的内容将十分有帮助: 如何选择

  • 问题内容: 我需要重新启动我的应用程序,以防万一我重新加载需要从一开始就开始的内容。我试过了 但我收到一个错误 启动路径不可访问 问题答案: 尽管问题本身是微不足道的(忘记了路径),但在其他人需要相同功能的情况下,我还是留下了疑问。 编辑 (Sw3的每日Swift语法更改; Sw4也适用):

  • 问题内容: 我将Wicket与Wicket Auth Project一起用于表示层,因此将其与Spring Security集成在一起。这是Wicket调用的身份验证方法: 我的Spring Security XML配置的内容(里面)是: 2.3.6节。参考文档的会话固定攻击防护说: 会话固定攻击是一种潜在的风险,恶意攻击者有可能通过访问站点来创建会话,然后诱使另一个用户以相同的会话登录(通过向他

  • 问题 你在写一段代码,最终需要创建一个新的类对象。你考虑将类的定义源代码以字符串的形式发布出去。 并且使用函数比如 exec() 来执行它,但是你想寻找一个更加优雅的解决方案。 解决方案 你可以使用函数 types.new_class() 来初始化新的类对象。 你需要做的只是提供类的名字、父类元组、关键字参数,以及一个用成员变量填充类字典的回调函数。例如: # stock.py # Example

  • null 我很感激任何建议/帮助。