本文开始,我们将用几篇文章记录下,我们的my_react的实现逻辑。类似于vue的学习过程,我们将尝试手写react的重要组成部分,以便更为彻底的理解其底层实现。
涉及的内容包括:createElement、render、cocurrent mode、fiber、render commit、reconcilliation及function components。

文本介绍createElement和render

先看看react的使用

const content = React.createElement(
    'div',
    {
    title: 'title',
    id: 'id',
    },
    '川崎重工'
)
console.log('content>>>', content)
const root = ReactDOM.createRoot(
    document.getElementById('root')
);
root.render(content)

从上面代码不难看出,通过调用createElement,会生成一种dom的数据结构,具体长啥样根据入参决定。这一块的内容我们之前在介绍vue底层时有提到过,他们都是根基于一个库snabbdom.就是通过结构化的数据, 去描述dom节点。然后做的事情就是render, 将结构化的数据转换成真实的dom,挂载到页面中去。具体长这样:

效果:

了解了其所做的事情,那么接下来,我们来diy实现之

createElement实现很简单,根据入参,生成一个对象并返回,这个对象我们称之为虚拟dom

const createTextNode = (child) => {
  return {
    type: 'text',
    props: {
      nodeValue: child,
      children: []
      
    }
  }
}
const myCreateElement = (type, props, ...children) => {
  return {
    type: type,
    props: {
      ...props,
      children: children.map((child) => typeof child === 'object'? child: createTextNode(child))
    },
  }
}
const VNode = myCreateElement(
  'div',
  {
    title: 'title',
    id: 'id'
  },
  '一段文本....川崎重工'
)
console.log(VNode)

render

const myRender = (element, container) => {
  const dom = element.type === 'text'? document.createTextNode(element.props.nodeValue): document.createElement(element.type)
  Object.keys(element.props).filter((item) => item !== 'children').forEach((item) => dom[item] = element.props[item])
  element?.props?.children?.forEach((child) => myRender(child, dom))
  container.appendChild(dom)
}

效果如下:

文毕。