react组件渲染原理

jsx如何生成element:

JSX代码经过babel编译成React.createElement的表达式。element在React里,是组成虚拟DOM 树的节点,用来描述在浏览器上看到什么。它的参数有三个:
1、type -> 标签
2、attributes -> 标签属性,没有的话,可以为null
3、children -> 标签的子节点

e.g.return(
	React.createElement(
            	‘div’,
            	{ className: ‘first’ },
            	'Hello, world’
       	 ),
)

React.createElement的表达式会在render函数被调用的时候执行。当render函数被调用的时候,会返回一个element,element不一定是Object类型。

element如何转化成真实DOM节点的:

  • 首次渲染:

    若不是Oobject类型,string、number创建ReactDOMTextComponent对象,调用该对象的mount方法。在这个mount方法中,把文本放到一个span中,调用容器组件的innerHTML,进行渲染;null、false创建ReactDOMEmptyComponent对象。
    element为Object类型,若是原生DOM标签,给它创建ReactDOMComponent的实例对象,通过递归调用到ReactDOMComponent的mountComponent方法来得到真实DOM。
    如果第二步render出来的element 类型是自定义组件
    它就会去调用ReactCompositeComponentWrapper的mountComponent方法,从而形成了一个递归。递归调用子组件的render方法进而调用map方法,直至把自定义标签分解为前两种标签。

  • 更新渲染:

    函数setState被调用后,将传入的state放进pendingState的数组里存起来,若当前流程处于批量更新,则将当前组件的instance放进dirtyComponent里,当这个更新流程中所有需要更新的组件收集完毕之后就会遍历uptateComponent对组件进行更新。当然,如果当前不处于批量更新的状态,会直接去遍历dirtyComponent进行更新。
    假设Example是自定义组件,即调用的是ReactCompositeComponentWrapper的updateComponent方法。
    在这里插入图片描述
    1、计算出nextState(shouldComponentUpdate)
    2、render()得到nextRenderElement(componentWillUpdate可修改state)
    3、与prevtElement进行Diff 比较,更新节点 (componentDidUpdate)

扩充:diff算法
两个相同的组件产生类似的DOM结构,不同组件产生不同DOM结构;
对于同一层次的一组子节点,它们可以通过唯一的id区分。
不同节点类型:React将不会在去对比子节点。因为不同的组件DOM结构会不相同,所以就没有必要在去对比子节点了。
相同节点类型:dom类型节点,react会对比它们的属性,只改变需要改变的属性;自定义节点类型逻辑都在React组件里面,所以它能做的就是根据新节点的props去更新原来根节点的组件实例,触发一个更新的过程,最后在对所有的child节点在进行diff的递归比较更新;
子节点比较:依次比较,顺序不同即使仍存在的节点依旧会被卸载重建,可以加null保持DOM结构的稳定性,也可以给节点配置key,让React可以识别节点是否存在,只在指定位置创建节点插入。

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值