我正在阅读React.memo上的以下文章https://blog.bitsrc.io/optimize-your-react-app-with-react-memo-ec52447b09ba
我对这篇文章有两个具体的问题。
- 根据链接,它说";在功能组件中,React默认情况下只执行两次优化。首先,如果通过浅层次比较,新状态等于旧状态,则可以避免重新渲染过程。其次,它只更新已更改的DOM节点,而不更新整个DOM,因为更新DOM的成本很高">
当它说React默认情况下比较状态时,我很困惑。我的理解是,只有当我们使用React.memo时,才会发生这种情况。我在这里错过了什么吗
- 根据网站上显示的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]
与对象行为相比,这有什么不同?
不是,这是相同的行为。