Сеттер 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. Я не понимаю, почему это происходит. У меня есть значение, и я его установил.
Проблема здесь в том, что 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.