想进一步认识一下preact

learn preact deeply

Posted by markzhang on July 11, 2019

react不是先构建dom tree,再把这棵树渲染到页面上 是边构建dom tree节点的时候边把节点渲染到了页面上

jsx是调用React.createElement生成react节点

这个语法转换是babel完成转换的

因为在书写react代码的时候,组件层级节点组织关系已经确定了,所以在后面生成dom tree的时候整棵树的构建过程是很自然的,因为每个节点它有哪些兄弟节点,以及有哪些children(通过attributes传到createElement函数里面的)节点相当于都是在写代码的时候就绑定好的

组件在生成的时候就是检测节点类型nodeName,然后创建相应的dom节点,append到父元素里面 同时会把生成的这个dom元素记录下来,因为后面diff的时候会用到,diff时候会判断同一位置节点是否还相同,如果不同则可能会发生insert move remove这几种操作

组件创建过程中,react会检测是否定义componentWillMount等方法,然后手动调用一次

组件创建完毕之后,会调用flushMounts,flushMouns里面会检测一个数组items,items里面存储的是渲染完毕的组件,所以可以一次把数组元素pop出来,调用其componentDidMount方法

组件调用setState之后会直接调用renderComponent方法,进入渲染流程,而不是按照平时的理解会先进入render方法,虽然感觉一定有地方调用的render函数

组件在更新的时候也会先对当前状态state、context、prevState、prevContext进行整合,然后作为参数手动调用shouldComponentWillUpdate、componentWillUpdate等方法

组件更新的时候会先对现存的节点进行收集,然后和新节点进行比较;如果有前后两个元素的key相同,那么会把这两个元素单独进行比对

组件更新的时候最后会调用recollectTree对不需要渲染的节点在virtual dom和页面上的dom进行移除

组件在渲染过程中有一个变量来记录渲染树的层次深度,向下渲染时候层次会加,回溯的时候层次会减,最后为0的时候也会调用一次flushMounts

flushMounts里面持有的items数组不可能是一直包含所有的组件,应该是只有在当前层加载的元素

不同于平时理解的preact setState是同步的,preact的setState也是异步的,要么是调用自定义的defer函数,要么是使用内部自定义的 Promise.then、setImediate、setTimeout(默认参数是0)

react既对元素作了处理,也对元素里面的文本节点作了处理

对于元素而言,其包含的文本就相当于其子节点(文本节点)比如:React.createElement(‘p’, {class: ‘record’}, ‘this is a record’);// 第三个参数是children

疑问: 1、组件更新的时候render方法是在哪里调用的 2、组件渲染的时候父元素的dom是怎么得到的 3、组件更新的时候state在哪里进行合并的 4、如果一个组件进行多次setState会出现什么情况 5、渲染树的层次渲染和更新过程是怎样的,就是如何一级一级进行深入的 6、react是如何帮元素绑定事件的 7、什么时候会给dom元素添加属性_component