Memoization
setState
함수를 사용하게 되면, 화면 전체가 다시 렌더가 되면서 state
와 여러개의 함수들을 다시 그려내게 된다.
- 그런데
onChange
이벤트로 setState
함수를 실행하게 되면 문자 하나하나 변경할때마다 컴포넌트가 다시 렌더가 되고 이과정에서 여러개의 state
와 함수들이 계속해서 재생성된다.
- 컴포넌트의 크기가 매우 크거나 함수의 로직이 매우 길다면
set
함수로 인해 처음부터 다시 그려내는 과정이 불필요하다가 느껴지게 된다.
- 메모이제이션은 특정 연산이나 특정 함수의 값을 기억해 놓은후
State
의 변화로 컴포넌트의 재렌더하더라도 재생성이 아니라 기존에 저장된 값을 그대로 사용할 수 있게 해준다.
- 메모이제이션 기능을 사용함으로서 컴포넌트의 불필요한 재렌더링을 줄여 좀 더 빠른 컴포넌트 렌더링을 유도할수 있다.
💻 코드적용
container.jsx
useMemo
는 react
의 기능으로
연산된 결과를 담는 변수의 값을 저장해준다.
useMemo(() => 적용할 연산 함수
, [ 적용할 변수
])
적용할 변수가 변경되었을 때만 메모이제이션 값만 다시 계산한다.
useCallback
은 함수를 메모이제이션 해준다.
useCallback(함수 로직
, [ 의존성 배열
])
useCallback으로 메모이제이션한 함수는 재렌더링되지않아 렌더효율성을 올릴 수 있다.
import { useMemo, useCallback, useState } from "react";
...
- 다음의 함수들을 이용하면 메모이제이션에 대해 이해할 수 있다.
onClickCountLet
인 onClick
함수는 콘솔창에서는 숫자가 올라가지만 화면상에는 숫자가 0에서 올라가지 않는다.
onClickCountState
인 onClick
함수는 콘솔창에서도, 화면에서도 숫자가 올라간다.
- 전자는 렌더링이 되고 있고 후자는 렌더링이 되고 있음을 의미한다.
export default function MemoizationContainerPage() {
console.log("컨테이너가 렌더링 되었습니다!");
let countLet = 0;
const [countState, setCountState] = useState(0);
const randomValue = useMemo(() => Math.random(), []);
console.log(randomValue);
const onClickCountLet = useCallback(() => {
console.log(countLet + 1);
countLet = countLet + 1;
}, []);
const onClickCountState = useCallback(() => {
setCountState((prev) => prev + 1);
}, []);
return (
<>
<div>카운트(let) : {countLet} </div>
<button onClick={onClickCountLet}>카운트(let) +1</button>
<div>카운트(state) : {countState}</div>
<button onClick={onClickCountState}>카운트(state) +1</button>
<MemoizationPresenterPage countState={countState} />
</>
);
}
presenter.tsx
memo
는 컴포넌트를 메모이제이션 하는 기능이다.
memo
로 감싸진 컴포넌트의 결과를 저장시킨 후
새로 렌더되는 결과가 저장된 결과와 같다면 해당 컴포넌트를 재렌더 하지 않게 된다.
memo
로 적용된 컴포넌트는 상위 컴포넌트가 재렌더가 되더라도 넘어오는
props
의 값이 동일 하다면 컴포넌트를 재랜더하지 않게 된다.
import { memo } from "react";
function MemoizationPresenterPage(props) {
console.log("프리젠터가 렌더링 되었습니다!");
return (
<>
<div>=============================</div>
<div>이것은 프리젠터입니다!!!</div>
<div>=============================</div>
</>
);
}
export default memo(MemoizationPresenterPage);
- 모바일 환경에서 웹 접속이 보편화되고 자연스러워지면서 반응형 웹을 적용한 웹사이트들이 많아졌다.
- 놀랍게도 이는 사이즈구간별로 각각의 다른 CSS코드가 존재 하는 것이었다.
- 보통 모바일, 태블릿, 웹 세가지 구간으로 적용시킨다.
💻 코드적용하기

index.tsx
@media{ }
부분이 중요하다. 미디어쿼리
라고 한다.
import styled from "@emotion/styled";
import { breakPoints } from "../../src/commons/styles/media";
const Wrapper = styled.div`
width: 1000px;
height: 1000px;
background-color: #cd5c5c;
//* 미디어 쿼리
@media ${breakPoints.tablet} {
// 화면이 1199px 이하로 작아진다면 아래의 css가 적용된다.
width: 500px;
// 넓이는 보통 핸드폰 사이즈가 다양하기 때문에 % 를 준다.
height: 500px;
// 높이는 같이 커졌다 작아졌다하기 애매하기 때문에 고정한다.
background-color: #4444c5;
}
@media ${breakPoints.mobile} {
// 화면이 767px 이하로 작아진다면 아래의 css가 적용된다.
width: 100px;
height: 100px;
background-color: #81d8b1;
/* display: none; */ // 작아지면 안보이게끔 하게도 할수있다.
}
`;
export default function ResponsiveMediaPage() {
return (
<>
<Wrapper>상자</Wrapper>
</>
);
}
- 구간은 여러 페이지에서 적용할 수 있게 따로 컴포넌트화하는 것이 편하다.
export const breakPoints = {
tablet: "(min-width : 768px) and (max-width: 1199px)",
mobile: "(max-width : 767px)",
};