首页 > 解决方案 > React deep 只比较一个道具

问题描述

我希望组件中的一个道具是一个深度比较的字符串数组:<ChildComponent deepCompareThis={['a', 'b']} />所以我想从浅比较中删除它,因为这个数组总是会失败浅比较。为了便于阅读,我想保留这种语法。我正在使用功能组件,所以使用React.memo.

我很好奇是否有一种干净的方式来使用和深入比较一个道具,而其他一切都React.memo回到 React 自己的默认值 。https://github.com/facebook/react/blob/master/packages/shared/shallowEqual.js

编辑:查看 shallowCompare,似乎只要您使用Object.is其他道具值,您就应该具有相同的比较功能。也许复制比较函数并没有我想象的那么可怕。大部分是优化!

标签: reactjs

解决方案


这是我的解决方案:(1)对于您尝试深度比较的道具,您可以为此编写单独的逻辑,(2)对于其余道具,使用 React 已经为浅比较编写的相同逻辑。看看我下面的源代码和其中的评论以获得洞察力

const CustomComponent = React.memo(
  (props) => {
    React.useEffect(() => {
      console.log("CustomComponent render");
    });

    return "";
  },
  (prevProps, nextProps) => {
    // destructure the prop you want to specifically target for deep comparison
    // the rest will be shallow compared
    const { deepCompareThis: prevDeep, ...prevRest } = prevProps;
    const { deepCompareThis: nextDeep, ...nextRest } = nextProps;

    // your custom logic for the deep comparison
    // i took this function from https://stackoverflow.com/a/16436975/8680805
    function arraysEqual(a, b) {
      if (a === b) return true;
      if (a == null || b == null) return false;
      if (a.length !== b.length) return false;

      for (var i = 0; i < a.length; ++i) {
        if (a[i] !== b[i]) return false;
      }
      return true;
    }

    const deep_comparison_result = arraysEqual(prevDeep, nextDeep);
    console.log(`deep comparison`, deep_comparison_result);

    // use same logic provided by reeact for shallow comparison
    // from https://github.com/facebook/react/blob/master/packages/shared/shallowEqual.js
    const shallow_comparison_result = shallowEqual(prevRest, nextRest);
    console.log(`shallow comparison`, shallow_comparison_result);

    return deep_comparison_result && shallow_comparison_result;
  }
);

编辑 React 备忘录 - 仅深度比较选定的道具


推荐阅读