React学习(一)—— jsx与虚拟dom渲染
tips:自建demo实现react
一、react使用
一个简单的react项目渲染,初始时会有以下几部分内容:
import React from './react'; // react api
import ReactDOM from 'react-dom'; // react 渲染dom的方法
const ele = ( // jsx
<div >
<h3 className="title"> hello, react</h3>
</div>
)
ReactDOM.render(
element,
document.getElementById('root')
);
// render 方法接收两个参数,一个是虚拟dom一个是容器
二、jsx语法
上边创建的ele变量就是一个jsx对象,bable会对其进行编译
bable在线编译工具:https://www.babeljs.cn/repl
ele在bable编译后为:
React.createElement("div", null,
React.createElement("h3", {
className: "title"
}, " hello, react")
);
// 由此createElement方法接收3个参数,createElement(标签,属性,children)
三、react 创建虚拟dom(即createElement方法)
function createElement (type, attrs, ...children) {
// 删除不必要的属性
delete attrs._self;
delete attrs._source;
// 将 创建的react元素返回
return {type, attrs, children}
}
打印编译后的ele
四、react虚拟dom渲染(render函数)
render(vnode,container)
render方法中主要做了一件事:对vnode进行校验
具体看代码:
function render (vnode, container) {
if (vnode === undefined) return
// 如果vnode是字符串
if (typeof vnode === 'string') {
// 创建文本节点,将文本内容加入
const textNode = document.createTextNode(vnode)
return container.appendChild(textNode)
}
// 虚拟node对象;
const {tag, attrs} = vnode;
// 创建节点对象
const dom = document.createElement(tag);
if(attrs) {
// 有属性时, 给dom设置对应的属性
Object.keys(attrs).forEach(key => {
const value = attrs[key];
setAttribute(dom, key, value)
})
}
// 递归渲染子节点
vnode.childrens.forEach(child => {
render(child, dom)
})
return container.appendChild(dom)
}
总而言之,就是将虚拟dom对象转为真实dom节点,并添加到页面上
源码中,React.createElement 、 createElementWithValidation 、 createElement 、 ReactElement,通过这些方法,我们用class声明的React组件在变成真实dom之前都是ReactElement类型的js对象
demo:https://github.com/wkh1234/react-vdom