리액트 강의를 듣다가 useMemo와 useEffect의 개념 및 차이를 정확하게 이해하고 싶어서 정리해보는 글이다.
리액트의 컴포넌트들은 생명주기(Lifecycle)를 가지게 되는데, 간단히 탄생-변화-죽음 으로 나타낼 수 있다.
원래 리액트는 기본적으로 이런 Lifecycle들을 제어할 수 있는 method들을 가지고 있다. 하지만 아쉽게도 이런 메서드는 class형 컴포넌트에서만 사용할 수 있다.
class형 컴포넌트에서만 사용 가능한 생애주기 제어 method
- ComponentDidMount
- ComponentDidUpdate
- ComponentWillUnmount
사실 근본적으로 함수형 컴포넌트에서는 상태를 관리하는 state
나 위의 메서드들을 사용할 수 없었지만, React Hooks
가 생긴 뒤부터 함수형 컴포넌트에서도 다양한 hooks를 이용해 제어할 수 있게 되었다! 👏
함수형 컴포넌트에서도 사용 가능한 Hooks의 등장
- useState
- useEffect
- useRef ... , 등등 수많은 Hooks 존재
React Hooks는 2019년 6월 정식 출시된 기능으로, Class형 컴포넌트의 길어지는 코드 길이 및 중복 코드, 가독성 문제 등을 해결하기 위해 등장하게 되었다.
useEffect는 컴포넌트가 렌더링 될 때마다 특정 작업(side effect)을 실행할 수 있도록 하는 React Hook이다.
여기서 특정 작업(side effect)이란, 컴포넌트 렌더링 이후 비동기로 처리되어야 하는 부수적인 효과들을 뜻한다.
useEffect(() => {
// 실행하고자 하는 코드
}, []}
useEffect는 두개의 파라미터를 전달받게 되는데,
useEffect(() => {
console.log("렌더링 될때마다 실행됩니다.")
});
이렇게 deps 부분을 생략할 경우 해당 컴포넌트가 렌더링 될 때마다 useEffect가 실행되게 된다.
처음 렌더링될때, 딱 한번만 실행되게 하고 싶다면 빈 배열을 넣어주면 된다.
useEffect(() => {
console.log("처음 렌더링될 때 한번만 실행됩니다.")
}, [])
useEffect(() => {
console.log(data)
console.log("data 값이 변화(업데이트)할 때만 실행됩니다.")
}, [data])
이렇게 deps 안에 특정 값을 넣어준다면, 특정 값이 변화할때마다 useEffect가 실행된다.
useEffect(() => {
console.log("mount될 때 실행됩니다.")
return () => {
console.log("unmount시점에 실행되게 됩니다.")
}
}, [])
useEffect가 return을 통해 함수를 반환할 경우 이 함수를 cleanUp
이라고 한다.
unmount 될 때만 함수를 실행시키고 싶다면 deps에 빈 배열을 넣어주면 되고, 특정 값이 업데이트 되기 직전 cleanup 함수를 실행시키고 싶다면 deps에 특정 값을 넣어주면 된다.
메모이제이션이란, 이미 계산한 연산 결과를 기억해 두었다가 동일한 계산을 시키면 다시 연산하지 않고 기억해 두었던 데이터를 반환시키는 프로그래밍 기법이다.
메모이제이션을 적용하면 중복되는 연산을 피해 성능 최적화가 가능하다.
useMemo는 이전 렌더링과 현재 렌더링 간에 값이 동일할 경우 메모이제이션된 값을 반환하는 것으로, deps 배열 안의 값이 변경될 경우에만 함수가 실행되는 것이다.
배열의 길이인 arr.length
가 변경될 때만 리렌더링 되어야 하는 컴포넌트가 있다고 가정했을 때, 불필요한 렌더링을 막기 위해 deps에 useMemo의 두번째 파라미터인 deps에 arr.length
를 넣어주면 arr.length
값이 변화될때만 함수를 실행한다.
만약 arr.length
값이 동일한 경우 다시 함수를 호출해 값을 구하는 대신 메모이제이션된 값을 반환하여 그대로 사용하기 때문에 리렌더링 되지 않는다.
useMemo(() => {
console.log("결과값 생성")
}, [deps])
useMemo를 사용하기 이전에는 getDiaryAnalysys
는 감정점수를 분석해주는 평범한 함수였다.
하지만 useMemo로 감싸준 뒤부터는 useMemo가 함수를 전달받아 콜백함수가 전달하는 값을 리턴하기 때문에, getDiaryAnalysys
는 값
을 리턴받게 된다.
따라서 사용할 때 함수 호출 방법이 아닌 값
으로 사용되어야 한다.
const { goodCount, badCount, goodRatio } = getDiaryAnalysys();
// 자주 하는 실수이다. ()를 붙여서 함수처럼 사용하면 에러가 발생한다.
const { goodCount, badCount, goodRatio } = getDiaryAnalysys;
// 값으로 사용
가장 큰 차이점은 useEffect
는 해당 컴포넌트의 렌더링이 완료된 후에 실행되고, useMemo
는 렌더링 중에 실행된다.
참고자료