React源码解析(三):react-component

论坛 期权论坛 编程之家     
选择匿名的用户   2021-5-30 09:13   11   0

在我们平时写一个类组件的时候,一般都会继承一个React.Component这个基类,我们可能会觉得,这个baseClass可能封装各种各样的功能(钩子函数等等),它帮助我们运行render函数,然后最终不是我们写在里面的dom标签、子组件之类的把它们都渲染到浏览器里的这种形式。但实际是这样的吗?答案是否定的。

在react当中不止有Component这一个baseClass, 它还有一个PureComponent这个baseClass, 它们俩唯一的区别就是PureComponent提供了一个shouldComponentUpdate简单的实现,在props没有变化的情况下减少不必要的更新。

我们先看看这个Component和PureComponent的实现源码:

/** 
* Copyright (c) Facebook, Inc. and its affiliates. 
* 
* This source code is licensed under the MIT license found in the 
* LICENSE file in the root directory of this source tree. 
*/

import invariant from 'shared/invariant';
import lowPriorityWarning from 'shared/lowPriorityWarning';
import ReactNoopUpdateQueue from './ReactNoopUpdateQueue';
const emptyObject = {};

if (__DEV__) {  Object.freeze(emptyObject);}
/** 
* Base class helpers for the updating state of a 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');
};

/** 
* 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 


分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