memo 는 언제 사용할까
리액트에서 컴포넌트가 재렌더링되면
그 안에 있는 자식 컴포넌트는 항상 같이 재렌더링 된다.
근데 어떤 자식 컴포넌트가 유난히 엄청 무거운 컴포넌트라면
하나의 그 위에 부모 컴포넌트 부를때 부담이 될거다.
이럴땐 그 무거운 자식 컴포넌트를 memo 라는 걸로 감싸면된다.
memo 사용법
import {memo, useState} from 'react'
let Child = memo( function(){
console.log('재렌더링됨')
return <div>자식임</div>
})
function Cart(){
let [count, setCount] = useState(0)
return (
<Child />
<button onClick={()=>{ setCount(count+1) }}> + </button>
)
}
먼저 memo를 import 해오고
원하는 컴포넌트를 선언할때 감싸서 만들면된다.
useMemo 란
useMemo 는 성능 최적화를 위해 사용되는 Hook 이다.
useMemo 는 주어진 함수를 실행하고, 그 결과를 캐시(cache)한다.
이후에 같은 입력값으로 함수를 호출하면 캐시된 결과를 반환한다.
→ 반복적으로 비용이 큰 계산을 수행하지 않고 성능을 최적화
사용법
첫번째 인자 : 캐시할 함수
두번째 인자 : 의존성 배열(dependency array)
→ 의존성 배열에는 캐시할 함수에서 참조하는 값들이 포함되며, 이 값들이 변경될 때마다 함수가 다시 실행되어 결과를 캐시함.
예시
import React, { useMemo } from 'react';
function MyComponent({ data }) {
const result = useMemo(() => {
// 복잡한 계산을 수행하는 함수
// data를 사용해서 결과값을 계산
return ...;
}, [data]);
return (
<div>
{result}
</div>
);
}
여기서 useMemo 는 data 가 변경될 때마다 result 를 캐시한다.
같은 data로 MyComponent 가 렌더링 되면, result 는 캐시되어있는 결과를 반환한다.
useMemo와 useEffect 의 차이
둘의 차이는 뭘까?
useEffect(() => {어떤 동작}, [뭔가]);
const [ state, setState ] = useState('idle');
useEffect(() => {
if (state === 'success'){
console.log("PROCESS DONE!! <<success>>");
setState('idle');
}
}, [state]);
- useEffect 는 뭔가가 바뀌면 어떤 동작을 자동으로 실행하기 위해 사용함
- state 가 바뀌면 { } 안에 있는 동작이 실행
위 코드에서는 state 가 여러 값으로 업데이트 된다.
이때 useEffect에 전달한 콜백함수가 실행되는데
내부에 있는 if문 때문에 console.log가 찍히는건 state 값이 success 일 때 뿐임
- 최초 컴포넌트 마운트 되는 경우, 컴포넌트 내 레이아웃 배치와 랜더링 완료된 후 실행
- 2 번째 인자(배열)의 요소 지정 시, 해당 요소 값이 업데이트 되는 경우에만 실행
- state나 props를 dependency로 지정 시, 불필요한 렌더링이 발생 가능
useMemo를 보자.
const person = useMemo(
() => (
<Person
name={name}
song={favoriteSong}
/>
),
[name, favoriteSong]
);
- useMemo는 원하는 값을 업데이트하기위해 사용한다.
- name 이랑 favoriteSong 이 바뀌면 값을 새로 계산한다.
- memoization 된 값을 반환
- useMemo에서 전달된 함수는 렌더링 중 실행을 하지만, useEffect 에서 전달된 함수는 렌더링 중 실행을 하지 않음.
아직은 좀 헷갈리는 것 같다.
나중에 직접 프로젝트를 하면서 개념을 활용해보아야겠다.
ref
https://intrepidgeeks.com/tutorial/usage-and-differences-of-hook-useeffect-usememoand-usecallback