createRoot初次渲染

442 阅读1分钟

react18将会用到ReactDOM.createRoot作为根函数渲染,render最作为兼容。

为什么用createroot?

render则是拿不到root,只能在开辟一个新的对象

let root = ReactDOM.createRoot(document.getElementById('root')) root.render(jsx) root.render(jsx2) 实现复用

创建一个react-dom.js文件

render拿到的children:

renderChild.jpg

其中 props属性,type,key是不是很眼熟? 这就是最原始的vnode(ReactFiber.js里crateFiber接收的参数)

拿到dom元素后开始生成filber,然后组件渲染

import {createFiber} from './ReactFiber'
import { scheduleUpdateOnFiber } from './ReactFilberWorkLoop';

/**
 *  @internalRoot 内部跟节点
*/
function ReactDOMRoot(internalRoot){
    this._internalRoot = internalRoot
}

/**
 * @children 子节点
*/

ReactDOMRoot.prototype.render = function(children){
    console.log('render-children',children);
    const root = this._internalRoot;
    updateContainer(children,root)
}

/**
 * @element 子节点,
 * @container 根节点,document.getElementById('root')
 * 初步渲染更新filber结构(先更新VDOM)
*/

function updateContainer(element,container){
    const {containerInfo} = container
    console.log('updateContainer-父节点:',containerInfo);
    console.dir(containerInfo);
        //父子节点的dom对象拿到了,生成fiber
    const filber = createFiber(element,{
        //父节点的filber
        type:containerInfo.nodeName.toLocaleLowerCase(),
        stateNode:containerInfo,
    })

    //组件渲染
    scheduleUpdateOnFiber(filber)
}

/**
 * @container 根节点,document.getElementById('root')
*/

function createRoot(container){
    const root = {containerInfo:container}
    return new ReactDOMRoot(root)
}

export default {
    createRoot,//懒汉式单件设计模式,返回唯一的ReactDOMRoot实例
}

在workloop.js中添加函数scheduleUpdateOnFiber,此函数用于初次渲染和更新,保存根节点。

let wip = null; //当前正在工作中的fiber
let wipRoot = null;
//初次渲染和更新
export function scheduleUpdateOnFiber(filber){
  wip = filber;
  //当所有fiber更新完之后,更新到根节点上,因此将初始的根节点保存
  wipRoot = filber;

}

现在该考虑如何更新节点了。怎么将performUnitOfWork跑起来