内容简介:本小书大部分内容来自作者 Jokcy 的 《React 源码解析》:react.jokcy.me/本文已同步在我的博客:感谢 Jokcy 让我深度了解 React。就如他所说,在决定阅读 React 源码时认为不会是一件很难的事,但是真正开始阅读之后才发现,事情没那么简答,需要足够的耐心、独立思考和静下新来(因为你会碰到之前编码没有见过的写法和概念等等)。
本小书大部分内容来自作者 Jokcy 的 《React 源码解析》:react.jokcy.me/
本文已同步在我的博客: ruizhengyun.cn/blog/post/f…
感谢 Jokcy 让我深度了解 React。就如他所说,在决定阅读 React 源码时认为不会是一件很难的事,但是真正开始阅读之后才发现,事情没那么简答,需要足够的耐心、独立思考和静下新来(因为你会碰到之前编码没有见过的写法和概念等等)。
ReactElement.js
整体部分
// 保留的 props const RESERVED_PROPS = { key: true, ref: true, __self: true, __source: true, }; const ReactElement = function(type, key, ref, self, source, owner, props) { const element = { // 此标记允许我们将其唯一标识为React元素 $$typeof: REACT_ELEMENT_TYPE, // 属于元素的内置属性 type: type, key: key, ref: ref, props: props, // 记录负责创建此元素的组件。 _owner: owner, }; if (__DEV__) {/*...*/} return element; } export function createElement(type, config, children) { let propName; // Reserved names are extracted(提取保留名称) const props = {}; let key = null; let ref = null; let self = null; let source = null; if (config != null) { if (hasValidRef(config)) { ref = config.ref; } if (hasValidKey(config)) { key = '' + config.key; } self = config.__self === undefined ? null : config.__self; source = config.__source === undefined ? null : config.__source; // Remaining properties are added to a new props object for (propName in config) { if ( hasOwnProperty.call(config, propName) && !RESERVED_PROPS.hasOwnProperty(propName) ) { props[propName] = config[propName]; } } } const childrenLength = arguments.length - 2; if( childrenLength === 1) { props.children = children; } else { const childArray = Array(childrenLength); for (let i = 0; i < childrenLength; i++) { childArray[i] = arguments[i + 2]; } if (__DEV__) { /*...*/ } props.children = childArray; } return ReactElement( type, key, ref, self, source, ReactCurrentOwner.current, props ); } 复制代码
分析 createElement
函数
function createElement(type, config, children) {} 复制代码
-
该函数接收 3 个参数,分别是
type, config, children
; -
调用
ReactElement
,ReactElement
内部返回一个对象element
;
config
逻辑
if(config != null){ if(hasValidRef(config)) { ref = config.ref; } if(hasValidKey(config)){ key = '' + config.key; } self = config.__self === undefined ? null : config.__self; source = config.__source === undefined ? null : config.__source; // 剩余的属性将添加到新的 props 对象中 for (propName in config) { if(hasOwnProperty.call(config, propName) && !RESERVED_PROPS.hasOwnProperty(propName)) { props[propName] = config[propName]; } } } 复制代码
这段代码做了
-
对
ref
和key
做了验证(对于这种校验方法无需内部实现,保持干净,也便于阅读); -
遍历
config
把内建的几个属性(剔除原型链上的属性和规定要剔除的属性)丢到props
中去;
children
逻辑
const childrenLength = arguments.length - 2; if( childrenLength === 1) { props.children = children; } else { const childArray = Array(childrenLength); for (let i = 0; i < childrenLength; i++) { childArray[i] = arguments[i + 2]; } if (__DEV__) { /*...*/ } props.children = childArray; } 复制代码
第一行可以看出,取出第二个参数后的参数,然后判断长度是否 > 1
:
-
> 1
就代表有多个children
,这个时候props.children
会是一个数组, 所以后面在对props.children
进行遍历的时候需要注意它是否是数组 ,当然你也可以利用React.Children
中的 API,下文中也会对React.Children
中的 API 进行讲解; -
=== 1
就是一个对象;
返回值
const ReactElement = function(type, key, ref, self, source, owner, props) { const element = { // 此标记允许我们将其唯一标识为React元素 $$type: REACT_ELEMENT_TYPE, // 属于元素的内置属性 type: type, key: key, ref: ref, props: props, // 记录负责创建此元素的组件。 _owner: owner, }; if (__DEV__) {/*...*/} return element; } 复制代码
核心就是通过 $$type
来识别这是个 ReactElement
,后会看到很多类似的类型。
注意:通过 JSX 写的 <APP />
代表 ReactElement
, APP
代表 React Component (组件)。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- ReactNative源码解析-初识源码
- Spring源码系列:BeanDefinition源码解析
- Spring源码分析:AOP源码解析(下篇)
- Spring源码分析:AOP源码解析(上篇)
- 注册中心 Eureka 源码解析 —— EndPoint 与 解析器
- 新一代Json解析库Moshi源码解析
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
程序设计方法(中文版)
Matthias Fellisen / 黄林鹏、朱崇恺 / 人民邮电出版社 / 2003-12 / 49.00元
《程序设计方法》以Scheme语言为基础介绍计算和程序设计的一般理论和实践。《程序设计方法》由8个部分和7个独立的章节(第8、13、18、24、29、33、38章)组成。8个部分主要讨论程序设计,独立章节则介绍一些与程序设计和计算相关的话题。《程序设计方法》第1至第3部分介绍了基于数据驱动的程序设计基础。第4部分介绍了程序设计中的抽象问题。第5部分和第6部分是与递归及累积相关的内容。《程序设计方法......一起来看看 《程序设计方法(中文版)》 这本书的介绍吧!