не удается выполнить обновление состояния реакции при проблеме с размонтированным компонентом с помощью useEffect

#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 проблемы, которые могут вызывать дефекты, которые вы видите:

  1. Первая проблема вызвана областью действия функции внутри useEffect и вашим обратным вызовом для storeUser . Вместо того, чтобы полагаться на обратный вызов, чтобы определить, есть ли у пользователя адрес электронной почты, просто сделайте это в своем условии рендеринга, и пусть redux react render cycle поможет вам.
  2. Кроме того, вы должны вызывать 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,
    };
};