리렌더링이 많이 일어나는 것이 좋지않다. 비용과 사용자의 불편함이 발생된다.
이를 해결하기 위해 memoization 탄생
React.memo : 컴포넌트를 캐싱useCallback: 함수를 캐싱useMemo: 값을 캐싱memoization을 사용하지 않으면 리렌더링이 불필요한 자식 컴포넌트까지 리렌더링이 된다.
import { useState } from "react";
import Box1 from "./components/Box1";
import Box2 from "./components/Box2";
import Box3 from "./components/Box3";
const App = () => {
const [count, setCount] = useState(0);
console.log("App 리렌더링 ==>");
const plusCount = () => {
setCount(count + 1);
};
const minusCount = () => {
setCount(count - 1);
};
return (
<div>
<h1>카운트</h1>
<span>현재 카운트: {count}</span>
<button onClick={plusCount}>+</button>
<button onClick={minusCount}>-</button>
<Box1 />
<Box2 />
<Box3 />
</div>
);
};
export default App;
const Box1 = () => {
console.log("Box1 리렌더링==>");
return (
<div
style={{
width: "100px",
height: "100px",
backgroundColor: "red",
color: "white",
display: "flex",
justifyContent: "center",
alignItems: "center",
}}
>
Box1
</div>
);
};
export default Box1;
const Box2 = () => {
console.log("Box2 리렌더링==>");
return (
<div
style={{
width: "100px",
height: "100px",
backgroundColor: "green",
color: "white",
display: "flex",
justifyContent: "center",
alignItems: "center",
}}
>
Box2
</div>
);
};
export default Box2;
const Box3 = () => {
console.log("Box3 리렌더링==>");
Box3;
return (
<div
style={{
width: "100px",
height: "100px",
backgroundColor: "blue",
color: "white",
display: "flex",
justifyContent: "center",
alignItems: "center",
}}
></div>
);
};
export default Box3;

+버튼을 한 번 눌렀을 때 최초 렌더링이후에 App컴포넌트 이외에변화가 없는 자식 컴포넌트들 까지 리렌더링이 발생한다.이를 해결하기 위해React.memo를 사용한다.
export 한 부분에서 컴포넌트 이름을 React.memo()로 감싸면된다.
export default React.memo(Box1);
export default React.memo(Box2);
export default React.memo(Box3)

+버튼을 한 번 눌러보니 App컴포넌트 즉, 부모 컴포넌트만 리렌더링 된 결과를 볼 수 있다.함수를 memoization한다.
카운트를 초기화 하는 initCount함수를 만들고 Box1에 props로 전달했다. 초기화 버튼을 만들어 연결한 상태다.
import { useState } from "react";
import Box1 from "./components/Box1";
import Box2 from "./components/Box2";
import Box3 from "./components/Box3";
const App = () => {
const [count, setCount] = useState(0);
console.log("App 리렌더링 ==>");
const plusCount = () => {
setCount(count + 1);
};
const minusCount = () => {
setCount(count - 1);
};
const initCount = () => {
setCount(0);
};
return (
<div>
<h1>카운트</h1>
<span>현재 카운트: {count}</span>
<button onClick={plusCount}>+</button>
<button onClick={minusCount}>-</button>
<Box1 initCount={initCount} />
<Box2 />
<Box3 />
</div>
);
};
export default App;
import React from "react";
const Box1 = ({ initCount }) => {
console.log("Box1 리렌더링==>");
return (
<div
style={{
width: "100px",
height: "100px",
backgroundColor: "red",
color: "white",
display: "flex",
justifyContent: "center",
alignItems: "center",
}}
>
<button onClick={initCount}>초기화</button>
</div>
);
};
export default React.memo(Box1);

+버튼을 10번 누른 후 초기화 버튼을 누른 상태다.
함수형 컴포넌트를 사용했기 때문이다.initCount함수는 재생성(재실행)된다. Box1은 initCount와 연결 되어있기 때문에 같이 리렌더링이 된다.사용 방법은 생성한 함수 부분을 useCallback()으로 감싸면 된다.
꼭! 두 번째 인자로 의존성 배열을 넣어줘야한다!
const initCount = useCallback(() => {
setCount(0);
}, []);

값을 memoization 한다.
사용 방법은useMemo(,[])함수에 값을 넣거나 호출된 함수를 넣으면 된다.
아래 코드는for (let i = 0; i < 1000000000; i++) {}라는 무거운 작업을 넣어 새로고침 시간을 길게 만들고, useMemo를 사용해 새로고침 시간을 짧게 만든 코드다.
heavyWork 도 재생성(재실행)되기 때문이다.import styled from "styled-components";
import HeavyComponent from "./components/HeavyComponent";
const App = () => {
const Nav = styled.nav`
background-color: green;
margin: 20px 0;
`;
const Footer = styled.footer`
background-color: purple;
margin-top: 20px;
`;
return (
<div>
<h1>useMemo</h1>
<Nav>내비게이션 바</Nav>
<HeavyComponent />
<Footer>푸터</Footer>
</div>
);
};
export default App;
import { useMemo, useState } from "react";
const HeavyComponent = () => {
const [value, setValue] = useState(0);
const heavyWork = () => {
for (let i = 0; i < 1000000000; i++) {}
return 100;
};
const sampleValue = useMemo(() => heavyWork(), []);
return (
<div>
<p>나는 {sampleValue}를 가져오는 무거운 컴포넌트!</p>
<button
onClick={() => {
setValue(value + 1);
}}
>
카운트!
</button>
<br />
카운트{value}
</div>
);
};
export default HeavyComponent;
오늘은 바쁜하루였다. 오늘안에 강의를 다 들어야 내일 과제를 할 시간있기 때문이다. 이번에는 강의를 천천히 들었기 때문에 시간이 타이트했다. 천천히 들어서 그런지 좀 더 이해를 하고 넘어간 부분이 많아진 것 같다. 이 기세를 몰아서 개인과제도 아무런 탈 없이 했으면 좋겠다.