我在使用带身份验证的用户的PrivateRoute
时遇到问题。
因为我使用redux来捕获用户的身份验证,所以在呈现组件之前,我需要等待state
从存储返回。如果不是,页面将自动重定向到login route
。
我的问题是,当前路由在等待身份验证结果时会被重定向到登录页面。如果通过身份验证,将返回页面。
所以我想先等authentication result
。如果通过认证,将加载页面组件,否则将重定向到登录页面。
这是我的带身份验证的私有路由。
import React from "react";
import { Route, Redirect} from "react-router-dom";
import { connect } from "react-redux";
const PrivateRoute = ({ component: Component, auth, role, ...rest }) => {
return (
<Route
{...rest}
render={props => auth.isAuthenticated ? (
<Component {...props} />
) : (
<Redirect to={{
pathname: "/",
state: { from: props.location }
}} />
)
}
/>
)
}
const stateStoreToProp = state => ({
auth: state.loginReducer,
});
export default connect(stateStoreToProp)(PrivateRoute);
这是我的自动重定向的登录组件。
let history = useHistory();
let location = useLocation();
let { from } = location.state || { from: { pathname: "/choose" } };
const isAuthenticated = prop.loginReducer.isAuthenticated;
const user = prop.loginReducer.user;
if (isAuthenticated && typeof user !== "undefined") {
history.replace(from);
}
这是App.js
import { loadUser } from './actions/AuthAction';
function App() {
useEffect(() => {
store.dispatch(loadUser());
}, []);
return (
<Provider store={store}>
<Router>
<Fragment>
<div className="blockcontain">
<div className="fss">
<div className="rightSide">
<Switch>
<Route path='/' exact component={Login} />
<PrivateRoute exact path='/choose' component={Choose} />
</Switch>
</div>
</div>
</div>
</Fragment>
</Router>
</Provider>
);
}
和LoginReducer
import {
LOGIN_SUCCESS, LOGIN_FAIL, USER_LOADED, AUTH_ERROR
} from '../actions/typeName';
import Cookies from 'js-cookie';
const initialState = {
token: Cookies.get('token'),
isAuthenticated: null,
loading: true,
user: null
}
const loginReducer = (state = initialState, action) => {
const {type, payload} = action;
switch(type) {
case USER_LOADED:
return {
...state,
isAuthenticated: true,
loading: false,
user: payload
};
case LOGIN_SUCCESS:
Cookies.set('token', payload.access_token, { expires: payload.expires_at });
return {
...state,
isAuthenticated: true,
loading: false
}
case AUTH_ERROR:
case LOGIN_FAIL:
return {
...state,
token:null,
isAuthenticated: false,
loading: true
}
default:
return state;
}
}
export default loginReducer;
我去choose page
,它将转到登录页面,因为store for authentication
还没有准备好。
谢谢。
发布于 2021-01-02 12:40:48
您可以将加载属性添加到您的状态,并仅在获取完成后显示路由:
const PrivateRoute = ({ component: Component, auth, isLoading, role, ...rest }) => {
if(isLoading) return <div>Loading...</div>;
return (
<Route
{...rest}
render={(props) =>
auth.isAuthenticated ? (
<Component {...props} />
) : (
<Redirect
to={{
pathname: '/',
state: { from: props.location },
}}
/>
)
}
/>
)
}
const stateStoreToProp = (state) => ({
isLoading: state.loading,
auth: state.loginReducer,
})
export default connect(stateStoreToProp)(PrivateRoute)
并在你的reducer中添加加载突变,例如:
case REQUEST_LOGIN:
return [...state, isLoading: true];
case LOGIN_SUCCESSFUL:
return [...state, auth: isAuthenticated, isLoading: false];
发布于 2021-01-02 12:41:19
您可以做的是添加一个“正在加载”的密钥到您的身份验证状态,因此当它进行身份验证时,状态将为"true“,否则为"false”。如果为真,则显示一个加载器。
import React from "react";
import { Route, Redirect} from "react-router-dom";
import { connect } from "react-redux";
const PrivateRoute = ({ component: Component, auth, role, ...rest }) => {
return (
<>
{
auth.loading && (
<Loader/>
)
}
{
!auth.loading && (
(
<Route
{...rest}
render={props => auth.isAuthenticated ? (
<Component {...props} />
) : (
<Redirect to={{
pathname: "/",
state: { from: props.location }
}} />
)
}
/>
)
)
}
</>
)
}
const stateStoreToProp = state => ({
auth: state.loginReducer,
});
export default connect(stateStoreToProp)(PrivateRoute);
https://stackoverflow.com/questions/65538978
复制相似问题