React.memo和肤浅的比较



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

我对这篇文章有两个具体的问题。

  1. 根据链接,它说";在功能组件中,React默认情况下只执行两次优化。首先,如果通过浅层次比较,新状态等于旧状态,则可以避免重新渲染过程。其次,它只更新已更改的DOM节点,而不更新整个DOM,因为更新DOM的成本很高">

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

  1. 根据网站上显示的Shallow Comparison示例,它似乎暗示了对象v/s阵列的不同行为。不确定这是否也是正确的。我认为两个数组/对象每次都会得到一个新的引用,因此浅比较每次都会返回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 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默认情况下比较状态时,我很困惑。我的理解是,只有当我们使用React.memo时,才会发生这种情况。我在这里错过了什么吗?

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

尽管有变通办法,但他们并不考虑";默认情况下";,例如,通过将先前的状态保存在参考中并通过它有条件地改变状态:

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

根据网站上显示的Shallow Comparison示例,它似乎暗示了对象v/s阵列的不同行为。不确定这是否也是正确的。我认为两个数组/对象每次都会得到一个新的引用,因此浅比较每次都会返回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
};

请注意,在最后一个示例中,即使上一个状态和当前状态完全相等,它仍然会重新出现。

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

[1] === [1]与对象行为相比,这有什么不同?

不是,这是相同的行为。

最新更新