早些年的设计是将JSX翻译成React.createElement,然后生成一个Vnode实例,然后在ReactDOM.render的扫描过程中,根据其type, props生成它的updater与stateNode(可能是实例也可能是真实DOM),这两个东西都是放在vnode中的。然后问题来了,每次更新是产生新的vnode,新旧vnode进行比较,然后再将这些updater与stateNode搬到新的vnode上。
<JSX> --> React.createElement -- > vnode --> vnode.updater + vnode.stateNode
新的设计是这样的,当我们生成vnode后,在ReactDOM.render的扫描过程中,同样生成updater与stateNode, 并且现在连文本节点也有updater(fiber), 然后把vnode与stateNode放在updater中,updater(fiber)上面还有children,用于放置vnode的孩子的updater(fiber)。vnode不再存放updater(fiber)与stateNode的引用。在更新时,是通过 新vnode与updater.vnode进行比较。此外还要想办法,弄一个对象池,重复利用updater.
总结一句,旧的架构是 新旧vnode进行diff,然后更新真实DOM,现在是fiber与新vnode进行diff,然后更新真实DOM。目的是减少diff时属性或对象的修改
属性名改成与官方的一致,还可以直接使用官方的许多工具,好处多多
https://github.com/RubyLouvre/anu/tree/scout
早些年的设计是将JSX翻译成React.createElement,然后生成一个Vnode实例,然后在ReactDOM.render的扫描过程中,根据其type, props生成它的updater与stateNode(可能是实例也可能是真实DOM),这两个东西都是放在vnode中的。然后问题来了,每次更新是产生新的vnode,新旧vnode进行比较,然后再将这些updater与stateNode搬到新的vnode上。
新的设计是这样的,当我们生成vnode后,在ReactDOM.render的扫描过程中,同样生成updater与stateNode, 并且现在连文本节点也有updater(fiber), 然后把vnode与stateNode放在updater中,updater(fiber)上面还有children,用于放置vnode的孩子的updater(fiber)。vnode不再存放updater(fiber)与stateNode的引用。在更新时,是通过 新vnode与updater.vnode进行比较。此外还要想办法,弄一个对象池,重复利用updater.
总结一句,旧的架构是 新旧vnode进行diff,然后更新真实DOM,现在是fiber与新vnode进行diff,然后更新真实DOM。目的是减少diff时属性或对象的修改
属性名改成与官方的一致,还可以直接使用官方的许多工具,好处多多
https://github.com/RubyLouvre/anu/tree/scout