react原理分析--this.state修改引起的重新渲染

整理向,非原创,目的是整理出浅显易懂的方向性说明.

 

比如现有

this.state={name:"小明",age:18}

 

我们说修改组件的状态要用this.setState()来实现.这里有两个问题

1.为什么?我直接用this.state.age=17能不能实现重新渲染?

不能.因为它只是改变了这个组件当前的状态,并没有调用render().

 

2.this.setState()的原理是什么?

react中有一个原则:有变化,就一定返回一个新对象;没变化,原对象不做变化直接返回;

结合这个原则我们来分析一下原理:

参数:

this.setState()有三个参数:分别是this.state、nextState和callback.

       其中,第一个参数是默认已经给的,为什么还要提出来是为了方便理解.

       第二个参数是新状态,也就是我们期望组件能达到的状态.有多种方式.传一个对象或者传一个返回对象的函数.最终效果就是传一个对象.

this.setState({age:17})

      第三个参数是设置成功之后的回调函数.

返回值:

this.setState()的返回值是一个新的对象,也就是说是一个新的状态.它使用了Object.assign(),将已修改的属性添加进去.而不是覆盖.

 

this.state里面有两个属性,如果我   this.setState({age:17}) 这么操作会不会导致this.state里面没有了"name"属性?

不会!我们上面刚说,this.setState()是返回一个新的对象,它会把有变动的改变成变动后的值,没有变动的保留.所以,你完全可以用这个方法去改变其中的某一个值.

 

接下来我们重点分析内部的原理:

首先,需要根据原来的this.state和传进来的参数来判断是否批量更改(是否批量差了一个收集待改组件的步骤),而这里的this.state是我之前说的默认传进来的.

然后,再根据this.state来计算nextstate. (shouldComponentUpdate()根据拿到的nextstate来返回一个布尔值,true则进行下一步,false,则下一步不执行.然后就进入componentWillUpdate)

接着render()出一个next组件,

最后根据diff算法进行更新渲染. 结束后进入生命周期函数componentDidUpdate()

这里也有几个问题:

(1)假如我调用this.setState()设置的值跟之前一样的,会不会重新渲染一次?

会!因为shouldComponentUpdate()默认肯定返回true,所以一定会往下执行.那为什么我要是根据nextstate返回一个布尔值呢?因为我们可以手动通过这种方式来控制render()来减少无用功,这是shouldComponentUpdate()的功能,只不过没有默认执行而已.

 

(2)假如我进行多次this.setState()的操作,而且都是同一个属性修改最终以哪次为主?

 

function stateChange() {
      this.setState({age: this.state.age + 1});
      this.setState({age: this.state.age + 1});
      this.setState({age: this.state.age + 1});
}

 

这里情况比较复杂,大体上可以理解为在react的体制内setState()是异步操作,所以最后this.state.age最终还是只加了1,比如onClick()这种react原生的事件中.但是体制外的是同步操作.最终会加3.

 

(3)为啥console.log()拿不到最新的this.state?

如第(2)点所说,setState()是异步操作.还记得上面所说this.setState()还有一个参数是回调函数吗?所以需要在this.setState()的参数里面再传一个回调函数,在函数中打印就能得到this.state.

 

转载于:https://www.cnblogs.com/Shyno/p/11098196.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值