繁体   English   中英

React Native Redux:比较 prevProps 和 this.props 的最佳方法是什么?

[英]React Native Redux: what's the best way to compare prevProps and this.props?

在我的 React Native 应用程序中,如果某个道具发生了变化,我想触发 function。 像这样的东西:

componentDidUpdate(prevProps) {
  if (prevProps.a !== this.props.a) {
    <trigger event>
  }
}

问题是我假设prevProps.a.== this.props.a总是正确的,因为它是通过引用进行比较的。

解决此问题的最佳方法是什么,以便仅当this.props.a的属性发生更改时才会触发我的事件?

最好直接比较属性,而不是像这样比较整个对象:

componentDidUpdate(prevProps) {
  if (prevProps.a.field1 === this.props.a.field1) {
    // Do stuff here
  }
}

但是,如果您仍然想比较两个具有深度嵌套属性的对象,一个简单的方法是对两个对象进行字符串化,然后直接比较字符串:

if (JSON.stringify(prevProps.a) === JSON.stringify(this.props.a) {
    // Do stuff here
  }

这在一定程度上取决于被比较的 object a性质。 如果是特定属性的问题,那么您显然可以单独比较它们,这始终是最有效的方法。 但是,如果您想在对a进行任何更改时触发代码,包括嵌套对象内部的深度更改,那么比较对象的字符串化表示 (JSON.stringify) 可以解决问题。 然而,它也是低效的。 一种中间方法是进行浅比较,这里有一些代码(来自 React 团队)来做到这一点:

export function shallowEqual(objA: any, objB: any, compare?, compareContext?) {
  let ret = compare ? compare.call(compareContext, objA, objB) : void 0;

  if (ret !== void 0) {
    return !!ret;
  }

  if (objA === objB) {
    return true;
  }

  if (typeof objA !== 'object' || !objA || typeof objB !== 'object' || !objB) {
    return false;
  }

  const keysA = Object.keys(objA);
  const keysB = Object.keys(objB);

  if (keysA.length !== keysB.length) {
    return false;
  }

  const bHasOwnProperty = Object.prototype.hasOwnProperty.bind(objB);

  // Test for A's keys different from B.
  for (let idx = 0; idx < keysA.length; idx++) {
    const key = keysA[idx];

    if (!bHasOwnProperty(key)) {
      return false;
    }

    const valueA = objA[key];
    const valueB = objB[key];

    ret = compare ? compare.call(compareContext, valueA, valueB, key) : void 0;

    if (ret === false || (ret === void 0 && valueA !== valueB)) {
      return false;
    }
  }

如果您需要进行有效的深度比较(比 JSON.stringify 更重要),那么使用react-fast-compare等库(此处)是您的最佳选择。

(还要注意JSON.stringify在某些情况下并不完美,因为日期和函数等某些对象没有正确或根本没有字符串化。实际上,这些限制在 React 中通常不是问题,但你应该在至少。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM