在babel中, 勾上React, 输入如下代码:
let div = <div id="test">test <span> test</span><p>nihao</p></div>
然后右边就会输出:
"use strict";
var div = React.createElement(
"div",
{ id: "test" },
"test ",
React.createElement(
"span",
null,
" test"
),
React.createElement(
"p",
null,
"nihao"
)
);
那么react
在遇到这样的代码之后, 是会去找React
下的createElement
函数.
在react
中, 编写的jsx
代码, 就是React.createElement
的语法糖. 方便编写.
jsx => React.createElement => vNode => render
这就是react 的渲染流程.
在 react
环境下, 如果直接写入jsx
, 肯定是会被转换为上述格式的js
代码的.如果我们打印一下这个div
:
那么主要的属性也就是:
ref, type, props, key
那就可以简易的模拟一下:
const React = {
createElement(type, props, ...children){
return {
type,
props,
children
}
}
}
然后将div
的jsx
打印(react
环境会自己去找React.createElement
方法)
执行完毕就会扔出来这么个对象 => Vnode
虚拟dom都已经有了, render想来也不是什么难事
// react 的render
ReactDOM.render('<App />', document.getElementById('root'))
MyRender(vNode, container){
if(typeof vnode === 'string'){ // 文本直接添加进去
const text = document.createTextNode(vnode)
container.appendChild(text)
return
}
const {type, props, children } = vnode
const el = document.createElement(type)
for (let key in props){
// 将原有的属性添加上去
// 过滤掉原型上的属性
if(key.startsWith("__")){
continue
}
el.setAttribute(key, props[key])
}
children.forEach(item=>{
// 递归子元素
render(item, el)
})
container.appendChild(el)
}
MyRender(div, window.root) // document.getElementById('root')
image.png
image.png
网友评论