请您帮助我理解我可以使用最新版反应路由器(v1.1.0)的重定向机制。我想重定向到let history = createBrowserHistory();
,具体取决于用户登录的成功与否。
我试图做以下事情
首先使用。
history.pushState(null, 'abc')
然后尝试使用
推送状态transitionTo()
什么都没发生。你可以告诉我正确的转换方式。从我理解的文档中,Log.getStackTraceString(exception)
API在最新版本中不存在。
如果您能指出一个简单的工作示例,那将会很棒。
提前致谢。
答案 0 :(得分:24)
想要更新这个帖子,因为我花了很多时间在这上面挖掘。在React Router 2.0.x中,不推荐使用replaceState
以支持replace。有关详细信息,请参阅此处:https://github.com/ReactTraining/react-router/blob/v2.0.0/upgrade-guides/v2.0.0.md#link-to-onenter-and-isactive-use-location-descriptors
这样做的正确方法是这样的:
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组件中,您可以在成功登录后重定向:
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('/')
}
}
})
答案 1 :(得分:17)
您可以注册&#34;挂钩&#34;在您进入和离开路线时触发的路线上。查看onEnter and onLeave hooks的文档。
路由上还有example of requiring auth,如果用户未登录,则会重定向到其他路径。
以下是app.js中来自require auth示例的摘录:
function requireAuth(nextState, replaceState) {
if (!auth.loggedIn())
replaceState({ nextPathname: nextState.location.pathname }, '/login')
}
// And from the route configuration, use the requireAuth function in onEnter...
<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>
nextState
和replaceState
参数是来自rackt/history的对象,并被注入到传入onEnter的方法中。
答案 2 :(得分:9)
@terranmoccasin的回答是正确的。然而,通常需要很少的例子来解决。
我们假设您需要保护多条路线(仪表板1,仪表板2,......)。成功登录后,如何重定向回原始页面?换句话说,你如何处理{nextPathname: nextState.location.pathname}
?
这是我在./containers/LoginContainer.js
中所做的事情:
import { push } from 'react-router-redux';
const mapStateToProps = (state) => ({
nextPathname: state.routing.locationBeforeTransitions.state.nextPathname,
});
const mapDispatchToProps = (dispatch) => ({
changeLocationOnSignIn: (nextPathname) => {
dispatch(push(nextPathname));
},
});
并在./components/Login.js
componentWillReceiveProps(nextProps) {
// user signed in or signed up, assuming redux. you may use this elsewhere.
if (nextProps.user.status === 'authenticated' && nextProps.user.user &&
!nextProps.user.error) {
this.props.changeLocationOnSignIn(this.props.nextPathname);
}
React-router 2。4。0(2016年4月)与萝卜一起推出,创建了一个HOC。但是它包装了React.createClass,而不是JS类。我还没有能够使用redux-form等工作。此外我认为上面的代码更容易理解。
答案 3 :(得分:3)
React Router v4.2
我正在使用 React-16.2 &amp; React-router-4.2
我得到了解决方案
this.props.history.push("/");
我的工作代码:
.then(response => response.json())
.then(data => {
if(data.status == 200){
this.props.history.push("/");
console.log('Successfully Login');
}
})
我正在关注此文档redirect-on-login-and-logout
答案 4 :(得分:3)
我只想分享2020年的实际答案。 在状态中存储先前位置的主要方法是相同的。但是onEnter已从库中删除。现在我们可以像在documentation中一样使用AuthRoute:
<AuthRoute exact path="/food">
<Food />
</AuthRoute>
<Route exact path="/login">
<Login />
</Route>
const AuthRoute = ({ children, isAuthorized, ...rest }) => {
const loginLink = usePrepareLink({
to: "/login",
isRelativePath: true
});
return (
<Route {...rest} render={({ location }) =>
isAuthorized ? (
children
) : (
<Redirect to={{
...loginLink,
state: { from: location }
}} />
)
} />
);
};
我们可以使用状态在登录后恢复先前的URL
const onSignIn = useCallback(() => {
setIsAuthorized(value);
const link = (state && state.from) || "/restore-prevented-route";
history.replace(link);
}, [setIsAuthorized, value, history, state]);
答案 5 :(得分:1)
onEnter
不再存在于 react-router-4
,您可以利用 <Route render={ ... } />
来实现相同的功能。
这是一个相同的例子。
<React.Fragment>
<Switch>
<Route path="/dashboard" render={() => (isAuth() ? <Redirect to="/login" /> : <DashboardRoutes />)} />
<Route path="/login" component={Login} />
</Switch>
</React.Fragment>
isAuth()
在我的例子中是一个函数,它基本上检查我们是否有身份验证令牌,并根据它返回真/假。
function isLoggedIn() {
if (!localStorage.getItem('token')) {
return true;
}
return false;
}
答案 6 :(得分:1)
Redirect to Login After Logout
import { useHistory } from "react-router-dom";
const history = useHistory();
history.push("/login");
答案 7 :(得分:0)
@JohnSz提到我在使用withRouter方面也存在问题。相反,我按照这里的指示做了: https://github.com/reactjs/react-router/blob/master/upgrade-guides/v2.0.0.md#programmatic-navigation
const RouteComponent = React.createClass({
contextTypes: {
router: React.PropTypes.object.isRequired
},
someHandler() {
this.context.router.push(...)
}
})
基本上:
干杯。