>  기사  >  웹 프론트엔드  >  React와 Preact의 setState 차이점

React와 Preact의 setState 차이점

一个新手
一个新手원래의
2017-10-24 09:34:281943검색

Preact는 React의 더 나은 대안 중 하나입니다. 물론 크기가 작다는 장점이 있습니다. 이 글에서는 setState의 차이점을 소개합니다.

소스 코드 분석

먼저 React와 Preact의 setState 부분의 구체적인 구현을 분석해 보겠습니다.

(너무 길어서 게으르게 하고 싶으면 그냥 아래로 스크롤해서 결론을 읽어도 됨)

React

Key code:

setState stage:


// ReactUpdateQueue.jsenqueueSetState: function(publicInstance, partialState) {
  ...  var queue =
    internalInstance._pendingStateQueue ||
    (internalInstance._pendingStateQueue = []);
  queue.push(partialState);

  enqueueUpdate(internalInstance);}

React가 안 되는 걸 볼 수 있어요 setState 중 처리되는 모든 변경 사항은 구성 요소가 업데이트될 때 사용하기 위해 처리 상태 전용 대기열에 직접 배치됩니다.

업데이트 단계:


// ReactCompositeComponent.jsupdateComponent: function(
  transaction,
  prevParentElement,
  nextParentElement,
  prevUnmaskedContext,
  nextUnmaskedContext,) {
  var inst = this._instance;
  ...  var willReceive = false;
  var nextContext;

  if (this._context === nextUnmaskedContext) {
    nextContext = inst.context;
  } else {
    nextContext = this._processContext(nextUnmaskedContext);
    willReceive = true;
  }

  var prevProps = prevParentElement.props;
  var nextProps = nextParentElement.props;

  if (prevParentElement !== nextParentElement) {
    willReceive = true;
  }

  if (willReceive && inst.componentWillReceiveProps) {
    ...    inst.componentWillReceiveProps(nextProps, nextContext);
  }
  
  // 在此处才计算 nextState
  var nextState = this._processPendingState(nextProps, nextContext); // 此处传入了 nextProps
  var shouldUpdate = true;

  if (!this._pendingForceUpdate) {
    if (inst.shouldComponentUpdate) {
      ...
      shouldUpdate = inst.shouldComponentUpdate(
        nextProps,
        nextState,
        nextContext,
      );
    } else {
      if (this._compositeType === CompositeTypes.PureClass) { // 敲黑板,知识点 —— 如果你的组件没实现shouldComponentUpdate,那么把React.Component 换成 React.PureComponent 可以获得基础版优化,提高性能。
        shouldUpdate =
          !shallowEqual(prevProps, nextProps) ||
          !shallowEqual(inst.state, nextState); // 浅比较,可以抄去自己改成属性黑/白名单版
      }
    }
  }
  ...}// ReactCompositeComponent.js_processPendingState: function(props, context) { // props: nextProps
  var inst = this._instance;
  var queue = this._pendingStateQueue;
  var replace = this._pendingReplaceState;
  this._pendingReplaceState = false;
  this._pendingStateQueue = null;

  if (!queue) {
    return inst.state;
  }

  if (replace && queue.length === 1) {
    return queue[0];
  }

  var nextState = Object.assign({}, replace ? queue[0] : inst.state);
  for (var i = replace ? 1 : 0; i < queue.length; i++) {
    var partial = queue[i];
    Object.assign(
      nextState,
      typeof partial === &#39;function&#39;
        ? partial.call(inst, nextState, props, context) // nextProps
        : partial,
    );
  }

  return nextState;}

위 구성 요소 업데이트의 프로세스 코드에서 확인할 수 있습니다.

  • updateComponent에서 nextState는 componentWillReceiveProps 이후에 계산되므로, 현재 업데이트에서는 componentWillReceiveProps의 setState를 유효하게 사용할 수 있습니다.

  • _processPendingState에서는 큐의 상태가 중첩됩니다. 수정이 함수 모드인 경우 여기에 전달된 상태 매개변수는 nextState이고 props는 nextProps입니다.

