JS问题整理与思考--react setState的过程

  • setState 的异步
  • vue 修改属性也是异步的
  • setState的过程

setState 的异步

class App extends Component {
  constructor (props) {
    super(props)
    this.state = {
      name:"111"
    }
  }
  render() {
    return (
        <div className="App" onClick={this.clickHandler.bind(this)}>
          {this.state.name}
        </div>
    );
  }
    clickHandler () {
        console.log(this.state.name)
        this.setState({
            name:'aaa'
        })
        console.log(this.state.name)
    }
}

setState为什么需要异步

  • 可能会一次执行多次setState
  • 无法规定/限制用户如何使用setState
  • 没必要每次都重新渲染,考虑性能
  • 即便是每次重新渲染,用户也看不到中间效果

例如下面的 栗子,只需要执行一次。

clickHandler () {
    console.log(this.state.name)
    this.setState({
        name:'aaa1'
    })
    this.setState({
        name:'aaa2'
    })
    this.setState({
        name:'aaa333'
    })
    console.log(this.state.name)
}

vue 修改属性也是异步的

vue中data属性变化

其中第二步是异步执行的。

  • 修改属性,被响应式的set监听到
  • set中执行updateComponent
  • uodateComponent重新执行vm.render()
  • 生成vnode和prevVnode,通过patch进行对比
  • 渲染到html

setState的过程

  • 每个组件实例,都有renderComponent方法
  • 执行renderComponent会重新执行实例的render
  • render函数返回newVnode,然后拿到preVnode
  • 执行patch(preVnode,newVnode)

renderComponent是Component的一个方法,实例可以直接使用

    // 模拟 拷贝下旧的Vnode,调用render生成新的Vnode,然后执行patch
class Component {
  constructor(props){
    super(props)
  }
  renderComponent () {
    const prevVnode = this._vnode
    const newVnode = this.render()
    patch(prevVnode,newVnode)

  }
}
    // setState是异步的,原理类似于执行完成之后,回调执行renderComponent
clickHandler () {
    console.log(this.state.name)
    this.setState({
        name:'aaa'
    },() => {
      console.log(this.state.name)
        this.renderComponent()
    })
    console.log(this.state.name)
}

React问题整理

  • jsx为何需要vdom:jsx需要渲染成html。这时要vdom这个中间层,来达到数据驱动视图的目的。
  • React.creatElement和H,都生成vnode
  • 核实patch:ReactDOM.render和setState(rerender)
  • 自定义组件都解析:初始化示例,然后执行render(1.初始化示例。2.调用render函数)

随机浏览