Как использовать функцию перенаправления React Router?
Я хочу настроить React Router следующим образом. Если определенный маршрут согласован, пользователь перенаправляется на другой. Документация утверждает, что это возможно, но не дает точного способа достижения этого. Кто-нибудь знает об этом?
type EnterHook = (nextState: RouterState, replaceState: RedirectFunction, callback?: Function) => any;
type RedirectFunction = (state: ?LocationState, pathname: Pathname | Path, query: ?Query) => void;
Ответы
Ответ 1
EDIT См. другой ответ для нового, не устаревшего синтаксиса реактивного маршрутизатора
Хороший пример использования крюка 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
, поэтому после входа в систему пользователь может быть перенаправлен на эту страницу (см. Метод handleSubmit
в компоненте Login
).
Если пользователь вошел в систему, requireAuth
ничего не делает, а так как replaceState
никогда не называется, маршрут работает как обычно, то есть компонент Dashboard
отображается.
Ответ 2
Направляет кого-либо, кто читает этот вопрос, как на response-router 2.0.0, replaceState (state, pathname, query) теперь устарел. Теперь вы должны вместо этого заменить (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' } })
Ответ 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('/')
}
}
})