Я пишу небольшое приложение для ведения дел, и у меня возникают проблемы с перенаправлением пользователя на основе данных из бэкэнда. Приложение использует:
express-session
для создания пользовательского сеанса на стороне сервера connect-mongodb-session
для хранения данных сеанса react-redux
для приложения управление состоянием
Когда пользователь входит в систему, свойство модели User
с именем isLoggedIn
устанавливается на true
. Это значение используется для перенаправления пользователя в компонент LandingPage
, где он может создавать новые задачи. Это нормально, но проблема в том, что, если целевая страница обновляется, значение для isLoggedIn
не поступило из бэкэнда до визуализации LandingPage
. Это приводит к тому, что пользователь перенаправляется на страницу входа, затем поступают данные, а затем они снова перенаправляются на целевую страницу.
«Вспыхивающая» страница входа чрезвычайно раздражает, и я не могу найти какой-либо способ обойти это. Я попытался сохранить логическое значение isLoggedIn
в localStorage
, и это сработало замечательно, но, конечно, это лишает смысла использование сеанса на стороне сервера?
Вот некоторые фрагменты из моего кода, спасибо
Приложение. js
import { getUser } from "./redux/actions/auth";
const App = withRouter(({ user, data }) => {
useEffect(() => {
store.dispatch(getUser()); // user data loaded every time app re-renders
}, []);
return (
<Provider store={store}>
<Router>
<div className='my-app'>
<Switch>
<Route exact path='/login' component={Login} />
<Private
isLoggedIn={isLoggedIn}
path='/landing'
component={LandingPage}
/>
</Switch>
</div>
</Router>
</Provider>
);
const Private = ({ isLoggedIn, component: Component, ...rest }) => {
return (
<Route
{...rest}
render={props =>
isLoggedIn ? (
<Component {...props} />
) : (
// I think the problem is here - because isLoggedIn is not available from the backend
// call yet, so login page gets rendered before the data arrives
<Redirect to='/login' {...props} />
)
}
/>
);
};
Вход. js
render() {
const { user } = this.props;
if (user.isLoggedIn) return <Redirect to='/landing' />; // user sent to landing if they are logged in
return (... login form jsx)
}
Login.propTypes = {
user: PropTypes.object
};
const mapStateToProps = state => ({
user: state.auth.user
});
export default connect(mapStateToProps)(Login);
getUser. js
export const getUser = () => async dispatch => {
try {
const response = await axios.get("/api/user");
dispatch({
type: LOADED_USER,
payload: response.data
});
} catch (error) {
dispatch({
type: LOAD_USER_FAILED
});
}
};
getUserReducer. js
const initialState = {
user: {}
};
export default function(state = initialState, action) {
const { type, payload } = action;
switch (type) {
case LOGIN_SUCCEEDED:
case LOADED_USER:
return {
...state,
user: payload
};
case LOGIN_FAILED:
case LOAD_USER_FAILED:
return {
...state,
user: {}
};
default:
return state;
}
}