内容简介:排版本小书的 React 版本是先说下 React16 这个版本节点吧。React16 较之前的版本是核心上的一次重写(想想就疯狂),虽然之前 API 没有变化继续使用,但同时也增加了很多好用的功能(不然不是白瞎了么)。这也是首次引入
排版本小书的 React 版本是 V16.8.6
。
先说下 React16 这个版本节点吧。
React16 较之前的版本是核心上的一次重写(想想就疯狂),虽然之前 API 没有变化继续使用,但同时也增加了很多好用的功能(不然不是白瞎了么)。这也是首次引入 Fiber
概念,之后新的功能都是围绕 Fiber
,比如 AsyncMode
和 Profiler
等。
说明:后面章节贴代码的部分,我都会删除原来英文注释,加上自己的理解,有问题的地方,还请在评论中指出(如果有评论的话,没有评论可以加我,有朋自远方来...)
上 V16.8.6
代码
看看截止目前为止,React 暴露出来的 API
// react-16.8.6/packages/react/index.js 'use strict'; const React = require('./src/React'); module.exports = React.default || React; // react-16.8.6/packages/react/src/React.js ... const React = { // packages/react/src/ReactChildren.js Children: { map, forEach, count, toArray, only, }, // packages/react/src/ReactCreateRef.js createRef, // packages/react/src/ReactBaseClasses.js Component, PureComponent, // packages/react/src/ReactContext.js createContext, // packages/react/src/forwardRef.js forwardRef, lazy, memo, // packages/react/src/ReactHooks.js useCallback, useContext, useEffect, useImperativeHandle, useDebugValue, useLayoutEffect, useMemo, useReducer, useRef, useState, // packages/shared/ReactSymbols.js Fragment: REACT_FRAGMENT_TYPE, StrictMode: REACT_STRICT_MODE_TYPE, Suspense: REACT_SUSPENSE_TYPE, // packages/react/src/ReactElementValidator.js createElement: __DEV__ ? createElementWithValidation : createElement, cloneElement: __DEV__ ? cloneElementWithValidation : cloneElement, createFactory: __DEV__ ? createFactoryWithValidation : createFactory, isValidElement: isValidElement, // packages/shared/ReactVersion.js version: ReactVersion, // packages/shared/ReactSymbols.js unstable_ConcurrentMode: REACT_CONCURRENT_MODE_TYPE, unstable_Profiler: REACT_PROFILER_TYPE, // packages/react/src/ReactSharedInternals.js __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: ReactSharedInternals, }; ... 复制代码
上面代码我们选择性的去解析,无需所有都要去了解(个人学习方法方式)。
先说 Children
这个对象提供了一些处理 props.children
方法, children
是一个类似数组但又不是数组的数据结构,对其进行处理时可用 React.Children
外挂方法。
createRef
新 ref
用法,不推荐使用 string ref
用法,比如 <div ref="divRef" />
。那正确姿势是怎样的呢?请看
class App extends React.Component { constructor() { this.ref = React.createRef(); } render() { return <div ref={this.ref} /> // or return <div ref={node => this.ref = node} /> } } 复制代码
Component
和 PureComponent
看 packages/react/src/ReactBaseClasses.js
代码
// Component function Component(props, context, updater) { this.props = props; this.context = context; this.refs = emptyObject; this.updater = updater || ReactNoopUpdateQueue; } Component.prototype.isReactComponent = {}; Component.prototype.setState = function(partialState, callback) {} Component.prototype.forceUpdate = function(callback) {} // ComponentDummy => Component仿制品 function ComponentDummy() {} ComponentDummy.prototype = Component.prototype; // PureComponent function PureComponent(props, context, updater) { this.props = props; this.context = context; this.refs = emptyObject; this.updater = updater || ReactNoopUpdateQueue; } const pureComponentPrototype = (PureComponent.prototype = new ComponentDummy()); pureComponentPrototype.constructor = PureComponent; Object.assign(pureComponentPrototype, Component.prototype); pureComponentPrototype.isPureReactComponent = true; // 多了一个标识 export { Component, PureComponent }; 复制代码
这两个类基本相同,唯一区别是 PureComponent
的原型上多了一个标识 isPureReactComponent
if (ComponentExample.prototype && ComponentExample.prototype.isPureReactComponent) { return ( !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState) ); } 复制代码
这是检查组件是否需要更新的一个判断, ComponentExample
是你声明的继承自 Component
或 PureComponent
的类,他会判断你是否继承自 PureComponent
,如果是的话就用 shallowEqual
比较 state
和 props
。
By the way(顺便说一下,允许我骚一下):React 中对比一个 ClassComponent
是否需要更新,只有两个地方。
一是看有没有 shouldComponentUpdate
方法;二就是这里的 PureComponent
判断;
createContext
createContext
是官方定稿的 context
方案,在这之前我们一直在用的老的 context API
,也是 React 不推荐的 API
。Now(现在),新的 API 出来了,官方也已经确定在 17 大版本会把老 API 去除。
新 API 的使用方法
const { Provider, Consumer } = React.createContext('defaultValue'); const ProviderComp = props => ( <Provider value='realValue'> {props.children} </Provider> ); const ConsumerComp = () => ( <Consumer> {value => <p>{value}</p>} </Consumer> ) 复制代码
具体差异,后面讲 context
环节会详细指出。
forwardRef
forwardRef
是用来解决 HOC 组件传递 ref
的问题的,所谓 HOC 就是 Higher Order Component
。就拿 redux
来说,使用 connect
来给组件绑定需要的 state
,这其中其实就是给我们的组件在外部包了一层组件,然后通过 ...props
的方式把外部的 props
传入到实际组件。 forwardRef
的使用方法如下:
const TargetComponent = React.forwordRef((props, ref) => { <TargetComponent ref={ref} {...props} /> }); 复制代码
这也说明了为什么要提供 createRef
作为新的 ref
使用方法的原因,如果用 string ref
就没法当作参数传递了。
后面章节会详细分析 ref
。
lazy
是用来实现异步加载模块的功能。
memo
是一个高阶函数,它与 React.PureComponent类似,但是一个函数组件而非一个类。
useXXX
系列
这就是 React16 的 Hooks 了,后续会做代码分解。
类型
Fragment: REACT_FRAGMENT_TYPE, StrictMode: REACT_STRICT_MODE_TYPE, Suspense: REACT_SUSPENSE_TYPE, unstable_ConcurrentMode: REACT_CONCURRENT_MODE_TYPE, unstable_Profiler: REACT_PROFILER_TYPE, 复制代码
这 5 个都是 React 提供的组件,但他们呢其实都只是 占位符
,都是一个 Symbol
,在 React 实际检测到他们的时候会做一些特殊的处理,比如 StrictMode
和 AsyncMode
会让他们的子节点对应的 Fiber 的 mode
都变成和他们一样的 mode
。
元素
createElement: __DEV__ ? createElementWithValidation : createElement, cloneElement: __DEV__ ? cloneElementWithValidation : cloneElement, createFactory: __DEV__ ? createFactoryWithValidation : createFactory, isValidElement: isValidElement, 复制代码
createElement
是 React 输出中最重要的 API 了,是用来创建 ReactElement
的,但是很多前端童鞋却从没见过,也没用过,这是为什么呢?这就得感谢 JSX 了,我们知道 JSX 并不是标准的 js,所以要经过编译才能变成可运行的 js,而编译之后, createElement
就出现了:
// jsx <div id="app">content</div> // js React.createElement('div', { id: 'app' }, 'content') 复制代码
cloneElement
它就很明显了,是用来克隆一个 ReactElement
的
createFactory
它是用来创建专门用来创建某一类 ReactElement
的工厂的
export function createFactory(type) { const factory = createElement.bind(null, type); factory.type = type; return factory; } 复制代码
其实就是绑定了第一个参数的 createElement
,一般我们用 JSX 进行编程的时候不会用到这个 API。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 浅析webpack源码之NodeEnvironmentPlugin模块总览(六)
- webpack系列之一总览
- JVM知识点总览
- 步步深入:MySQL架构总览
- Spring Cloud Eureka体系总览
- vivo 商城前端架构升级:总览篇
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。