react에서PureComponent에 대한 깊은 인식

31221 단어 js 전단reactes6
react 최적화에 대해 말하자면 가장 중요한 구성 요소는 바로PureComponent이다. 주요한 특징은 데이터가 심층적인 변화가 발생하더라도PureComponent는 업데이트되지 않고 하위 구성 요소에 영향을 주지 않는다는 것이다.그럼PureComponent와Component의 관계는 어디에 있습니까? 다음은react 프레임워크 코드에 대한 이해입니다.
하나, 모두 React에서.js에서 노출, 이번 상관없는 코드 많이 삭제
import {Component, PureComponent} from './ReactBaseClasses';


const React = {
  Children: {
    map,
    forEach,
    count,
    toArray,
    only,
  },

  createRef,
  Component,
  PureComponent,

 
};


export default React;

Component는 모두 ReactBaseClasses에서 나온 것입니다.js, 이렇게 하면 재미있어요.Pure Component는 사실 Component에서 물려받은 것입니다. Component Dummy는 개인적으로 Component 복제품으로 이해됩니다.
function Component(props, context, updater) {
  this.props = props;
  this.context = context;
  this.refs = emptyObject;
  this.updater = updater || ReactNoopUpdateQueue;
}

Component.prototype.isReactComponent = {};
//          setSate
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.',
  );
  //       setState   ,updater        
  this.updater.enqueueSetState(this, partialState, callback, 'setState');
};

//      
Component.prototype.forceUpdate = function(callback) {
  this.updater.enqueueForceUpdate(this, callback, 'forceUpdate');
};
//        Component,       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;
}
// PureComponent     ,   Component
const pureComponentPrototype = (PureComponent.prototype = new ComponentDummy());
pureComponentPrototype.constructor = PureComponent;
// assign     Component     PureComponent
Object.assign(pureComponentPrototype, Component.prototype);
//      PureComponent   Component          isPureReactComponent  = true
pureComponentPrototype.isPureReactComponent = true;

export {Component, PureComponent};

2. 어떻게 발생했는지 얕게 비교한다. 1. 우리는 다시 React로 돌아간다.js 파일에 React 포함 방법
import {
  createElement,
  createFactory,
  cloneElement,
  isValidElement,
} from './ReactElement';
const React = {
  createElement: __DEV__ ? createElementWithValidation : createElement,
  cloneElement: __DEV__ ? cloneElementWithValidation : cloneElement,
  createFactory: __DEV__ ? createFactoryWithValidation : createFactory,
 }

2. React Elemene에서.js에서createElement을 통해 Element을 만듭니다
import ReactCurrentOwner from './ReactCurrentOwner';

const ReactElement = function(type, key, ref, self, source, owner, props) {
  const element = {

    $$typeof: REACT_ELEMENT_TYPE,

    type: type,
    key: key,
    ref: ref,
    props: props,


    _owner: owner,
  };
  return element;
};

export function createElement(type, config, children) {
  let propName;

  const props = {};

  let key = null;
  let ref = null;
  let self = null;
  let source = null;

  if (config != null) {
    if (hasValidRef(config)) {
      ref = config.ref;
    }
    if (hasValidKey(config)) {
      key = '' + config.key;
    }

    self = config.__self === undefined ? null : config.__self;
    source = config.__source === undefined ? null : config.__source;
    // Remaining properties are added to a new props object
    for (propName in config) {
      if (
        hasOwnProperty.call(config, propName) &&
        !RESERVED_PROPS.hasOwnProperty(propName)
      ) {
        props[propName] = config[propName];
      }
    }
  }

  const childrenLength = arguments.length - 2;
  if (childrenLength === 1) {
    props.children = children;
  } else if (childrenLength > 1) {
    const childArray = Array(childrenLength);
    for (let i = 0; i < childrenLength; i++) {
      childArray[i] = arguments[i + 2];
    }
    props.children = childArray;
  }

  // Resolve default props
  if (type && type.defaultProps) {
    const defaultProps = type.defaultProps;
    for (propName in defaultProps) {
      if (props[propName] === undefined) {
        props[propName] = defaultProps[propName];
      }
    }
  }
  //        element     ReactCurrentOwner,      element
  return ReactElement(
    type,
    key,
    ref,
    self,
    source,
    ReactCurrentOwner.current,
    props,
  );
}

3. 여기를 보면 알 수 있듯이 생성된 요소가 Owner와 연관된 것은 하나의 Fiber 대상이고 전체 Fiber 모듈에서 그 중의 비교를 발견할 수 있다.
import type {Fiber} from 'react-reconciler/src/ReactFiber';

const ReactCurrentOwner = {
  /**
   * @internal
   * @type {ReactComponent}
   */
  current: (null: null | Fiber),
};

export default ReactCurrentOwner;

4、ReactFiberClassComponent이PureComponent인지 아닌지, 그중ctor가 사실은Component이다
function checkShouldComponentUpdate(
  workInProgress,
  ctor,
  oldProps,
  newProps,
  oldState,
  newState,
  nextContext,
) {
  const instance = workInProgress.stateNode;
  if (typeof instance.shouldComponentUpdate === 'function') {
    startPhaseTimer(workInProgress, 'shouldComponentUpdate');
    const shouldUpdate = instance.shouldComponentUpdate(
      newProps,
      newState,
      nextContext,
    );
    stopPhaseTimer();

   
    return shouldUpdate;
  }

  if (ctor.prototype && ctor.prototype.isPureReactComponent) {
    return (
      !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState)
    );
  }

  return true;
}

4. 파이버가 최종적으로 집행한 후에 나타난 것은 ReactDOM이다.react-reconciler와 연결하여ReactFiberBeginWork 모듈에서ReactFiberClassComponent를 호출하는 방법
function beginWork(
  current: Fiber | null,
  workInProgress: Fiber,
  renderExpirationTime: ExpirationTime,
): Fiber | null {
  const updateExpirationTime = workInProgress.expirationTime;

  // Before entering the begin phase, clear the expiration time.
  workInProgress.expirationTime = NoWork;

  switch (workInProgress.tag) {
	//      ,                  
	case IndeterminateComponent: {
    }
    //      
    case LazyComponent: {
    }
    //      
    case FunctionComponent: {
    }
    // class        
    case ClassComponent: {
      const Component = workInProgress.type;
      const unresolvedProps = workInProgress.pendingProps;
      const resolvedProps =
        workInProgress.elementType === Component
          ? unresolvedProps
          : resolveDefaultProps(Component, unresolvedProps);
      return updateClassComponent(
        current,
        workInProgress,
        Component,
        resolvedProps,
        renderExpirationTime,
      );
    }

  }

}

좋은 웹페이지 즐겨찾기