S
S
Sergey2021-05-23 13:14:18
React
Sergey, 2021-05-23 13:14:18

Why is useState not working on click?

Why doesn't setChosenPicture work?
chosenPicture produces an empty string even if put in setTimeout after 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)
                        }
                    />
                );
            }

Answer the question

In order to leave comments, you need to log in

2 answer(s)
Y
Yustas Alexu, 2021-05-23
@DaveGarrow

setChosenPicture(fileName);
     setTimeout(() => {
                console.log(chosenPicture);
     }, 5000);

This code will not work the way you want. The state does not change instantly, the new value will be in the next iteration of the render, in other words, the next time the component function is called.
I don't know what you want to do with chosenPicture, but you can print the value to the console like this:
const [chosenPicture, setChosenPicture] = useState('');

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

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

You can do something with the value through useEffect:
const [chosenPicture, setChosenPicture] = useState('');

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

const handleShowFloatingPicture = (index, fileName, width, height, element) => {
     setChosenPicture(fileName);
}

A
abberati, 2021-05-23
@abberati

He works. It is asynchronous. The documentation says about it. If you want to do something with the new value of the state, then this is something you should do in useEffect
And in the timeout it does not change due to the closure. This is a constant. It will never change in a closure. Never.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question