JSX => DOM
用过React的同学可能都有这样的感觉:
- 刚接触React:JSX是什么鬼 莫名其妙,又有点神奇
- 用React: JSX就JSX吧,老夫拿起来就是一把梭
React采用的JSX语法,书写方式和直接写HTML标签类似,但是从JSX到DOM,经历了哪些过程呢? 本文就带同(da)学(lao)们扒一扒其中的奥妙,实现一个最最最简版的React(对, 就是这么小, 因为我还没长大) 动手写代码之前,我们先理一理React的渲染流程:
1. babel
我们先把一段JSX代码通过babel编译下看看变成啥样: 打开babeljs.io/, try it out
我们看到babel将JSX编译成了React.createElement()方法。createElement接收三个参数
- type 标签名
- props 属性
- children 子节点
等等,React.createElement又是啥, 没用过啊::dizzy_face:
2. Virtual DOM
没用过没关系,我们来看看他是个啥,在React环境下执行以下代码:
React.createElement(
"h1",
{ titile: "\u5C0F\u59D0\u59D0\u597D" },
"hello, little sister"
);
复制代码
按照以上思路, 实现React.createElement, ReactDOM.render方法:
const React = {
createElement: function (type, props, ...children) {
return {type, props, children}
}
}
const ReactDOM = {
render: function (vnode, container) {
let {type, props, children} = vnode;
let node = document.createElement(type)
for(let key in props) {
node.setAttribute(key, props[key])
}
children.forEach(child => {
if(typeof child === 'string'){
node.innerHTML = child
} else {
ReactDOM.render(child, node)
}
})
container.appendChild(node);
}
}
ReactDOM.render(<h1 title="hello">world<span>123</span></h1>, document.getElementById('root'));
复制代码