useState与布尔值在反应

时间:2020-04-06 06:42:04

标签: reactjs react-hooks

在下面的代码段中,当我单击“更改”按钮以更改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 个答案:

答案 0 :(得分:2)

setIsLoading是一个异步函数,您无法在更新后立即获取状态值。

setState 操作是异步的,并且为了提高性能而进行了批量处理。 setState()不会立即对此进行更改。因此,setState调用是异步的,也可以是批处理的,以便获得更好的UI体验和性能。这适用于两个functional/Class组件。

来自React文档

React可以将多个setState()调用批处理为一个更新,以提高性能。 由于this.props和this.state可以异步更新,因此您不应依赖于它们的值来计算下一个状态。 您可以阅读有关此here

的更多信息

如果要获取更新后的状态值,请使用带有依赖项数组的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 :(得分:0)

这是预期的行为。您可能要使用useEffect来访问最新值。

以下是讨论相同问题的主题:useState set method not reflecting change immediately

希望这会有所帮助!

答案 2 :(得分:0)

状态和挂钩是异步的。调用isLoading之后,您不会直接在set...中看到任何更改,而只会在组件的下一次渲染时看到,这将“很快”发生。

如果您确实打印了statelet的值(作为字符串; false不显示任何内容),您可以看到更改:

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