如何使用 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 是如何作为函数参数注入的? @BacemrequireAuth
是作为 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 的重定向功能?的主要内容,如果未能解决你的问题,请参考以下文章