Сеттер React useState не работает внутри useEffect с axios

Сеттер UseState внутри promise.then() не использует сеттер UseState внутри promise.then() не работает

Это мой хук useEffect

const [isLoggedIn, setIsLoggedIn] = useState(false);

  useEffect(() => {
      // axiosClient.get('user').then((data) => console.info(data.data.data.id));
      console.info(authAPI.isLoggedIn().then((res) => {
        setIsLoggedIn(res)
        console.info('done!', isLoggedIn)
      }));
    }, []);

Это мой апи:

async isLoggedIn() {
        try { 
            const res = await axiosClient.get('user');
            console.info(res.data.data)
            if (res.data.data.id) {
                return true;
            }
        } catch(err) {
            return false
        }
    },

а это мой клиент:

get(apiUrl) {
      const response = axios({
        method: 'get',
        url: this.url + apiUrl,
        withCredentials: true,
      })
      return response
    },

Когда я использую .then((res) => res в обещании, я получаю желаемое значение, которое является «истинным», однако, когда я пытаюсь установить его с помощью setIsLoggedIn(res), это не работает. Он просто остается со своим значением по умолчанию, которое равно false. Я не понимаю, почему это происходит. У меня есть значение, и я его установил.

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
1
0
101
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проблема здесь в том, что console.info('done!', isLoggedIn) регистрирует предыдущее значение состояния isLoggedIn, которое по-прежнему ложно, даже после того, как вы вызвали setIsLoggedIn(res).

Это связано с тем, что setIsLoggedIn является асинхронным и не сразу обновляет состояние. Поэтому, когда вы регистрируете isLoggedIn сразу после вызова setIsLoggedIn, он по-прежнему показывает предыдущее значение.

Чтобы увидеть обновленное значение isLoggedIn, вы можете либо использовать console.info('done!', res) вместо console.info('done!', isLoggedIn), либо добавить isLoggedIn в массив зависимостей вашего хука useEffect, чтобы ловушка запускается снова, когда isLoggedIn изменяется и регистрирует обновленное значение.

Вот обновленная версия вашего кода с добавленным массивом зависимостей:

const [isLoggedIn, setIsLoggedIn] = useState(false);

useEffect(() => {
  authAPI.isLoggedIn().then((res) => {
    setIsLoggedIn(res)
    console.info('done!', isLoggedIn)
  });
}, [isLoggedIn]);

Или вы можете напрямую зарегистрировать обновленное значение isLoggedIn:

const [isLoggedIn, setIsLoggedIn] = useState(false);

useEffect(() => {
  authAPI.isLoggedIn().then((res) => {
    setIsLoggedIn(res)
    console.info('done!', res)
  });
}, []);

Однако будьте осторожны, добавляя здесь зависимость isLoggedIn. Как только setIsLoggedIn() вызывается в первый раз, useEffect() будет повторно запущен при следующем повторном рендеринге, который вызовет authAPI.isLoggedIn() и .then(), который снова вызовет setIsLoggedIn(). В этот момент он снова перерендерится. На этот раз useEffect() не следует перезапускать, потому что его зависимость все та же, но это все еще дополнительный вызов API.

M. Desjardins 30.03.2023 19:44

Другие вопросы по теме