ReactJS의 평등 - The ShallowEqual
14056 단어 reactjavascript
소개
React Rendering에 대한 간략한 요약.
3가지 조건 중 하나가 충족되면 구성 요소가 다시 렌더링됩니다.
props
변화. state
변경됩니다. 이 게시물에서는 포인트 1, "그것의
props
변화"에 초점을 맞출 것입니다.얕은평등
우리가 어딘가에 도달하기 전에 "변화"가 무엇을 의미하는지 물어야 합니다.
React 자체의 source code을 보고 봅시다!
shallowEqual
/**
* Performs equality by iterating through keys on an object and returning false
* when any key has values which are not strictly equal between the arguments.
* Returns true when the values of all keys are strictly equal.
*/
function shallowEqual(objA: mixed, objB: mixed): boolean {
if (Object.is(objA, objB)) {
return true;
}
if (
typeof objA !== 'object' ||
objA === null ||
typeof objB !== 'object' ||
objB === null
) {
return false;
}
const keysA = Object.keys(objA);
const keysB = Object.keys(objB);
if (keysA.length !== keysB.length) {
return false;
}
for (let i = 0; i < keysA.length; i++) {
if (
!hasOwnProperty.call(objB, keysA[i]) ||
!Object.is(objA[keysA[i]], objB[keysA[i]])
) {
return false;
}
}
return true;
}
이 코드는 React의 Reconciler가 props의 변경 사항을 기반으로 구성 요소를 업데이트해야 하는지 여부를 결정할 때 실행됩니다(같은 스타일의 검사는 React에서도 다른 곳에서 동등성을 위해 사용되지만 여기서는 props에 초점을 맞출 것입니다). 첫 번째 인수
objA
는 이전 소품이고 두 번째 인수objB
는 다음 소품입니다.Object.is()
여기서 이해해야 할 핵심은 for 루프 검사의 다음 줄입니다.
!Object.is(objA[keysA[i]], objB[keysA[i]])
React가 하는 것은 특정 prop이 Object.is 으로 다음 prop과 동일한지 확인하는 것입니다.
Object.is
평등에 대한 엄격한 검사입니다. 두 가지가 동일합니다(동일함과 의미상 다름).Object.is
는 기본 유형 undefined
및 null
에서 예상한 대로 정확히 작동합니다.Object.is(1, 1) // true
Object.is('Hello World', 'Hello World') // true
Object.is(true, true) // true
Object.is(undefined, undefined) // true
Object.is(null, null) // true
많은 사람들이 빠지는 함정은 참조 유형(객체, 배열, 함수)에 있습니다.
Object.is
는 이들의 메모리 참조를 확인합니다. 동일한 경우에만 true
반환합니다.Object.is(['a'], ['a']) // false
Object.is({ a: 1 }, { a: 1 }) // false
Object.is(() => {}, () => {}) // false
각 인수는 동일한 값을 가진 개체에 대한 새로운 참조이므로
false
가 결과입니다. 우리가 갔다면 :const array = ['a'];
Object.is(array, array); // true
이번에는 참조가 메모리의 동일한 배열에 대한 것이므로
Object.is
는 true
를 반환합니다.컴포넌트 렌더링
그러나 이것이 React 구성 요소에 대해 무엇을 의미합니까?
예를 들어보겠습니다(유형이 지정된 props가 명시적임 😁):
interface AppleProps {
isBrusied: boolean;
info: {
type: string;
color: 'red' | 'green';
}
}
const Apple = ({
isBruised,
info
}) => (
<div>{`Imagine I'm an apple! ${isBruised, info.type, info.color}`}</div>
);
이제
Apple
🍎가 있습니다.다음과 같이 처음 렌더링되었다고 가정해 보겠습니다.
<Apple isBrusied={false} info={{ type: 'jazz', color: 'red' }} />
그리고 부모의 모든 후속 렌더링에는 똑같은 소품이 있는 사과, 상처가 나지 않은 빨간색 재즈 사과 😋가 있습니다.
props
변경만 고려하면 Apple이 다시 렌더링합니까?불행히도 우리에게 사과의
props
는 동일하지만 shallowEqual
에 따르면 동일하지 않습니다. info
가 물건이기 때문에 범인이다. shallowEqual
는 서로 다른 메모리 주소를 참조하므로 항상 이전info
이 다음info
과 같지 않음을 반환합니다.이것은
Apple
가 지속적으로 불필요하게 다시 렌더링된다는 것을 의미합니다.잠재적인 솔루션
이 게시물을 너무 길게 만들지 않기 위해 이 문제를 해결하기 위해 존재하는
useCallback
및 useMemo
와 같은 후크를 탐구하지 않겠습니다. 후속 조치에서 다룰 수 있습니다. 이 솔루션은 이를 무시합니다.기본 유형 대 참조 유형에 대해 우리가 알고 있는 것에서.
info
를 두 개의 기본 유형으로 분할해 보겠습니다. 우리는 이제 이런 모양의 애플을 갖게 될 것입니다.<Apple isBruised={false} type={'jazz'} color={'red'} />
이렇게 하면 세 가지 소품이 모두 동일하게 유지되면 구성 요소가 렌더링되지 않습니다. 이제 더 최적화된 응용 프로그램으로 나아가고 있습니다!
결론
React의 동등성 검사는 변경을 결정할 때 엄격한 검사를 사용합니다. 기본 유형은 예상대로 작동하지만 함수, 객체 및 배열과 같은 참조 유형을 사용할 때 주의하지 않으면 애플리케이션에 불필요한 변경이 발생할 수 있음을 기억하는 것이 중요합니다.
읽어주셔서 감사합니다 🎖! 나는 이 얕은 평등도 적용되는
useCallback
및 useMemo
와 이러한 후크가 존재하는 이유에 대해 자세히 알아보기 위해 이 게시물을 따르기를 바랍니다.
Reference
이 문제에 관하여(ReactJS의 평등 - The ShallowEqual), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/sheepysean/equality-in-reactjs-the-shallowequal-2bci텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)