setState与批处理

    0

本文基于版本17.0.218

同步还是异步

setState本身逻辑并不是由异步逻辑实现

在setState之后console.log打印的值并不是最新的值、由于批处理,状态变化是异步的

不同模式下表现是不一样的

  1. react17同步模式ReactDOM.render中如果在异步里是同步的,否则是异步的
  2. react18异步模式ReactDOM.createRoot中是都是异步更新的

批处理

是什么

在批处理下,你可能不会得到想到的结果

jsx
this.setState({ num: this.state.num + 1 }); this.setState({ num: this.state.num + 2 }); this.setState({ num: this.state.num + 3 }); #等于 Object.assign( previousState, {num: state.num + 1}, {num: state.num + 2}, {num: state.num + 3} ) #结果+3

为什么

如果每一次setState都去重新渲染更新视图,那么对性能有非常大的影响

具体表现

在react17,异步(setTimeout)或者绕过react组件(addEventListener)的不会进行批处理

jsx
import "./styles.css"; import React, { Component } from "react"; export default class App extends Component { state = { num: 1 }; handleClick = () => { // setTimeout(() => { // this.setState({ num: this.state.num + 1 }); // this.setState({ num: this.state.num + 1 }); // console.log(this.state.num); // }); }; componentDidMount() { document.querySelector("button").addEventListener("click", () => { this.setState({ num: this.state.num + 1 }); this.setState({ num: this.state.num + 1 }); console.log(this.state.num); }); } render() { return ( <div className="App"> <h2>{this.state.num}</h2> <button onClick={this.handleClick}>111</button> </div> ); } }

怎么获取最新的state值

react17

在class component下

  1. setState用函数写法

  2. setState回调函数获取最新

  3. setTimeout

  4. addEventListener(不推荐)

在function下

  1. useEffect

react18

在class component下

  1. setState用函数写法

  2. setState回调函数获取最新

在function下

  1. useEffect

总结

  1. 在react18以前,setState只有在原生和setTimeout是可以立即获取值的
  2. setState执行过程和代码是同步的,但是由于事件合成、批处理无法立即拿到更新后的值,形成了异步、
评论区

共有评论 0

暂无评论