React源码解析之React.createElement()
2019-10-17 本文已影响0人
y先生_f18f
在第一次学习react的时候,我们总会带着许多疑问。比如我们看到下面的代码就会想:为什么我们只是引入了React,但是并没有明显的看到我们在其他地方用,这时我们就会想着既然没有用到,那如果删除之后会不会受到影响呢?答案当然是不行的。
import React from 'react';
import ReactDOM from 'react-dom';
let element = (
<h1 id="title" className="bg" style={{color: 'red'}}>
hello
<span>world</span>
</h1>
)
console.log({type: element.type, props:element.props})
ReactDOM.render(element,document.getElementById('root'));
当我们带着这个问题去研究的时候会发现其实在渲染element的时候调了React.createElement(),所以上面的问题就在这里找到了答案。
那么React.createElement()到底干了些什么事情呢?
- 我们看一看下面的代码
<h1 id="title" className="bg" style={{color: 'red'}}>
hello
<span>world</span>
</h1>
//上面的这段代码很简单,但是我们都知道react是所谓的虚拟dom,当然不可能就是我们看到的这样。当我们将上面的代码经过babel转译后,我们再看看
React.createElement("h1", {
id: "title",
className: "bg",
style: {
color: 'red'
}
}, "hello", React.createElement("span", null, "world"));
- 那到底React.createElement干了些什么呢?
//方法接受三个参数,第一个参数是组件类型,第二个参数是要传递给组件的属性,第三个参数是children。方法最终会返回一个具有以下属性的对象
function createElement(type,config,children){
let propName;
const props = {};
for(propName in config){
props[propName] = config[propName]
}
const childrenLength = arguments.length - 2; //减掉type config 看看后面还有几个儿子
if(childrenLength === 1){
props.children = children;
}else if(childrenLength > 1){ //如果说儿子的数量大于1的话,props.children就是一个数组
props.children = Array.from(arguments).slice(2)
}
return {type,props}
}
export default {
createElement
}
/**
React.createElement("h1", {
id: "title",
className: "bg",
style: {
color: 'red'
}
}, "hello", React.createElement("span", null, "world"));
*/
最后我们看到React通过createElement方法将组件或者元素转成ReactElement,并最终通过一系列操作渲染到页面成为HTMLElement。