@DaveGarrow

Почему не работает useState при клике?

Почему не срабатывает setChosenPicture?
chosenPicture выдает пустую строку даже если его поставить в setTimeout после setChosenPicture

const [chosenPicture, setChosenPicture] = useState('');


const handleShowFloatingPicture = (index, fileName, width, height, element) => {
     setChosenPicture(fileName);
     setTimeout(() => {
                console.log(chosenPicture);
     }, 5000);
}

...
       return (
                    <Picture
                        onClick={(e) =>
                            handleShowFloatingPicture(index, item.fileName, item.width, item.height, e)
                        }
                    />
                );
            }
  • Вопрос задан
  • 935 просмотров
Решения вопроса 2
@abberati
frontend-разработчик
Он работает. Он асинхронный. В документации про это написано. Если ты хочешь что-то делать с новым значением стейта, то это что-то ты должен делать в useEffect

А в тайм-ауте не меняется из-за замыкания. Это константа. Она никогда не поменяется в замыкании. Никогда.
Ответ написан
setChosenPicture(fileName);
     setTimeout(() => {
                console.log(chosenPicture);
     }, 5000);

Этот код не будет работать как вы хотите. Стейт не меняется мгновенно, новое значение будет в следующей итерации рендера, проще говоря при следующем вызове функции-компонента.
Я не знаю, что вы хотите сделать с chosenPicture, но вывести значение в консоль вы можете так:
const [chosenPicture, setChosenPicture] = useState('');

console.log(chosenPicture) // после обновления стейта в консоль выведется новое значение

const handleShowFloatingPicture = (index, fileName, width, height, element) => {
     setChosenPicture(fileName);
     setTimeout(() => {
                console.log(chosenPicture); // здесь старое значение, потому что функция вызвалась только один раз
                // и на момент вызова там была пустая строка
     }, 5000);
}

Сделать что-то со значением можно через useEffect:
const [chosenPicture, setChosenPicture] = useState('');

useEffect(() => {
  if (chosenPicture) {
    console.log(chosenPicture)
  }
}, [chosenPicture]) // это массив завимостей, useEffect  вызывает свой коллбэк каждый раз при изменении завимостей

const handleShowFloatingPicture = (index, fileName, width, height, element) => {
     setChosenPicture(fileName);
}
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы