七、React中setState的理解

53 阅读1分钟

Vue对数据管理和界面刷新流程解析

template模板 -> render() -> h('div', {props}, children)

React对数据管理和界面刷新流程解析

render() -> React.createElement('div', {props}, children)

当我们执行this.setState的时候,render函数就会被重新执行、即使state中的数据没有发生改变

   shouldComponentUpdate() {
       if(prevState.msg === this.state.msg) return false
   }
   
   PureComponent()
  • React并没有做Vue那种类似Object.defineProperty Proxy的数据监听
  • React 必须通过调用this.setState告知state的变化
  • 方法继承自React.Component
  • 内部实现是 Object.assign(oldState, newState) 进行值的合并
  • this.setState({})是一个异步调用
import React, { Component } from "react";

export class App extends Component {
  constructor() {
    super();
    this.state = {
      counter: 0,
      msg: '默认值'
    };
  }

  btnClick() {
    // 这里的新对象值会与原来的值进行合并, Object.assing()
    // 这里不会立即进行合并,是一个异步操作
    this.setState({
      counter: this.state.counter + 1,
    });
    console.log(this.state.counter) // 此时的值还是0
    
    // 想拿到变化后的结果进行逻辑操作
    this.setState({
        msg: '异步修改后的值'
    }, () => {
        console.log('此回调会在成功合并后执行')
    })
  }

  render() {
    let { counter } = this.state;
    return (
      <div>
        <h3>当前计数:{counter}</h3>
        <button onClick={() => this.btnClick()}>改变</button>
      </div>
    );
  }
}

export default App;

设计异步setState的原因

  • 显著的提升性能
  • 不需要每次调用setState就执行一次render函数、应该在获取多个更新后进行批量更新
  • 每次更新完执行一次render函数,数据state发生改变,但是render函数还没执行完,传递给子组件的数据props并没有同步更新