목차
- useMemo
최적화를 위한 React hook
중 마지막 !
useMemo
를 알아본다.
앞서 최적화를 위해 사용하는 hook
두 개를 알아봤다.
React.memo
는 컴포넌트를 메모이제이션 하고,
useCallback
은 함수 자체를 메모이제이션 한다고 했다.
그럼 useMemo
는?
바로 value
를 메모이제이션한다!
const value = useMemo(() => {
return 반환될 함수()
},[dependencyArray])
반환될 함수를 useMemo
함수로 감싸주고, 마지막 콤마 기준 우측에
의존성 배열로 감싸주면, 의존성 배열의 값이 변경될 때만 반환될 함수() 가 호출된다.
그 외에는 담아둔 값을 가져오는 형식 !
heavyWork 라는 변수로 지정된 함수는 함수 내부의 for문이 수없이 많은 숫자를 돌아야 하기 때문에 아주 아주 무거운 작업이다.
그니까 렌더링 속도가 늦고, 반응 속도도 늦을 수 밖에 없다.
예시 사진 최하단 버튼을 누르면 작업이 매우 늦겠지?
그렇지만, useMemo
로 감싸 주면 !
처리 속도가 매우 빨라진다.
import React, {useEffect, useState} from 'react';
function ObjectComponent(){
const [isAlive, setIsAlive] = useState(true);
const [uselessCount, setUselessCount] = useState(0);
const me = {
name: 'Ted Chang',
age: 21,
isAlive: isAlive ? '생존' : '사망',
};
useEffect(() => {
console.log('생존여부가 바뀔 때만 호출해주세요!')
}, [me]);
return (
<>
<div>
내 이름은 {me.name}이구, 나이는 {me.age}야!
</div>
<br/>
<button onClick={() => {
setIsAlive(!isAlive);
}}
>
누르면 살았다가 죽었다가 해요
</button>
<br/>
{uselessCount}
<br/>
<button
onClick={() => {
setUselessCount(uselessCount + 1);
}}
>
누르면 숫자가 올라가요
<button>
</>)
);
}
export default ObjectComponent;
상단 사진의 선 기준으로 위 아래를 분리해놓고, useEffect
부분은 me
라는 객체가 변경될 때만 호출되도록 했음 !
근데 하단부의 누르면 1씩 숫자가 올라가는 버튼을 눌렀을 때, useEffect
함수가 실행되고, 콘솔 로그가 호출되는 걸 볼 수 있다.
<button onClick={() => {
setIsAlive(!isAlive);
}}
상단 버튼을 눌러, !isAlive
조건이 만족이 될 때만 콘솔창이 호출되어야 하는데 뭔가 문제가 있다.
정답은 바로 불변성
과 연관이 있다.
사진 하단부 버튼을 누르면 uselessCount
가 변경되므로,
function ObjectComponent(){
const [isAlive, setIsAlive] = useState(true);
const [uselessCount, setUselessCount] = useState(0);
~~~~~~~~~
};
결과적으로 ObjectComponent
함수 자체가 리렌더링된다.
즉, 함수가 새롭게 만들어진다는 것이다.
그러면 당연히
const me = {
name: 'Ted Chang',
age: 21,
isAlive: isAlive ? '생존' : '사망',
};
useEffect(() => {
console.log('생존여부가 바뀔 때만 호출해주세요!')
}, [me]);
ObjectComponent
아래 이 부분, me
라는 객체도 다시 만들어지겠지? 값은 같지만 주소값은 다른 새로운 객체가 생성된다는거다. 값이 같다고 하더라도, 주소값이 다르면 리액트 입장에선 me
라는 객체에서 변경이 발생했구나! 이렇게 인식을 하고
이 부분이 호출된다는 거임!!!
이런 경우에 값이 변경되지 않았다는 걸 리액트에게 알려주기 위해서
useMemo
사용하면 된다!
바로 이렇게 me라는 객체를 useMemo
로 감싸주고, dependency array
를 사용해서, isAlive
가 변경될 때만, me
라는 객체가 리렌더링 되도록!
그러면 isAlive
값이 변경될 때 리렌더링이 발생하므로,
하단부 버튼을 암만 눌러도 변경 사항은 없는걸 볼 수 있다.
근데 너무 남발하면 메모리 확보를 위한 공간이 너무 낭비 되기 때문에, 리액트 성능이 안좋아질 수도 있다고 하니, 꼭 필요할 때만 쓸 수 있도록 하는게 좋겠다.