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 letPureComponent
inheritanceComponent
So 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)