简体   繁体   English

React.memo 和浅层比较

[英]React.memo and shallow comparision

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

I had 2 specific questions around the article.关于这篇文章,我有 2 个具体问题。

  1. As per the link, it says "In function components React only performs two optimizations by default. First, it avoid the re-render process if by shallow comparison the new state is equal to the old state. Second, it only updates the DOM nodes which have changed and not the whole DOM as updating DOM is costly."根据链接,它说“在 function 组件中,React 默认只执行两个优化。首先,如果通过浅比较新的 state 等于旧的 Z9ED39E2EA931425876B6A985A,它会避免重新渲染过程。它已经改变,而不是整个 DOM,因为更新 DOM 的成本很高。”

I was confused when it says React by default, compares the state.当它说默认为 React 时,我很困惑,比较 state。 My understanding is that happens only if we use React.memo.我的理解是,只有当我们使用 React.memo 时才会发生这种情况。 Am I missing something here?我在这里错过了什么吗?

  1. As per the Shallow Comparison example shown on the site, it seems to suggest different behavior for objects v/s arrays.根据网站上显示的浅比较示例,它似乎暗示了对象与 arrays 的不同行为。 Not sure if that is correct as well.也不确定这是否正确。 I thought both arrays/objects would get a new reference each time and hence shallow comparison would return false every time for them?我认为两个数组/对象每次都会获得一个新的引用,因此每次浅比较都会为它们返回 false?

Specifically, this example on the link confused me;具体来说,链接上的这个例子让我很困惑;

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

Also, from my end I tried using below custom function for shallow compare and observed both object and array to behave similarly.另外,从我的角度来看,我尝试使用下面的自定义 function 进行浅比较,并观察到 object 和数组的行为相似。 This function is not part of the article link above.此 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;
}

Let's start with the fact that the most reliable source is what published by React team.让我们从一个事实开始,最可靠的来源是 React 团队发布的内容。

I was confused when it says React by default, compares the state.当它说默认为 React 时,我很困惑,比较 state。 My understanding is that happens only if we use React.memo.我的理解是,只有当我们使用 React.memo 时才会发生这种情况。 Am I missing something here?我在这里错过了什么吗?

It's true, you can't customize how you compare state in React.确实,您无法自定义在 React 中比较 state 的方式。

Although there are workarounds they don't consider "by default", for example by saving the previous state in a reference and conditionally changing state by it:尽管有一些解决方法,但他们不考虑“默认情况下”,例如通过将以前的 state 保存在参考中并有条件地更改 state :

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

As per the Shallow Comparison example shown on the site, it seems to suggest different behavior for objects v/s arrays.根据网站上显示的浅比较示例,它似乎暗示了对象与 arrays 的不同行为。 Not sure if that is correct as well.也不确定这是否正确。 I thought both arrays/objects would get a new reference each time and hence shallow comparison would return false every time for them?我认为两个数组/对象每次都会获得一个新的引用,因此每次浅比较都会为它们返回 false?

You are right, the author's definition for "shallow comparison" is wrong, because "shallow comparison" is defined by the Strict equality ( === ) operator .您是对的,作者对“浅比较”的定义是错误的,因为“浅比较”是由严格相等( === )运算符定义的。

// 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
};

Note that in the last example, even if the previous state and the current state are deeply equal it still will rerender.请注意,在最后一个示例中,即使之前的 state 和当前的 state 非常相等,它仍然会重新渲染。

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

[1] === [1] Why is this different compared to object behavior? [1] === [1]为什么这与 object 的行为不同?

It's not, it's the same behavior.这不是,这是相同的行为。

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

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