> For the complete documentation index, see [llms.txt](https://docs.sysout.co.kr/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.sysout.co.kr/web/develop-page/js/reactjs/cdn/component/functional-component/usememo.md).

# useMemo

## useMemo

useMemo는컴포넌트 최적화를 위해 사용하는 React Hook이다.

## 예제 - useMemo를 사용하지 않는 컴포넌트

```jsx
function MainComponent(){
    console.log("MainComponent 렌더링");
    
    const [nickname, setNickname] = React.useState('');
    const [count1, setCount1] = React.useState(0);
    const [count2, setCount2] = React.useState(0);

    const total = count1+count2;

    return (
        <>
            <h1>useMemo 예제</h1>
            닉네임 : <input onChange={e=>setNickname(e.target.value)}/>
            <hr/>
            <p>설정된 닉네임은 {nickname}입니다</p>
            <hr/>
            <button onClick={()=>setCount1(count1+1)}>click : {count1}</button>
            <button onClick={()=>setCount2(count2+1)}>click : {count2}</button>
            <h3>총 클릭 횟수 : {total}</h3>
        </>
    );
}

const app = ReactDOM.createRoot(document.querySelector("#app"));
app.render(<MainComponent/>);
```

{% embed url="<https://codepen.io/hiphop5782/pen/jOKKxqq>" %}

MainComponent의 구조는 다음과 같다.

<div align="left"><figure><img src="https://4208234536-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M_TNZwLuHV9ipYLbvRq%2Fuploads%2FOzj6mGW5Blbz3g7jukji%2Fusememo.png?alt=media&amp;token=44f28048-cffb-46b2-b427-7a5669b1ddd7" alt=""><figcaption></figcaption></figure></div>

state로 선언된 <mark style="color:blue;">**`nickname`**</mark>, <mark style="color:blue;">**`count1`**</mark>, <mark style="color:blue;">**`count2`**</mark>가 변경될 경우 <mark style="color:green;">**`<MainComponent/>`**</mark>는 다시 렌더링을 실시한다. 렌더링을 실시하면 모든 코드를 다시 실행하며, total 역시 다시 계산된다.&#x20;

현재 상황에서는 state가 적어서 심각하게 느껴지지 않겠지만 디테일하게 살펴보면 <mark style="color:blue;">**`nickname`**</mark>과 **total**은 전혀 상관이 없는 데이터이다. 따라서 컴포넌트의 성능 저하가 발생하며 규모가 커질 수록 성능 저하로 발생하는 낭비는 심해질 것이다.

## 예제 - useMemo를 사용하는 컴포넌트

<mark style="color:blue;">**`count1`**</mark>, <mark style="color:blue;">**`count2`**</mark>가 변경되는 경우만 **total**이 변경되도록 처리하기 위해서 다음과 같이 React.useMemo를 사용한다.

```jsx
const total = React.useMemo(()=>count1 + count2, [count1, count2]);
```

전체 코드는 다음과 같다.

```jsx
function MainComponent(){
    console.log("MainComponent 렌더링");

    const [nickname, setNickname] = React.useState('');
    const [count1, setCount1] = React.useState(0);
    const [count2, setCount2] = React.useState(0);

    const total = React.useMemo(()=>{
        console.log("total 재계산");
        return count1+count2;
    }, [count1, count2]);

    return (
        <>
            <h1>useMemo 예제</h1>
            닉네임 : <input onChange={e=>setNickname(e.target.value)}/>
            <hr/>
            <p>설정된 닉네임은 {nickname}입니다</p>
            <hr/>
            <button onClick={()=>setCount1(count1+1)}>click : {count1}</button>
            <button onClick={()=>setCount2(count2+1)}>click : {count2}</button>
            <h3>총 클릭 횟수 : {total}</h3>
        </>
    );
}

const app = ReactDOM.createRoot(document.querySelector("#app"));
app.render(<MainComponent/>);
```

실행한 뒤 콘솔을 확인하면 total 재계산이라는 글자는 count1과 count2가 변경되었을 경우만 실행되는 것을 확인할 수 있다.

{% embed url="<https://codepen.io/hiphop5782/pen/dyKKeZa>" %}

## 결론

**`React.useMemo()`**&#xB294; 재계산되는 항목에 대한 최적화를 수행한다. 이를 사용하면 컴포넌트의 성능 향상을 가져올 수 있다.

{% hint style="info" %}
VueJS의 computed와 유사하다.
{% endhint %}
