React 中的 setState 回调函数

Irakli Tchigladze 2023年1月30日 2021年12月4日
  1. 为什么需要回调参数
  2. 何时使用 setState() 回调函数
React 中的 setState 回调函数

乍一看,React 组件的 .setState() 方法似乎很简单。它更新现有状态以反映参数的变化。然而,很多人不知道 .setState() 方法还接受另一个可选参数。这个参数是一个回调函数,在状态更新后立即执行。

为了编写更可靠的代码,你需要了解 .setState() 回调函数的作用以及如何使用它。

为什么需要回调参数

大多数 React 开发人员不知道 .setState() 方法是异步的。更新不会立即发生。如果你尝试在调用 setState() 后立即读取 state 的更新内容,你可能会失败或读取错误的数据。

为了解决这个问题,setState() 方法采用另一个可选参数 - 回调函数。只有在状态更新后才会执行回调函数中指定的操作。

何时使用 setState() 回调函数

正如我们上面提到的,setState 调用是异步的。它不会立即更新状态对象。如果你想根据最近的更新执行检查或其他一些操作,使用 setState() 回调是一个很好的做法。但是,这不是执行此类操作的唯一方法。我们将在后面的部分讨论替代方案。

setState() 回调对于以下类型的操作非常有用:调用 API、检查 state 的内容以有条件地抛出错误,以及需要在 state 更新后立即执行的其他操作. setState() 回调也经常用于验证。

例如,如果我们想使用 <input> 来更新状态,我们可以使用回调函数绝对确定地读取更新后的值。如果没有回调,我们可能会检查状态的陈旧旧版本。

代码示例:

class App extends Component {
  constructor(props){
    super(props)
    this.state = {
      text: ""
    }
  }
  render() {
    return (
    <div>
    	<h1>Hello World</h1>
   		<input type="text" 
         onChange={(e) => this.setState({text: e.target.value}, 
         () => console.log(this.state.text))}></input>
    </div>
    )
  }
}

回调函数 vs render()

怀疑论者可能会问,当我可以访问 render() 方法主体中更新的 state 时,为什么我需要 setState() 回调?

不同之处在于,render() 方法将在每次 state 更新时运行,而 setState() 回调只会在更新 state 中的特定值后运行。

async 函数中的 .setState()

有时 .setState() 方法可以在异步函数中调用。在这种情况下,状态不会立即更新。

如果你使用 this 关键字读取 state 属性的值,你将获得一个旧值。另一方面,一旦 async 任务完成,就会调用回调函数。

替代方案

React 文档建议开发人员改用 componentDidUpdate() 生命周期方法,该方法仅适用于类组件。

对于功能组件,useEffect() 可以有效地替换所有生命周期钩子,包括 componentDidUpdate()。你只需要自定义依赖项数组。

例如,如果你的状态有一个 age 属性,并且你想在状态更新后检查它的值,useEffect() 钩子将如下所示:

useEffect(()=>console.log(`doing something with ${this.state.age}`), [age])
Irakli Tchigladze avatar Irakli Tchigladze avatar

Irakli is a writer who loves computers and helping people solve their technical problems. He lives in Georgia and enjoys spending time with animals.

LinkedIn