#javascript #reactjs #redux-thunk
#javascript #reactjs #исправление-thunk
Вопрос:
Я пытаюсь перенаправить своего пользователя на частный маршрут. Я использую redux thunk для извлечения информации о пользователе из базы данных с помощью storeUser (), если информация существует, пользователь продолжает, в противном случае они перенаправляются обратно на домашнюю страницу. Однако это работает не так, как ожидалось. Его перенаправление обратно на домашнюю страницу, когда оно должно продолжаться. Я могу сделать это, используя синтаксис на основе классов и componentDidMount. Я попытался устранить эту проблему отсутствия доступа к componentDidMount, используя состояние проверки подлинности, чтобы определить, когда компонент завершил рендеринг
const PrivateRoute = (props) => {
const [authChecked, handleAuthChecked] = useState(false);
const [isAuth, handleIsAuth] = useState(false);
useEffect(() => {
props
.storeUser()
.then(() => {
props.user.email ? handleIsAuth(true) : handleIsAuth(false);
handleAuthChecked(true);
})
.catch(() => {
handleAuthChecked(true);
});
}, [props]);
if (authChecked) {
return isAuth ? <props.component /> : <Redirect to="/" />;
}
return null;
};
const mapStateToProps = (state) => {
return {
user: state.user,
};
};
export default connect(mapStateToProps, { storeUser })(PrivateRoute);
Однако код всегда будет перенаправлять пользователя. isAuth никогда не вернет true, даже если значение props.user.email равно true. Он запускается и перенаправляется до того, как у него появится возможность запустить handleIsAuth (true)
Комментарии:
1. Каждый раз, когда ваш компонент выполняет рендеринг, он вызывает асинхронную функцию StoreUser(). Вы должны убедиться, что он вызывается только один раз, указав [] во втором аргументе useEffect .
Ответ №1:
У вас есть 2 проблемы, которые могут вызывать дефекты, которые вы видите:
- Первая проблема вызвана областью действия функции внутри
useEffect
и вашим обратным вызовом дляstoreUser
. Вместо того, чтобы полагаться на обратный вызов, чтобы определить, есть ли у пользователя адрес электронной почты, просто сделайте это в своем условии рендеринга, и пусть redux react render cycle поможет вам. - Кроме того, вы должны вызывать
storeUser
действие только при монтировании. Не каждый разprops
обновляется.
Например:
const PrivateRoute = (props) => {
const [authChecked, handleAuthChecked] = useState(false);
useEffect(() => {
props
.storeUser()
.then(() => {
handleAuthChecked(true);
})
.catch(() => {
handleAuthChecked(true);
});
}, []);
if (authChecked) {
return !!props.user.email
? <props.component />
: <Redirect to="/" />;
}
return null;
};
const mapStateToProps = (state) => {
return {
user: state.user,
};
};