此文章源码解读版本 react16.6
作者:starkwang
欢迎关注订阅号:rd-hub
如需转载请标明作者和出处
开始
从一个最简单的jsx开始
import React from 'react';
import ReactDOM from 'react-dom';
ReactDOM.render(<h2 style={{ "color": "#53cde2" }}>hi stark wang</h2>, document.getElementById('root'));
bable 会转译成(编译原理会另有篇幅橡树)
import React from 'react';
import ReactDOM from 'react-dom';
ReactDOM.render(React.createElement(
'h2',
{ style: { "color": "#53cde2" } },
'hi stark wang'
), document.getElementById('root'));
编译 在这只勾选 一个react选项(为了保证阅读体验,编译后还是es6)
React.createElement
在此我们看到在ReactDOM.render()函数里面有两个参数,下面我们来看看React.createElement()源码
createElement() 源码如下:
分析 createElement()源码
function createElement(type, config, children) {
}
从函数来看,三个参数:type,config,children
参数 type
表示类型比如我们传入的是 <h2 style={{ "color": "#53cde2" }}>hi stark wang</h2>
此时的type就是 h2
为了增加文章的严谨,我专门在源码里面做了调试
参数 config
config 就是dom属性: style={{ "color": "#53cde2" }}
参数 children
children 就是我们在dom里面的内容了
把config的属性放在props上面
检查是否有ref 和 key 源码 (上面用到的源码)
function hasValidRef(config) {
{
if (hasOwnProperty.call(config, 'ref')) {
var getter = Object.getOwnPropertyDescriptor(config, 'ref').get;
if (getter && getter.isReactWarning) {
return false;
}
}
}
return config.ref !== undefined;
}
function hasValidKey(config) {
{
if (hasOwnProperty.call(config, 'key')) {
var getter = Object.getOwnPropertyDescriptor(config, 'key').get;
if (getter && getter.isReactWarning) {
return false;
}
}
}
return config.key !== undefined;
}
把dom里面的内容放在props上面
// 通过arguments 的长度来判断dom里面的内容
var childrenLength = arguments.length - 2; // 2 :代表默认的 type 和 config,减去就是 children了
if (childrenLength === 1) {
props.children = children;
} else if (childrenLength > 1) {
var childArray = Array(childrenLength);
for (var i = 0; i < childrenLength; i++) {
childArray[i] = arguments[i + 2];
}
{
if (Object.freeze) {
Object.freeze(childArray);
}
}
props.children = childArray;
}
如果dom属性内容为<h2>hi stark {shudong} {rdhub.cn} {starkwang}</h2>
则参数为 8个
默认有有两个,剩下都是 children 所以剩下有6个分别是
{shudong}
- ''
- {rdhub.cn}
- ''
- {starkwang}
每个变量中间的隔得内容都算一个参数
type.defaultProps 到 props
if (type && type.defaultProps) {
var defaultProps = type.defaultProps;
for (propName in defaultProps) {
if (props[propName] === undefined) {
props[propName] = defaultProps[propName];
}
}
}
返回一个构造函数 ReactElement
return ReactElement(type, key, ref, self, source, ReactCurrentOwner.current, props);
总结一下createElement()做了哪些事情
- 把 config里的内容拷入props
- 把 children 到 props.children
- 把 type.defaultProps 到 props
- 返回一个构造函数 ReactElement
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。