繁体   English   中英

React.memo 和浅层比较

[英]React.memo and shallow comparision

我正在阅读以下关于 React.memo https://blog.bitsrc.io/optimize-your-react-app-with-react-memo-ec52447b09ba的文章

关于这篇文章,我有 2 个具体问题。

  1. 根据链接,它说“在 function 组件中,React 默认只执行两个优化。首先,如果通过浅比较新的 state 等于旧的 Z9ED39E2EA931425876B6A985A,它会避免重新渲染过程。它已经改变,而不是整个 DOM,因为更新 DOM 的成本很高。”

当它说默认为 React 时,我很困惑,比较 state。 我的理解是,只有当我们使用 React.memo 时才会发生这种情况。 我在这里错过了什么吗?

  1. 根据网站上显示的浅比较示例,它似乎暗示了对象与 arrays 的不同行为。 也不确定这是否正确。 我认为两个数组/对象每次都会获得一个新的引用,因此每次浅比较都会为它们返回 false?

具体来说,链接上的这个例子让我很困惑;

const car1 = {
  color: 'red',
  model: 'S',
};

const car2 = {
  color: 'red',
  model: 'X',
};

const car3 = {
  color: 'red',
  model: 'S',
};

shallowCompare(car1, car2); // false
shallowCompare(car1, car3); // true - Why would this return true ???




const arr1 = [1];
const arr2 = [1];
const arr3 = arr1;

console.log(arr1 === arr2);     // false - Why is this different compared to object behavior ?
console.log(arr1 === arr3);     // true

另外,从我的角度来看,我尝试使用下面的自定义 function 进行浅比较,并观察到 object 和数组的行为相似。 此 function 不是上述文章链接的一部分。

function areEqualShallow(a, b) {
    for(var key in a) {
        if(!(key in b) || a[key] !== b[key]) {
            return false;
        }
    }
    for(var key in b) {
        if(!(key in a) || a[key] !== b[key]) {
            return false;
        }
    }
    return true;
}

让我们从一个事实开始,最可靠的来源是 React 团队发布的内容。

当它说默认为 React 时,我很困惑,比较 state。 我的理解是,只有当我们使用 React.memo 时才会发生这种情况。 我在这里错过了什么吗?

确实,您无法自定义在 React 中比较 state 的方式。

尽管有一些解决方法,但他们不考虑“默认情况下”,例如通过将以前的 state 保存在参考中并有条件地更改 state :

useEffect(() => {
  if (areEqualCustom(prevState.current, newState)) {
    setState(newState);
    prevState.current = newState;
  }
}, [newState]);

根据网站上显示的浅比较示例,它似乎暗示了对象与 arrays 的不同行为。 也不确定这是否正确。 我认为两个数组/对象每次都会获得一个新的引用,因此每次浅比较都会为它们返回 false?

您是对的,作者对“浅比较”的定义是错误的,因为“浅比较”是由严格相等( === )运算符定义的。

// Blog example

const car1 = {
  color: 'red',
  model: 'S',
};

const car3 = {
  color: 'red',
  model: 'S',
};

// car1 === car3
shallowCompare(car1, car3) // always false

// React example
const onClick = () => {
  // Don't mutate state in React.
  stateObject.x = 5;
  // prevState === stateObject (true)
  setState(stateObject); // no render

  // Instead use Object.assign / shallow copy
  setState({ ...stateObject, x: 5 }); // always render
};

请注意,在最后一个示例中,即使之前的 state 和当前的 state 非常相等,它仍然会重新渲染。

setState({ x: 5 }); // always render
// even if prevState = { x: 5 }

[1] === [1]为什么这与 object 的行为不同?

这不是,这是相同的行为。

暂无
暂无

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

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