Preact

키 코드:

setState 단계:


// component.jssetState(state, callback) {
  let s = this.state;
  if (!this.prevState) this.prevState = extend({}, s);
  extend(s, typeof state===&#39;function&#39; ? state(s, this.props) : state);
  if (callback) (this._renderCallbacks = (this._renderCallbacks || [])).push(callback);
  enqueueRender(this);}

구현은 간단하고 대략적입니다. This.state는 즉시 다시 작성되며 첫 번째 setState 동안 유지됩니다. 상태를 prevState로 변경합니다. 상태는 즉시 병합되므로 입력 매개변수 상태가 함수인 경우 props는 현재 this.props가 됩니다.

업데이트 단계:


export function renderComponent(component, opts, mountAll, isChild) {
  ...
  previousProps = component.prevProps || props,
  previousState = component.prevState || state,
  previousContext = component.prevContext || context,
  ...  // if updating
  if (isUpdate) {
    component.props = previousProps;
    component.state = previousState;
    component.context = previousContext;
    if (opts!==FORCE_RENDER      && component.shouldComponentUpdate
      && component.shouldComponentUpdate(props, state, context) === false) {
      skip = true;
    }
    else if (component.componentWillUpdate) {
      component.componentWillUpdate(props, state, context);
    }
    component.props = props;
    component.state = state;
    component.context = context;
  }
  ...}

업데이트 프로세스 전에 이전 상태가 추출되고 shouldComponentUpdate 및 componentWillUpdate가 새 값으로 복원됩니다. 따라서 shouldComponentUpdate 수명 주기에서 this.props는 일관된 prevProps를 얻습니다. React의 논리와 일치하지 않습니다.

Emphasis

동일 사항:

  • ComponentWillReceiveProps의 setState가 nextState에 적용됩니다.

  • shouldComponentUpdate의 setState는 nextState에 적용되지 않지만 들어오는 nextState는 직접 조작될 수 있습니다.

  • 차이:

    React의 setState 값은 즉시 적용되지 않고, componentWillReceiveProps까지 누적되며, 이후 병합되어 후속 라이프사이클에 제공됩니다. Preact에서 setState는 this.state에 즉시 반영되지만
  • 렌더링할 구성 요소의 수명 주기를 업데이트하기 전에(예: shouldComponentUpdate) this.state는 prevState가 됩니다.

    shouldComponentUpdate 단계의 setState는 최종 상태 값에 영향을 미치지 않지만 나중에 componentWillUpdate의 this.state와 같이 Preact의 this.state 값에 영향을 미칩니다. 즉, 여기서 setState를 안 해도 소용이 없습니다. 단계.
  • setState 함수를 사용하여 수정하면 Preact에 전달된 props는 prevProps가 되고, React에서는 nextProps가 됩니다.
  • 요약
작성한 프로젝트가 React와 Preact 모두와 호환되어야 하는 경우:

동일한 구성 요소 업데이트가 실행되기 직전에 상태가 업데이트되지 않는다는 React의 setState 기능을 사용하지 마세요. 그들 사이에 여러 개의 setState가 있는지 주의하세요. 효과, 필요한 경우 이전 값을 수동으로 저장하세요.
  • 컴포넌트 업데이트 라이프사이클에서는 componentWillReceiveProps 외에는 setState를 사용하지 마세요. nextState 라이프사이클이 제공되며 nextState를 직접 수정할 수 있습니다.
  • setState 함수 수정 방법을 사용하지 마세요.
  • p.s: antd-mobile 2.0 공식 버전이 출시되었습니다. 또한, React 및 preact와도 호환되는 가볍고 빠르며 사용하기 쉬운 모바일 컴포넌트 라이브러리입니다~ [ 포털]

위 내용은 React와 Preact의 setState 차이점의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.