useState с логическим значением в реагировать - PullRequest
3 голосов
/ 06 апреля 2020

В приведенном ниже фрагменте кода, когда я нажимаю кнопку Изменить, чтобы изменить значение isLoading, ничего не происходит (isLoading ложно).

const App = (props) => {
  const [isLoading, setIsLoading] = useState(false)

  const buttonHandler = () => {
    setIsLoading(current => !current)
    console.log(isLoading) // is false 
  }

  return (
    <div>
      <button onClick={buttonHandler} type="button">
        Change
      </button>
    </div>
  )
}

Я пытался изменить isLoading с помощью Следующие способы, но не влияют:

1-setIsLoading(current => !current)
2-setIsLoading(!isLoading)
3-setIsLoading(true)

Ответы [ 3 ]

2 голосов
/ 06 апреля 2020

setIsLoading - это асинхронная функция c, и вы не можете получить значение состояния сразу после обновления.

setState действия являются асинхронными и группируются для повышения производительности. setState () не изменяет это немедленно. Таким образом, вызовы setState являются асинхронными, а также пакетными для улучшения пользовательского интерфейса и производительности. Это относится к обоим functional/Class компонентам.

Из документации React

React может объединять несколько вызовов setState () в одно обновление для повышения производительности. Поскольку this.props и this.state могут обновляться асинхронно, вы не должны полагаться на их значения для вычисления следующего состояния. Вы можете прочитать больше об этом здесь

Если вы хотите получить обновленное значение состояния, тогда используйте useEffect ловушку с массивом зависимостей. React будет выполнять эту ловушку после каждого обновления состояния.

const {useEffect, useState } = React;

const App = (props) => {
  const [isLoading, setIsLoading] = useState(false)
  const buttonHandler = () => {
    setIsLoading(current => !current)
  }

  useEffect( () => {
    console.log(isLoading);
}, [isLoading]);

  return (
    <div>
      <button onClick={buttonHandler} type="button">
        Change
      </button>

      {isLoading? "Loading...": null}
    </div>
  )
}

ReactDOM.render(<App />, document.getElementById('root'));
<script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>

    <div id="root">
      loading.....
    </div>
1 голос
/ 06 апреля 2020

Состояние и перехватчики асинхронны. Вы не увидите изменения в isLoading непосредственно после вызова set..., но только при следующем рендеринге компонента, что произойдет «достаточно скоро».

Если вы напечатаете значение Statelet (в виде строки; false отображает как ничего), вы можете увидеть изменение:

return (
    <div>
      <button onClick={buttonHandler} type="button">
        Change (now {"" + isLoading})
      </button>
    </div>
  )
1 голос
/ 06 апреля 2020

Это ожидаемое поведение. Вы можете использовать useEffect для доступа к последнему значению.

Вот нить, обсуждающая ту же проблему: метод useState, не отражающий немедленное изменение

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...