Реагировать на useState в функциональных компонентах, не обновляя значения свойств немедленно

Хук react useState не обновляет значение свойства и не отображает старое значение, даже обращаясь к нему через некоторое время. Я знаю, что это асинхронное обновление, но в конечном итоге оно должно обновить значение. Вот мой код:

const [ currentRowIndex, setCurrentRowIndex] = useState(0);
    React.useEffect(() => { 
        console.log('Index from useEffect: ',currentRowIndex);
        setCurrentRowIndex(currentRowIndex);}, [currentRowIndex]);
..
..
..
 const handleClick = (event, index) => {

        console.log('Index after click: ',index);
        setCurrentRowIndex(index);

        setTimeout(function(){ 
            console.log('Index in timeout: ',currentRowIndex);
         }, 3000);

        console.log('Index after updating: ',currentRowIndex);

    };

Вывод из консоли:

Index after click:  4
Index after updating:  0
Index from useEffect:  4
Index in timeout:  0

person Salman    schedule 28.01.2021    source источник
comment
Это связано с закрытием developer.mozilla.org/en-US/docs. /Web/JavaScript/Замыкания   -  person Nadia Chibrikova    schedule 28.01.2021
comment
зачем вам нужно setCurrentRowIndex в useEffect?   -  person fullstack    schedule 28.01.2021


Ответы (2)


console.log('Index after updating: ',currentRowIndex); это дает 0, потому что не подтверждено, что когда браузер выполняет это состояние, оно уже обновлено.

Когда вы хотите увидеть значение индекса после завершения обновления, вы просто печатаете индекс в useEffects со списком зависимостей, содержащим [currentRowIndex], тогда он показывает, что индекс обновляется правильно.

если вы можете предоставить информацию, что именно вы хотите сделать с этим обновленным значением, это поможет нам лучше понять проблему.

person Pavan    schedule 28.01.2021

Все происходит так, как должно быть, подумайте каждый раз, когда компонент визуализируется как кадр.

В то время, когда вы вызываете handleClick, currentRowIndex равен 0, вы передаете 0 в свой setTimeout и печатаете 0, потому что эта функция запоминает currentRowIndex как 0 при этом конкретном рендеринге, эта функция не изменяется при обновлении состояния.

Если вы визуализируете currentRowIndex в текстовом компоненте, вы увидите, что он обновляется, потому что новый рендеринг имеет обновленное состояние.

Вы можете распечатать его вне handleClick и увидеть значение состояния для каждого рендера.

 console.log('Index: ',currentRowIndex);

 const handleClick = (event, index) => {
       ...
    };
person Rubioj    schedule 28.01.2021