组件化和react

说一下对组件化的理解

组件化的核心有两点:

  1. 组件的封装
  2. 组件的复用

那些需要封装?首先是视图。一个组件的定义中,视图是首要的;其次是数据;最后是变化逻辑,即数据如何驱动视图变化。

而对于组件的复用,每次复用的是这个模板,并传递不同的属性过去。那么其重点就是props传递。

JSX本质是什么?

JSX解析成JS

JSX语法根本无法被浏览器所解析,那么它是如何在浏览器中运行的?简单来说,就是被解析成了JS。

解析过程用一个例子来解释:

pic1

看一下React.createElement,这是React中定义好的一个函数,第一个参数是标签名,第二个参数是属性,第三个参数可以是个数组,包含了所有的子元素,也可以是直接把子元素放在第三个参数开始的位置,即下面的用法:

pic2

那么第一个例子就是用了第二种用法,从第三个参数开始就是子元素。再看另外一个例子

pic3

这就是另外一种用法,第三个参数是数组,里面包含了所有子元素。

在另外一篇文章 vdom和vue 中,讲了vdom的两个核心函数,h函数和patch函数,那么这里的React.createElement函数就和h函数是类似的,和vue中的_c函数也是类似的。

那么总结一下,JSX其实就是一个语法糖,在开发环境下会将JSX编译成JS代码。

JSX的写法出现,大大降低了学习成本和编码工作量,但是同时,JSX也会增加debug成本。

独立的标准

JSX是React引入的,但不是React独有的。React已经将它作为一个独立标准开放,其他项目也可用。而React.createElement是可以自定义修改的。

JSX的本身功能已经晚辈了,和其他标准兼容和扩展性没问题。

JSX和vdom

首先为什么需要vdom?

vdom就是React初次推广开来的,结合JSX。而JSX其实就是模板,最终要渲染成html。

其次react需要通过数据驱动视图,JSX需要转换为JS代码,JS在这种数据驱动视图的场景下不能亲自操作dom,需要一个中间层——vdom。

需要渲染成html的两个场景包括初次渲染和修改state后的re-render重复渲染。

其次,在上面我们讲过了,react里,React.createElement相当于vdom中的h函数,如下

pic4

可以知道,所有jsx都会被转换为js代码来执行,其次,上图中的profile会返回vnode。

接下来就是patch,何时patch?

初次渲染时间就是使用ReactDOM.render(<App/>, container)函数的时候,此时会触发patch(container, vnode);

之后的re-render触发则是在使用setState修改state时,会触发patch(vnode, newVnode)

自定义组件的解析

如果在react中定义了组件,那么会这样解析

pic5

在ReactDOM.render的第一个参数中就是该组件的构造函数。

自定义组件的解析过程如下:

  1. ‘div’ - 直接渲染
    即可,vdom可以做到
  2. Input和List是自定义组件(class),vdom默认不认识
  3. 因此Input和List定义的时候必须声明render函数
  4. 根据props初始化实例,然后执行实例的render函数
  5. render函数返回的还是vnode对象

这里详细解释一下3、4步

以List为例子:

pic6

当渲染List的时候,通过data属性里的数据初始化一个List(class)的实例,这个实例实际上就是render函数返回的vnode对象

因此,上面的过程类似于如下代码:

pic7

setState

说一下React setState的过程

重点1:setState是异步的。这里顺带一提,vue修改属性也是异步的。

重点2: setState的过程

首先举个例子证明setState是异步的:

pic8

可以看到,在setState后马上打印this.state.list的值是仍为变化的值,只有在异步的情况下才有这种结果

那为何setState需要异步?第一,可能会一次执行多次setState;其次,无法规定、限制用户如何使用setState;没必要每次setState都重新渲染,考虑性能;另外,即便是每次重新渲染,用户也看不到中间的效果。

因此使用异步,将state统一执行即可。

例子如下:

pic9

在这里,只需要执行最后一个setState的渲染就可以了。

vue修改属性也是异步的原因和setState是一样的。修改vue属性,被响应式的set监听到,然后set中执行updateComponent,updateComponent重新执行vm._render函数,生成的vnode和prevVnode通过patch对比,渲染到html中

在set中执行updateComponent是异步的,在这里和react是类似的。

现在开始说setState的过程,首先每个组件实例,都有一个renderComponent的用法,继承于父类Component,执行renderComponent会重新执行实例的render,即重新返回一个新的vnode,newVnode和preVnode执行patch函数。

 彻底弄懂 Http 缓存机制 - 基于缓存策略三要素分解法
虚拟dom 
上一篇:彻底弄懂 Http 缓存机制 - 基于缓存策略三要素分解法
下一篇:虚拟dom


如果我的文章对你有帮助,或许可以打赏一下呀!

支付宝
微信
QQ