如何使用 React Router 的重定向功能?

Posted

技术标签:

【中文标题】如何使用 React Router 的重定向功能?【英文标题】:How to use React Router's redirect function? 【发布时间】:2016-02-21 00:36:21 【问题描述】:

我想通过以下方式配置 React Router。如果某个路由匹配,则用户将被重定向到另一个路由。 Documentation 表示这是可能的,但没有提供实现这一目标的确切方法。有人对此有见解吗?

type EnterHook = (nextState: RouterState, replaceState: RedirectFunction, callback?: Function) => any;

type RedirectFunction = (state: ?LocationState, pathname: Pathname | Path, query: ?Query) => void;

【问题讨论】:

【参考方案1】:

编辑 查看其他答案以了解新的、未弃用的 react-router 语法


有一个很好的例子来说明如何在auth-flow example 中使用onEnter 钩子。以下是相关代码:

function requireAuth(nextState, replaceState) 
  if (!auth.loggedIn())
    replaceState( nextPathname: nextState.location.pathname , '/login')


render((
  <Router history=history>
    <Route path="/" component=App>
      <Route path="login" component=Login />
      <Route path="logout" component=Logout />
      <Route path="about" component=About />
      <Route path="dashboard" component=Dashboard onEnter=requireAuth />
    </Route>
  </Router>
), document.getElementById('example'))

如您所见,当访问/dashboard 路由时,会调用requireAuth 函数。它接收两个参数:nextState,它是一个 RouterState 对象,表示用户将要进入的状态,replaceState,一个 RedirectFunction,可以调用它来用其他东西替换那个状态。在这种情况下,如果用户没有登录,requireAuth 会像这样调用replaceState

replaceState( nextPathname: nextState.location.pathname , '/login')

第二个参数显然是用户将被重定向到的路径名。第一个参数是一个对象,它可以包含我们希望路由处理程序(在本例中为Login 组件)拥有的任何数据。在这里,用户尝试访问的路径名 (/dashboard) 设置为 nextPathname 属性,因此登录后用户可以重定向到该页面(参见 Login 组件中的 handleSubmit 方法)。

如果用户已登录,requireAuth 什么都不做,因为 replaceState 从未被调用,所以路由照常工作,也就是说 Dashboard 组件被渲染。

【讨论】:

感谢您的详尽回答! 我正在使用通用渲染,不幸的是这种方法会导致 302 重定向。如果有服务器请求,有什么方法可以使用 301 重定向? 谁能告诉我 nextState 和 replaceState 是如何作为函数参数注入的? @Bacem requireAuth 是作为 onEnter 属性传递给 Route 组件的普通函数。 Route 调用函数就像你在一个 React 组件中调用任何事件处理程序一样,例如this.props.onEnter(nextState, replaceState)。 (另请注意,如果您正在寻找有关 当前 版本的 react-router 的信息,则此答案非常陈旧。) 似乎不推荐使用 onEnter 方法。请让我知道替代方案。【参考方案2】:

请注意从 react-router 2.0.0 开始阅读此问题的任何人,replaceState(state, pathname, query) 现在已弃用。您现在必须使用带有位置描述符的 replace(location)。

https://github.com/reactjs/react-router/blob/master/upgrade-guides/v2.0.0.md#link-to-onenter-and-isactive-use-location-descriptors

来自他们的指南:

// v1.0.x
(nextState, replaceState) => replaceState(null, '/foo')
(nextState, replaceState) => replaceState(null, '/foo',  the: 'query' )

// v2.0.0
(nextState, replace) => replace('/foo')
(nextState, replace) => replace( pathname: '/foo', query:  the: 'query'  )

【讨论】:

嗨。当我们使用替换功能时,它不会在重定向时保留存储状态。我怎样才能做到这一点?我的意思是,如何在下一条路线中传递存储状态(以及动作调度程序) 嗨@user3241111 我在下面添加了一个答案,希望有助于澄清。【参考方案3】:

以下是如何使用react-router 2.0.0 执行此操作的示例(使用replace 而不是replaceState):

router.jsx 中:

function requireAuth(nextState, replace) 
  if (!userExists()) 
    replace(
      pathname: '/signin',
      state:  nextPathname: nextState.location.pathname 
    )
  


export const renderRoutes = () => (
  <Router history=browserHistory>
      <Route path="protectedRoute" component=Protected onEnter=requireAuth />
      <Route path="signin" component=SignIn />
    </Route>
  </Router>
);

然后,在SignIn 组件中,您可以像这样在成功登录后重定向:

import  browserHistory  from 'react-router';

signInFunction(params, (err, res) => 
  // Now in the sign in callback
  if (err)
    alert("Please try again")
  else 
    const location = this.props.location
    if (location.state && location.state.nextPathname) 
      browserHistory.push(location.state.nextPathname)
     else 
      browserHistory.push('/')
    
  
)

【讨论】:

感谢您的回答。与您上面的示例和我的场景有两点不同。第一个是我的身份验证是基于 TOKEN 的,而不是将他重定向到登录表单,该表单是同一应用程序中的路由(在我的情况下不是)。第二种情况..在您进行替换的那一刻(路径名:'/signin'....)我已经知道我的用户是否已登录,条件“if(userExists())”始终为真,因为他是肯定已登录.. 我只想替换到“/ notFound”页面,但加载此路由时应用程序状态会丢失。我想保护某些组件免受登录用户的影响。 我的应用程序是同构的,所以问题来了。我将我的 TOKEN 发送到其他 url 以及“return url”,它验证了 TOKEN 并将重定向发送回“return url”。因此,如果我执行“cb()”,它会重定向到受保护的 URL 并保留我的 UserDetails,但如果我使用“replace('/notFound')”,那么它会忘记状态.. 在我必须 cb 的情况下() 或 replace(..),服务器状态已经有 userDetails 我想传递给'notFound'路由。

以上是关于如何使用 React Router 的重定向功能?的主要内容,如果未能解决你的问题,请参考以下文章

React redirect - react-router-dom 上的重定向组件

如何使用 react-router 重定向到另一条路由?

vue-router 的重定向-redirect

vue-router 的重定向-redirect

在React中处理用户验证的重定向?

如何从 express 重定向到 react-router?