A, React.Com ponent ()

Making: github.com/AttackXiaoJ…

Usage:

class A extends React.Component {

  constructor(props){

    super(props)

    this.state={ }

  } 



  componentWillMount(){ }



  render() {

    return{}

  }  

}

Copy the code

Source:

/ * *

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

* /


// Base class to help update component state

function Component(props, context, updater{

  this.props = props;

  // I don't use context in my work.

  //https://www.cnblogs.com/mengff/p/9511419.html

  React encapsulates the global variable API

  this.context = context;

  // If a component has string refs, we will assign a different object later.

  If ref="stringa" is used in the component, use another obj assignment

  this.refs = emptyObject;

  // We initialize the default updater but the real one gets injected by the

  // renderer.

  // Although the updater is given a default value, the real updater is registered in renderer

  this.updater = updater || ReactNoopUpdateQueue;

}

// The prototype is assigned a flag

Component.prototype.isReactComponent = {};



/** Use setState to change variables inside Component



 * Sets a subset of the state. Always use this to mutate

 * state. You should treat `this.state` as immutable.



* This. state is not immediately updated, so you may not get the new value after calling this.setState



 * 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 this.state is synchronous (nor is it asynchronous), use the callback to get the latest 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

* /






// Update the Component internal variable API,

// Also a very common and important API for development



// https://www.jianshu.com/p/7ab07f8c954c

// https://www.jianshu.com/p/c19e259870a5



//partialState: The state to update, which can be Object/Function

/ / callback: setState (} {XXX, callback)

Component.prototype.setState = function(partialState, callback{

  // Check whether partialState in setState meets the condition.

  // If not, an Error is raised

  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.'.

  );

  / / important! Update mechanism for state

  // React-dom is implemented, not react

  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.

 *

* This method is used when there is a deep Component change but setState is not called

 *

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

 *

* forceUpdate does not call shouldComponentUpdate,

* But the componentWillUpdate and componentDidUpdate methods are called

 *

 * This will not invoke `shouldComponentUpdate`, but it will invoke

 * `componentWillUpdate` and `componentDidUpdate`.

 *

* @param {? function} callback Called after update is complete.

 * @final

 * @protected

* /


// Forces Component to update once, regardless of whether props/state is updated

Component.prototype.forceUpdate = function(callback{

  this.updater.enqueueForceUpdate(this, callback, 'forceUpdate');

};

Copy the code

(1) Component() is essentially a class:

class Component {

  constructor(props, context, updater){

    this.props = props

    this.context = context

    this.refs = emptyObject

    this.updater = updater || ReactNoopUpdateQueue

  }

}

Copy the code

(2) setState() is a Component prototype method that essentially calls enqueueSetState() in reactNoopUpdatequeue.js. EnqueueSetState () will be examined in a later article

(3) forceUpdate()

(4) REact.componentWillmount (); render();

React.Com ponent () involves only the props/context/refs/updater/isReactComponent/setState/forceUpdate, other are not your own.


Second, the PureComponent

Making: github.com/AttackXiaoJ…

PureComponent: What is PureComponent? (2018.9.4)

Reusable components: If a component’s rendering relies only on props and its own state passed in, and does not rely on any external data, that is, like a pure function, it will spit out (render) whatever is given to it. This component is the most reusable. Pure Component or Dumb Component.

Usage:

class A extends React.PureComponent 

  / / with React.Com ponent ()

}

Copy the code

Source:

function ComponentDummy({}



//ComponentDummy's stereotype inherits Component's stereotype

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;

}



//PureComponent inherits from Component. The following three lines inherit from Component



// Copy the Component method to pureComponentPrototype

// The reason for using ComponentDummy is to reduce memory usage by not instantiating a Component instance directly

const pureComponentPrototype = (PureComponent.prototype = new ComponentDummy());



//PureComponent.prototype.constructor = PureComponent

pureComponentPrototype.constructor = PureComponent;



// Avoid an extra prototype jump for these methods.

// Avoid another prototype chain lookup because PureComponent inherits from Component

// Add object.assign () to avoid additional searches for the prototype chain



// object. assign is a shallow copy,

// Copy all the methods on Component.prototype to pureComponent. prototype

// The pureComponent prototype

/ / details please refer to: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/assign

Object.assign(pureComponentPrototype, Component.prototype);



// The only difference is that the isPureReactComponent property is added to the prototype to indicate that the Component is a PureComponent

pureComponentPrototype.isPureReactComponent = true;



export {Component, PureComponent};

Copy the code

(1) Reduce memory consumption and reduce the number of prototype chain lookups

PureComponentPrototype = (pureComponent.prototype = new ComponentDummy()) const ComponentPrototype = (pureComponent.prototype = New ComponentDummy()) Purecomponent. prototype equals ComponentDummy instance

The purpose of this is:

Purecomponent. prototype inherits Component’s constructor, but PureComponent already has its own constructor. This will consume more memory.

So we create a New ComponentDummy that inherits only Component stereotypes, not Constructor, to save memory.


(2) pureComponentPrototype. Constructor = PureComponent

Prototype constructor equals itself, overriding Component. Prototype’s constructor (Component)

①, ② is to letPureComponentinheritanceComponentSo why write another sentenceObject.assign(pureComponentPrototype, Component.prototype)?


Make a shallow copy of all Component prototype properties

③ What do you think of it?

pureComponentPrototype.__proto__=== ComponentDummy.prototype //true

/ / that is

PureComponent.prototype.__proto__=== Component.prototype //true

Copy the code

So there’s one more layer of implicit prototype search, so to reduce the prototype chain search, I wrote

Object.assign(pureComponentPrototype.Component.prototype)

Copy the code

Purecomponent. prototype: pureComponent. prototype: pureComponent. prototype: __proto__


(2)pureComponentPrototype.isPureReactComponent = true

In ReactFiberClassComponent. Js, have the isPureReactComponent judgment:

  if (ctor.prototype && ctor.prototype.isPureReactComponent) {

    return (

! shallowEqual(oldProps, newProps)||! shallowEqual(oldState, newState)

    );

  }

Copy the code

Note :(important)

The React Component class shouldComponentUpdate () {shouldComponentUpdate ();

Ii is ReactFiberClassComponent. Js checkShouldComponentUpdate of (in) to PureComponent judgment

The only difference between PureComponent and Component: PureComponent comes with a simple shouldComponentUpdate to optimize the update mechanism.


(after)