내배캠 스탠다드수업에서 유익하고 좋은 내용을 배워서 오늘의 TIL은 스탠다드수업강의를 배운것들을 정리하기로 했닷..!!
React에서 성능 최적화를 위한 고차 컴포넌트로, 이를 사용하면 컴포넌트가 이전에 렌더링된 결과를 기억하고, props가 변경되지 않았을 때 이전 결과를 재사용하여 레더링을 피할 수 있습니다.
일반적으로, React컴포넌트는 부모컴포넌트나 상태가 변경될 때마다 다시 렌더링되지만 React.memo
를 사용하면 컴포넌트가 받는 props가 변경되지 않으면 이전에 렌더링한 결과를 캐시하고, 같은 props로 다시 렌더링될 때는 이전 결과를 사용합니다.
- 컴포넌트에서 state가 바뀌었을 때
- 컴포넌트가 내려받은 props가 변경되었을 때
- 부모 컴포넌트가 리-렌더링 된 경우 자식 컴포넌트는 모두
부모.jsx
export default function 부모 () {
const [count, setCount] = useState(0);
return (
<div>
<button onClick={()=>setCount(count+1)}>플러스</button>
<자식 />
</div>
)
}
자식.jsx
export default function 자식 () {
return (
<div>헤헤 난 아무것도 안하지롱</div>
)
}
App.jsx
import React, { useState } from "react";
import Box1 from "./components/Box1";
import Box2 from "./components/Box2";
import Box3 from "./components/Box3";
function App() {
console.log("App 컴포넌트가 렌더링되었습니다!");
const [count, setCount] = useState(0);
// 1을 증가
const onPlusButtonClickHandler = () => {
setCount(count + 1);
};
// 1을 감소
const onMinusButtonClickHandler = () => {
setCount(count - 1);
};
return (
<>
<h3>카운트 예제입니다!</h3>
<p>현재 카운트 : {count}</p>
<button onClick={onPlusButtonClickHandler}>+</button>
<button onClick={onMinusButtonClickHandler}>-</button>
<div>
<Box1 />
<Box2 />
<Box3 />
</div>
</>
);
}
export default App;
Box1.jsx
import React from "react";
function Box1() {
console.log("Box1이 렌더링되었습니다.");
return <div>Box1</div>;
}
export default Box1;
Box2.jsx
import React from "react";
function Box2() {
console.log("Box2가 렌더링되었습니다.");
return <div>Box2</div>;
}
export default Box2;
Box3.jsx
import React from "react";
function Box3() {
console.log("Box3가 렌더링되었습니다.");
return <div>Box3</div>;
}
export default Box3;
App컴포넌트에서 button을 클릭을하면 자식컴포넌트인 Box들도 렌더링이 되는것을 볼 수 있습니다. 이런 불 필요한 렌더링을 막기위해서 React.memo를 사용해 불필요한 렌더링을 막아보겠습니다.
Box1.jsx
import React from "react";
function Box1() {
console.log("Box1이 렌더링되었습니다.");
return <div>Box1</div>;
}
export default React.memo(Box1);
React.memo를 Box1컴포넌트에만 넣어보았는데 첫 렌더링은 모든 컴포넌트가 렌더링되지만 그 이후 버튼을 클릭할 시 React.memo를 넣어준 자식컴포넌트는 렌더링이 안되는것을 볼 수 있습니다.
App.jsx
// count를 초기화해주는 함수
const initCount = () => {
setCount(0);
};
return (
<div style={appStyle}>
<h3>카운트 예제입니다!</h3>
<p>현재 카운트 : {count}</p>
<button onClick={onPlusButtonClickHandler}>+</button>
<button onClick={onMinusButtonClickHandler}>-</button>
<div style={boxesStyle}>
<Box1 />
<Box2 initCount={initCount} />
<Box3 />
</div>
</div>
);
}
Box2.jsx
function Box2({ initCount }) {
console.log("Box2가 렌더링되었습니다.");
return (
<div>
<button onClick={initCount}>초기화</button>
<div>Box2</div>
</div>
);
}
export default React.memo(Box2);
Box2컴포넌트에 React.memo를 사용했지만 리렌더링이 되는게 볼 수 있습니다.
부모컴포넌트가 다시 렌더링하면서 initCount가 새로 생겨서 기존에 있던 initCout함수랑 새롭게 생긴 initCount함수는 다릅니다.
App.jsx
const initCount = useCallback(() => {
setCount(0);
}, []);
initCount는 다시 한번 생성되는게 불필요한데 이러한 불필요한 작업들을 막아주는게 useCallback입니다.
React.memo는 컴포넌트
를 memoization을 하고, useCallback은 함수
를 memoization을 한다.