react 核心方法:
1、react 核心API (createElement, Component,ReactDom)
2、setState核心
3、diff算法
当然本文先对createElement进行解析,文章持续更新中
一 、createElement
react 官网地址:https://reactjs.org/
首先我们需要去官网看下,认识一下在线解析。
勾选前的样子
官网一个简单的例子,右上角有一个勾选项,取消勾选后会显示如下:
取消勾选后的样子
我们可以发现,jsx帮我们做了一些事情,使得我们写法更简单了
render() {
return (
<div>
Hello {this.props.name}
</div>
);
}
转成了
render() {
return React.createElement(
"div",
null,
"Hello ",
this.props.name
);
}
并且用 React.createElement() 这个方法去创建render可以渲染的东西(我们称它为vdom, 虚拟dom)
createElement()参数有:
//React.createElement(type,props,[...children]);
render() {
return React.createElement(
"div",//标签名字
null,//div的属性如className等
"Hello ",//子元素的内容
this.props.name //子元素的属性
);
}
如果有很多子元素的话,会多次使用createElement 来创建,type 分为:
div,也就是浏览器可以识别的类型
hello:是纯文本标签类型,如果是纯文本,其实是没有type的。
对于createElement来说,不同的标签会创建不同的内容:
class HelloMessage extends React.Component {
render() {
return (
<div>
Hello {this.props.name}
<div> haha </div>
<MyComp> haha </MyComp>//自定义类组件
</div>
);
}
}
ReactDOM.render(
<HelloMessage name="Taylor" />,
document.getElementById('hello-example')
);
会被转成如下代码:
class HelloMessage extends React.Component {
render() {
return React.createElement(
"div",
null,
"Hello ",
this.props.name,
React.createElement(//子div
"div",
null,
"haha"
),
React.createElement(//自定义组件MyComp
MyComp,//自定义组件类型
null,//属性
"haha"//child:纯文本标签
)
);
}
}
ReactDOM.render(React.createElement(HelloMessage, { name: "Taylor" }), document.getElementById('hello-example'));
通过createElement把这么一系列的嵌套的标签,转成虚拟dom(vdom,就是一堆js对象),然后通过render对这些对象的解析,来渲染到浏览器上。
问题:
1、虚拟dom是什么 (vdom)
用来描述我们dom结构的js对象。
你肯定会有疑问,为什么我们需要使用jsx,为什么不直接通过createElement来写代码呢?
答案:其实是可以的,但是你觉得哪个写起来更方便?当然是
<div>haha</div>
这样方便了,不然每次你都 createElement ,写起来很麻烦,而且很容易出错,不严谨,jsx通过编译器的校验,帮我们快速的找出语法错误。
二、createElement简易源码解析
接下来我们来看下源码,createElement里面到底实现了哪些功能,下面代码是通过过滤筛选的简易的源码,避免看晕了。我加了一些注释便于理解。
import {
VELEMENT,
VSTATELESS,
VCOMPONENT
} from './constant'
import { createVnode } from './virtual-dom'//创建虚拟节点需要
export default function createElement(type, props, ...children) {
let vtype = null;//虚拟type,需要手动去判断标签的类型,上面说过,有纯文本类型,自定义组件类型等
if (typeof type === 'string') {//类似div这种标签,type是字符串
vtype = VELEMENT
} else if (typeof type === 'function') {//函数组件,我们自定义的组件都是函数类型的,别问我为什么,我也不好说,请看【类组件&&函数组件】 图。
if (type && type.isReactComponent) {//通过react创建出来的自定义组件都会给它加上一个isReactComponent,意味着是类组件
vtype = VCOMPONENT //类组件
} else {
vtype = VSTATELESS //函数组件
}
} else {
throw new Error(`React.createElement: unexpect type [ ${type} ]`)
}
let key = null
let ref = null
let finalProps = {}
if (props != null) {
for (let propKey in props) {
if (!props.hasOwnProperty(propKey)) {
continue
}
if (propKey === 'key') {
if (props.key !== undefined) {
key = '' + props.key
}
} else if (propKey === 'ref') {
if (props.ref !== undefined) {
ref = props.ref
}
} else {
finalProps[propKey] = props[propKey]
}
}
}
finalProps.children = children //赋值子类
return createVnode(vtype, type, finalProps, key, ref) //开始创建虚拟节点(先创建虚拟节点,创建完了以后,通过render绘制到页面上,是这么一个流程)
}
类组件&&函数组件
上图解释为啥类组件都是function。
欢迎大家关注我的公众号一起讨论交流。
本文暂时没有评论,来添加一个吧(●'◡'●)