여기서 말하는 memo는 memoization
을 뜻하며, 기억한다는 말이다. 무엇을 기억할까??
// as-is
const value = 반환할_함수();
// to-be
const value = useMemo(()=> {
return 반환할_함수()
}, [dependencyArray]);
dependency Array의 값이 변경 될 때만 반환할_함수()
가 호출된다.
그 외의 경우에는 memoization 해놨던 값을 가져오기만 한다.
import React, { useState, useMemo } from "react";
function HeavyButton() {
const [count, setCount] = useState(0);
const heavyWork = () => {
for (let i = 0; i < 1000000000; i++) {}
return 100;
};
// CASE 1 : useMemo를 사용하지 않았을 때
const value = heavyWork();//
// CASE 2 : useMemo를 사용했을 때
const value = useMemo(() => heavyWork(), []);
return (
<>
<p>나는 {value}</p>
<button
onClick={() => {
setCount(count + 1);
}}
>
누르면 count 가 올라간다.
</button>
<br />
{count}
</>
);
}
export default HeavyButton;
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 />
<div>
<button
onClick={() => {
setIsAlive(!isAlive);
}}
>
누르면 살았다가 죽었다함
</button>
<br />
생존여부 : {me.isAlive}
</div>
<hr />
//---------------
<br />
{uselessCount}
<br />
<button
onClick={() => {
setUselessCount(uselessCount + 1);
}}
>
누르면 숫자가 올라간다
</button>
</>
);
}
export default ObjectComponent;
신기하게도 useEffect
hook을 이용해서 me의 정보가 바뀔 때 발동되게끔 dependency array
를 넣었는데도 count를 증가하는 button
을 눌러보면 계속 해서 콘솔이 찍힌다...
Q . Why...
A. uselessCount state
가 바뀌면 리렌더링이 된다.
-> 컴포넌트 함수가 새롭게 호출된다.
-> me 객체도 다시 할당이 된다.
-> useEffect의 dependency array에 의해 me 객체가 바뀌었는지 주소를 확인 하는데 당연히 새롭게 그려진 me 객체
이므로 useEffect가 실행된다.
이러한 상황에서 해결할 수 있는 것은
셋 중에서 당연히 객체도 값으로 정의 내릴 수 있으니
useMemo로 해결해보자
const me = useMemo(() => {
return {
name: "Ted Chang",
age: 21,
isAlive: isAlive ? "생존" : "사망",
};
}, [isAlive]);
useMemo()
만 써주면, uselessCount
가 아무리 증가돼도 영향이 없게 된다.