一、组件
组件可以将UI切分成一些独立的、可复用的部件,这样我们就只需要专注于每个单独的部件开发。组件的概念类似于
JS函数
,它接受任意的入参(即 “props”),并返回用于描述页面展示内容的 React 元素。
二、React组件
2.1 函数组件
函数式组件就是通过编写
JavaScript
函数来定义的组件,通过接受一个props对象
并返回一个React元素
来实现组件。
function Welcome(props){
return <h1>Hello,{props.name}</h1>
}
// <Welcome name='Tom'></Welcome>
2.2 类组件
类组件是通过
ES6
的class
来定义的组件,类组件相较于函数组件有一些额外的特性,这个我们会在下节组件更新中详细介绍。
class Welcome extends React.Component {
render(){
return <h1>Hello,{this.props.name}</h1>
}
}
这两个组件初渲染的结果是等价的
三、组件的初渲染原理
React中组件分为两类,一类是内置的原生组件,像div、p、span这些原生组件的
type
是字符串,第二类是自定义组件,他的type
类型是一个函数
3.1 函数组件
函数组件编译后结果
$$typeof: Symbol(react.element)
代表这个JSX
是个组件- 传入的
name
会被挂在props
上type
属性的值是一个函数
3.2 类组件
- 类组件需要注意的是,
type
的原型上isReactComponent
属性使用来标识该元素是否为类组件
3.3 组件初渲染原理
// 接着上一篇文章,修改createDOM代码
function createDOM(vdom){
let {type,props} = vdom;
let dom;
if(type === REACT_TEXT){
dom = document.createTextNode(props.content);
}else if(typeof type === 'function'){ // 组件
if(type.isReactComponent){ // 类组件
return mountClassComponent(vdom);
}else{ // 函数组件
return mountFunctionComponent(vdom);
}
}else{
dom = document.createElement(props.content);
}
if(props){
updateProps(dom,{},props);
if(typeof props.children == 'object' && props.children.type){
render(props.children,dom)
}else if(Array.isArray(props.children)){
reconcileChildren(props.children,dom)
}
}
vdom.dom = dom
return dom
}
3.4 函数组件的挂载
函数组件的挂载原理就是将
type
执行得到的vdom
传入到createDOM
中生成真实DOM
function mountFunctionComponent(vdom){
const [type,props] = vdom;
const renderVdom = type(props);
return createDOM(renderVdom);
}
3.5 类组件的挂载
类组件的父类
Component
的原型上有一个属性isReactComponent
值是一个空对象
3.5.1 Component
类
Component.js
实现简易Component
类
export class Component {
static isReactComponent = {} // 用于标识类组件
constructor(props){
this.props = props
}
}
3.5.2 挂载类组件
类组件的挂载原理,先通过
new type
得到类的实例,在调用实例的render
方法生成vdom,最后将得到的vdom
传入到createDOM
中生成真实DOM
function mountClassComponent(vdom){
const [type,props] = vdom;
const classInstance = new type(props);
const renderVdom = classInstance.render(renderVdom);
return renderVdom
}