[React] 리렌더링 최적화 1편 : React.memo
■ React 최적화 - 리렌더링 최적화를 위해서 !
■ React.memo
■ 예시 코드
■ React 최적화 - 리렌더링 최적화를 위해서 !
React에서 컴포넌트는 상태나 props가 바뀔 때 리렌더링 됩니다.
이때 컴포넌트 안에서 정의된 함수가 익명함수인지, 기명 함수인지에 따라 달라지는게 있을까요 ??
익명 함수 기명 함수 둘다 ! 차이는 없다 ..
- 렌더될 때 마다 함수 새로 생성 → 참조값이 달라짐 !!!
- 부모가 렌더링 되면, 자식에게 전달된 함수 props도 항상 새로움 !
→ 즉, 불필요한 리렌더링 발생
function MyComponent() {
return (
<button onClick={() => console.log("clicked!")}>Click</button>
);
}
function MyComponent() {
const handleClick = function handleClick() {
console.log("clicked!");
};
return <ChildComponent onClick={handleClick} />;
}
🧐 어떻게 리렌더링을 최적화 하나요 ??
우선 memo에 대해 알아봅시다.
■ React.memo
: 컴포넌트 자체를 메모이제이션하는 고차 컴포넌트
- props가 변경되지 않으면 리렌더링을 하지 않도록 막아주는 최적화 기법
이전 props와 새로운 props를 얕은 비교(shallow comparsion) 해서 같으면 렌더링을 건너뛰는데요!
이때, 얕은 비교가 무엇인지 알아야 memo에 대해 더 잘 이해할 수 있어요. 😙
타입 | 얕은 비교 방식 | 결과 |
원시값(number, string, boolean) | 값 자체 비교 | 값이 같으면 true |
참조형(object, array, function) | 참조(주소) 비교 | 같은 객체 참조면 true, 아니면 false |
함수의 내용은 같아도 생성될 때마다 참조값이 달라지니 memo로는 최적화가 힘들것 같네요.
→ 자식 컴포넌트 props에 함수가 있다면 memo 효과 없음
→ why? 함수 생성시 참조값이 달라지기 때문에 props가 변하였다고 인지!!
■ 간단한 예시를 통해 비교해볼까요 ~ ?
ex1 ) props가 원시값인 경우
부모 컴포넌트에서 버튼을 눌러 리렌더될 때,
자식 컴포넌트의 props가 변하지 않았으므로 memo로 컴포넌트 자체 메모이제이션 가능
import React from 'react';
import { useState } from 'react';
const Child = React.memo(({ count }) => {
console.log('Child rendered');
return <div>Child Count: {count}</div>;
});
function Parent() {
const [ParentCount, setParentCount] = useState(0);
return (
<div>
<button onClick={()=>setParentCount((prev)=> prev+1)}>
Parent Count: {ParentCount}
</button>
<Child count={10}} />
</div>
);
}
ex2 ) props가 원시값 + 함수일 경우
부모 컴포넌트에서 버튼을 눌러 리렌더될 때,
자식 컴포넌트의 props 함수가 새로 생성되므로 memo로 컴포넌트 자체 메모이제이션 불가능
- 의도치 않은 동작으로 Child rendered 출력됨
import React from 'react';
import { useState } from 'react';
const Child = React.memo(({ count, onClick }) => {
console.log('Child rendered');
return (
<div>
<button onClick={onClick}>
Child Count: {count}
</button>
</div>;
);
});
export default function App() {
const [ChildCount, setChildCount] = useState(0);
const [ParentCount, setParentCount] = useState(0);
return (
<div>
<button onClick={()=>setParentCount((prev)=> prev+1)}>
Parent Count: {ParentCount}
</button>
<Child count={ChildCount} onClick={()=>setChildCount((prev)=> prev+1)} />
</div>
);
}
memo는 얕은 비교로 동작한다는 것, 그래서 props가 함수일 경우 memo는 효과가 없다는 것을 알게 되었습니다 !
다른 원시값들은 메모이제이션이 가능하니 리렌더링 최적화가 되겠군요 😙
이어지는 포스팅에서는 props가 함수, 객체, 배열일 경우 리렌더링 최적화 하는 방법에 대해 알아보도록 해요 ☀️