React源码 React.Component
function Component(props, context, updater) {
this.props = props;
this.context = context;
// If a component has string refs, we will assign a different object later.
this.refs = emptyObject;
// We initialize the default updater but the real one gets injected by the
// renderer.
this.updater = updater || ReactNoopUpdateQueue;
}
Component.prototype.isReactComponent = {};
/**
* Sets a subset of the state. Always use this to mutate
* state. You should treat `this.state` as immutable.
*
* There is no guarantee that `this.state` will be immediately updated, so
* accessing `this.state` after calling this method may return the old value.
*
* There is no guarantee that calls to `setState` will run synchronously,
* as they may eventually be batched together. You can provide an optional
* callback that will be executed when the call to setState is actually
* completed.
*
* When a function is provided to setState, it will be called at some point in
* the future (not synchronously). It will be called with the up to date
* component arguments (state, props, context). These values can be different
* from this.* because your function may be called after receiveProps but before
* shouldComponentUpdate, and this new state, props, and context will not yet be
* assigned to this.
*
* @param {object|function} partialState Next partial state or function to
* produce next partial state to be merged with current state.
* @param {?function} callback Called after state is updated.
* @final
* @protected
*/
Component.prototype.setState = function(partialState, callback) {
invariant(
typeof partialState === 'object' ||
typeof partialState === 'function' ||
partialState == null,
'setState(...): takes an object of state variables to update or a ' +
'function which returns an object of state variables.',
);
this.updater.enqueueSetState(this, partialState, callback, 'setState');
};
/**
* Forces an update. This should only be invoked when it is known with
* certainty that we are **not** in a DOM transaction.
*
* You may want to call this when you know that some deeper aspect of the
* component's state has changed but `setState` was not called.
*
* This will not invoke `shouldComponentUpdate`, but it will invoke
* `componentWillUpdate` and `componentDidUpdate`.
*
* @param {?function} callback Called after update is complete.
* @final
* @protected
*/
Component.prototype.forceUpdate = function(callback) {
this.updater.enqueueForceUpdate(this, callback, 'forceUpdate');
};
我们看到 Component 的 prototype 上面有个 isReactComponent ,他等于一个空对象。这个东西好像没有什么特别的用处,就先略过。
/**
* Deprecated APIs. These APIs used to exist on classic React classes but since
* we would like to deprecate them, we're not going to move them over to this
* modern base class. Instead, we define a getter that warns if it's accessed.
*/
if (__DEV__) {
const deprecatedAPIs = {
isMounted: [
'isMounted',
'Instead, make sure to clean up subscriptions and pending requests in ' +
'componentWillUnmount to prevent memory leaks.',
],
replaceState: [
'replaceState',
'Refactor your code to use setState instead (see ' +
'https://github.com/facebook/react/issues/3236).',
],
};
const defineDeprecationWarning = function(methodName, info) {
Object.defineProperty(Component.prototype, methodName, {
get: function() {
lowPriorityWarning(
false,
'%s(...) is deprecated in plain JavaScript React classes. %s',
info[0],
info[1],
);
return undefined;
},
});
};
for (const fnName in deprecatedAPIs) {
if (deprecatedAPIs.hasOwnProperty(fnName)) {
defineDeprecationWarning(fnName, deprecatedAPIs[fnName]);
}
}
}
function ComponentDummy() {}
ComponentDummy.prototype = Component.prototype;
/**
* Convenience component with default shallow equality check for sCU.
*/
function PureComponent(props, context, updater) {
this.props = props;
this.context = context;
// If a component has string refs, we will assign a different object later.
this.refs = emptyObject;
this.updater = updater || ReactNoopUpdateQueue;
}
const pureComponentPrototype = (PureComponent.prototype = new ComponentDummy());
pureComponentPrototype.constructor = PureComponent;
// Avoid an extra prototype jump for these methods.
Object.assign(pureComponentPrototype, Component.prototype);
pureComponentPrototype.isPureReactComponent = true;
那么 PureComponent 我们可以认为他是继承与 Componnet 。他们两个也没有什么可继承的东西,因为他们两接收的东西是一模一样的,都是 props, context, updater 。这里用 ComponentDummy 去实现了一个简单的类似于继承的方式。 PureComponent.prototype 去 new 了一个 ComponentDummy 。 ComponentDummy 是一个空类。 将 Component 的原型赋给了 ComponentDummy 的原型。然后又将 ComponentDummy 的原型 赋给了PureComponent 。pureComponentPrototype 的构造函数指向了 pureComponent 。实际这就是一个实现继承的过程。其实就是一模一样。唯一的区别就是上面加了一个 isPureReactComponent 。他通过这么一个属性来标识继承自这个类的组件,他是一个 PureReactComponent。然后在后续更新的过程当中。 React dom 他会主动的去判断他是不是一个 PureComponent 。然后根据 props 是否更新来判断这个这个组件是否需要更新。
React源码 React.Component的更多相关文章
- React源码 React ref
ref 的功能,在 react 当中.我们写了一个组件,在这个时候,我们的 render function 里面我们会渲染一系列的子组件或者 dom 节点,有时候我们会希望有这样的需求,就是我们要获取 ...
- React源码 React.Children
children是什么意思呢?就是我们拿到组件内部的props的时候,有props.children这么一个属性,大部分情况下,我们直接把 props.children 渲染到 JSX 里面就可以了. ...
- 读react源码准备
git源码地址:https://github.com/facebook/react react 里面就是 react源码 react里面的react文件夹就是react源码,react源码非常的少,总 ...
- React源码剖析系列 - 生命周期的管理艺术
目前,前端领域中 React 势头正盛,很少能够深入剖析内部实现机制和原理.本系列文章希望通过剖析 React 源码,理解其内部的实现原理,知其然更要知其所以然. 对于 React,其组件生命周期(C ...
- React源码解析:ReactElement
ReactElement算是React源码中比较简单的部分了,直接看源码: var ReactElement = function(type, key, ref, self, source, owne ...
- react 源码之setState
今天看了react源码,仅以记录. 1:monorepo (react 的代码管理方式) 与multirepo 相对. monorepo是单代码仓库, 是把所有相关项目都集中在一个代码仓库中,每个mo ...
- React 源码剖析系列 - 不可思议的 react diff
简单点的重复利用已有的dom和其他REACT性能快的原理. key的作用和虚拟节点 目前,前端领域中 React 势头正盛,使用者众多却少有能够深入剖析内部实现机制和原理. 本系列文章希望通过剖析 ...
- React 源码剖析系列 - 生命周期的管理艺术
目前,前端领域中 React 势头正盛,很少能够深入剖析内部实现机制和原理. 本系列文章 希望通过剖析 React 源码,理解其内部的实现原理,知其然更要知其所以然. 对于 React,其组件生命周期 ...
- React躬行记(16)——React源码分析
React可大致分为三部分:Core.Reconciler和Renderer,在阅读源码之前,首先需要搭建测试环境,为了方便起见,本文直接采用了网友搭建好的环境,React版本是16.8.6,与最新版 ...
随机推荐
- xcode: {} 花括号缩进一个空格
if (jsonDict.HasParseError()) { //前面总是有一个空格 CCLOG("GetParseError %d\n",jsonDict.GetParseEr ...
- Golang(四)正则表达式使用
0. 前言 最近用到了 regexp 包,下面整理下正则表达式相关用法 参考 基础知识 - Golang 中的正则表达式 和 Golang regexp包中的函数和方法 做了汇总 1. 正则表达式 1 ...
- 依赖注入之unity(winform方式)
依赖注入之unity(winform方式) 要讲unity就必须先了解DI和IOC及DIP,如下链接提供DI和IOC的基础:https://www.cnblogs.com/zlp520/p/12015 ...
- 在vue-cli中安装element
在vue-cli中安装elemnent-ui 的步骤 在安装vue-cli 的基础上进行安装 1.npm i element-ui -S 安装element-cli 安装之后会在项目中的node_mo ...
- [转帖]为什么HikariCP被号称为性能最好的Java数据库连接池,如何配置使用
为什么HikariCP被号称为性能最好的Java数据库连接池,如何配置使用 原创Clement-Xu 发布于2015-07-17 15:53:14 阅读数 57066 收藏 展开 HiKariCP是 ...
- FPGA成神之路
先占个坑,网上写的都太没有体系了,打算写一个从电路到语法,从软件使用到硬件调试,从IP核调用到时序分析的系列帖子,人就是太懒,想把自己这两年踩的坑分享一下,加油,特种兵
- Direct Buffer介绍
Direct Buffer 前言 上篇文章Buffer末尾中谈到堆内Buffer(Heap Buffer)和直接Buffer(Direct Buffer)的概念,但是却一笔带过,并未涉及其细节,这篇文 ...
- 关于Java链接c#的webapi的注意事项
最近写了一个关于ad域的项目,ad域我也是第一次接触,对ad域的总结我会晚一些时间写出来.在此我先总结一下关于Java调用c#的webapi的一个注意点. [HttpPost] public Dict ...
- JVM故障分析系列之四:jstack生成的Thread Dump日志线程状态
JVM故障分析系列之四:jstack生成的Thread Dump日志线程状态 2017年10月25日 Jet Ma JavaPlatform JVM故障分析系列系列文章 JVM故障分析系列之一: ...
- php 安装imap报错“configure: error: utf8_mime2text() has new signature”解决
环境:php官方docker镜像 php:7.2-apache 安装IMAP扩展模块执行命令:docker-php-ext-install imap 报错信息:configure: error: ut ...