React 源码阅读入门1(JSX与Component)

react

基本信息

React的github地址 可选择分支对应的版本进行克隆。此处使用当前的master分支既v16.12.0进行学习。

项目目录结构如下,最重要的react与react-dom源码,位于package文件夹下对应目录的src文件夹中。

react源码的目录结构

react/src/React.js

创建React对象,该对象包括我们平时开发中常用的react api,例如Component组件、hooks方法等。

注:react的源码有使用flow进行静态代码检查,类似ts,导致部分js文件编辑器会报错。这里我尝试下载flow相关的vscode插件后仍然提示类型错误,只好暂时将vscode的javascript.validate.enable配置项关闭。


React.createElement与JSX

JSX是react的特色之一,其标准已由JavaScript内部实现,在react中用于描述用户界面,语法类似HTML。

在js/jsx/tsx文件中,使用JSX语法但没有导入react对象时,编辑器会给出这样的提示,既在使用JSX时必须导入react对象,原因就是JSX语法的转换必须依赖于React.createElement方法。

编译时,JSX会被babel-loader进行处理,编译为普通的js代码,例如: ( 在线转换JSX )

可以看出,JSX本质是JavaScript,React.createElement会返回一个元素节点,调用形式为: React.createElement(标签名, 标签属性, …子节点),从第三个参数到最后一个参数都为子节点,每个子节点也是由React.createElement创建或为字符串。

这也就是使用JSX语法必须导入React的原因。也可以看出,在JSX中之所以使用className而不是class指定标签的类名,是因为在JSX本质为JavaScript代码,JavaScript中class是创建类的关键字。


回到源码,可以看到导出的createELement方法如下。前一种createElementWithValidation也是调用createElement方法,只是在开发环境下会多一些验证与提示。(代码中出现__DEV__的判断时,都是React给开发者在本地环境下的提示,如某些API即将废弃、传参出错等)

进入createElement的源码,看到这里先预定义了一部分变量,如用于vdom渲染的key、节点引用ref、组件的props等。

先进行ref与key两个属性的获取(验证是否为undefined),再将config对象的其他属性添加到props对象中。

其中在向props对象添加属性时,会排除RESERVED_PROPS对象上存在的属性(key, ref, self, source)。

进行props.children的处理,也就是当前节点的子节点,会根据参数长度进行转化。

这也是我们在使用react时,在props上某些键是不能用于传递的,例如key、ref、children。

默认props的赋值。

最终返回ReactElement对象。

进入ReactElement函数,该函数返回一个对象,其中 typeof 属性为REACT_ELEMENT_TYPE,这里比较重要,也就是说所有由React.createElement创建的对象的 typeof 属性都为该常量。

其中 element.type 为createElement调用时,传入的第一个参数。若JSX代码中节点为普通HTML标签,这里则是标签字符串(“div”);若节点为组件,这里的type就是组件对象。


Component与PureComponent

类组件是过去React中最常用的组件,通过创建继承Component的类来实现。

打开 src/ReactBaseClasses.js 文件,看到Component类的定义

Component实例的setState与forceUpdate方法的定义。

setState第一个参数可以接收需要更新的state对象,或是一个函数;第二个参数接收更新后的回调函数。将参数传递给updater的enqueueState方法。

forceUpdate则为强制更新当前组件。

PureComponent用于渲染性能优化。与React.memo类似,在更新之前进行一层浅比较,之后再决定是否需要更新。

PureComponent类的定义,可以看出与Component类几乎相同,通过寄生继承方式,继承了Component上原型链的方法。

最大的不同之处在于,pureComponentProptype上的isPureReactComponent属性被标记为true。

在React中,并不关心具体的页面渲染与更新操作,渲染操作由对应的平台的库来进行,如react-dom、react-native,React只负责基础逻辑。

以上是 React 源码阅读入门1(JSX与Component) 的全部内容, 来源链接: utcz.com/z/383732.html

回到顶部