- 作者:老汪软件技巧
- 发表时间:2024-11-05 00:02
- 浏览量:
可能有人问,为啥会突然讲这么基础的内容?原因是这样的,最近工作实在太忙,没有时间看更难理解的内容,所以我想回到开始的章节,整理一下基础内容,谁说基础内容就没有含金量?看完后,我还是有收获的
回答这个问题前,我们先来看下面这个问题:在老版本的 React 中,为什么写 JSX 的文件要默认引入 React?
比如:
import React from react
function Index(){return <div> hello,React div>}
因为 JSX 在被 Babel 编译后,JSX 标签结构会变成React.createElement 形式,所以需要引入React,防止找不到 React 引起报错。
了解React.createElement
前面讲到JSX语法里 闭合标签元素会被 React.createElement 处理,看一下这个 API 的用法。
React.createElement(
type,
[props],
[...children])
createElement 参数:举个例子:
<TextComponent />
<div>hello,worlddiv>
let us learn React!
上面的代码会被 Babel 先编译成:
React.createElement(
"div", null,
React.createElement(TextComponent, null),
React.createElement("div", null, "hello,world"),
"let us learn React!"
)
ReactElement 对象
由上述内容可知,ReactElement 对象是通过 React.createElement 创建出来的特殊对象。它大致长这个样子
const element = {
$$typeof: REACT_ELEMENT_TYPE, // Element 元素类型
type: type, // type 属性,证明是元素还是组件
key: key, // key属性
ref: ref, // ref属性
props: props, // props属性
...
};
createElement 原理揭秘
export function createElement(type, config, children) {
/* 初始化参数*/
const props = {};
let key = null,propName, ref = null, self = null, source = null;
if (config != null) { /* 处理ref */
if (hasValidRef(config)) {
ref = config.ref;
}
if (hasValidKey(config)) { /* 处理key */
key = '' + config.key;
}
for (propName in config) { /*处理props */
if (
hasOwnProperty.call(config, propName) &&
! RESERVED_PROPS.hasOwnProperty(propName))
{props[propName]= config[propName];}
}
}
/* 处理Children逻辑*/
const childrenLength = arguments.length - 2;
if (childrenLength === 1) { // 只有一个 Children 的情况
props.children = children;
} else if (childrenLength > 1) {
// 存在多个 Children 的情况
const childArray = Array(childrenLength);
for (let i = 0; i < childrenLength; i++) {
childArray[i]= arguments[i + 2];
}
props.children = childArray;
}
/* 省略处理 defaultProps */
return ReactElement(type,key,ref,self,source,
ReactCurrentOwner.current,props,);
}
createElement 做的事情大致可以分为:
初始化参数,比如 props、key、ref 等。单独处理 key 和 ref 属性,处理 props 里面的其他属性。形成 Children 结构的数组。通过 ReactElement 创建 Element 对象并返回。
const ReactElement = function(type, key, ref, self, source,
owner, props) {
const element = {
$$typeof: REACT_ELEMENT_TYPE,
type: type,
key: key,
ref: ref,
props: props,
_owner: owner,
};
/* 创建element对象*/
return element;
};
ReactElement 作为一个纯函数,做的事情很简单,就是根据传进来的参数,创建并返回一个 Element对象。
好了,相信看完这些,我们对JSX和 createElement 有了一些原理上的认知,这些应该都是后面学习fiber结构的基础,所以 温故知新都必不可少呢,下期见