react使用setState

直接使用
this.state.counter = 5;
这种改变方式,虽然改变了致,但是react不知道他已经改变了,所以不会渲染,
setState是继承的,在Component的原型上

setState是异步更新的:

this.state = {
counter = 0
}

this.setState({
counter: 5
})
console.log(counter)//显示还是原来的counter 0

原因:
手下要承认的是 setState时re-render是很差的操作,重新渲染需要时间和资源
1.假设我们使用props传值给子组件, 如果父组件setState()同步更新了state时,父组件传给子组件的props是不会立即刷新的,因为无法同步re-render,就无法同步刷新props,这样自组建的props和父组件的state数据不一样了,破坏了内部数据的统一。
2.每次re-render会使用很多资源,效率很低,最好的办法就是同步获取多个更新,之后进行批量更新,
如何立即获取更新的数据呢?

1.在setState中添加回调函数
this.setState({
 counter:5
},())=>{
console.log(counter)//5
}
2.生命周期函数 而且运行优先级高于setState的回调函数
ComponentDidUpdate(){
console.log(this.state.counter)//5
}

但有的时候setState是同步更新:
setState在合成事件(onClick)和钩子函数是异步的
在settimeout和原生事件,dom里是同步的

componentDidMount() {
       document.getElementById("btn").addEventListener("click", () => {
           this.setState({
               message: "hello react"
           })
           console.log(this.state.message)
       })
    }
 setTimeout(() => {
            this.setState({
                message:"hello react"
            })
            console.log(this.state.message)

        },0)
      

数据的合并

this.state=({
counter: 0;
age: 18
)}
this.setState({
counter:1
)}
修改后 为什么age不会消失呢?
 通过Object.assign实现的
 Object.assign({}, this.state, {counter:1})
 后面的属性会覆盖前面形同的属性

setState本身的合并

Component.prototype.setState = function(partialState, callback) {
//将这个组件, setState内的值,回调函数穿了过去
  this.updater.enqueueSetState(this, partialState, callback, 'setState');
};

enqueueSetState(inst, payload, callback) {
   根据this拿到组件实例
       const fiber = getInstance(inst);
     const eventTime = requestEventTime();
     //优先级
     const lane = requestUpdateLane(fiber);

    const update = createUpdate(eventTime, lane);
    update.payload = payload;
    enqueueUpdate(fiber, update);
    通过enqueueUpdate将update存到updateQueue里面
}

getStateFromUpdate通过
// Merge the partial state and the previous state.
 Object.assign({}, prevState, partialState);
 合并之前的状态和现在

在
processUpdateQueue中通过 do while 每次里面都调用getStateFromUpdate
进行更新, 就导致 每次后面中更新的setState把之前setState里面的值覆盖

所以increment() {
    //1.setState本身被合并 输出为1
   /*  this.setState({
      counter: this.state.counter + 1
    });
    this.setState({
      counter: this.state.counter + 2
    });
    this.setState({
      counter: this.state.counter + 1
    }); *}


  //1.setState本身被合并 输出为最后一次的setState的操作 输出为2
    this.setState({
        counter: this.state.counter + 1
      });
      this.setState({
        counter: this.state.counter + 1
      });
      this.setState({
        counter: this.state.counter + 2
      });


/* // 2.setState合并时进行累加,当输入为函数时会累加合并
 因为在这个时候里面有一个判断,如果传过来的是函数 ,就。,执行这个函数call()中包括前一次的值
 
    this.setState((prevState, props) => {
      return {
        counter: prevState.counter + 1
      }
    });
    this.setState((prevState, props) => {
      return {
        counter: prevState.counter + 1
      }
    });
    this.setState((prevState, props) => {
      return {
        counter: prevState.counter + 1
      }
    }); */
    ```
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值