반응 후크 - useMemo()

useMemo 훅이란

useMemo() 후크는 메모이제이션을 사용하여 렌더링할 때마다 비용이 많이 드는 계산을 방지하는 데 사용됩니다.

useMemo()는 종속성이 변경될 때만 메모된 값을 반환합니다.

메모이제이션이란

메모이제이션은 최적화 기술입니다. 값비싼 연산 결과를 저장하고 결과에 변화가 없을 경우 저장된 값을 사용함으로써 컴퓨터 프로그램/컴포넌트 성능을 빠르게 하는데 사용됩니다.

비싼 함수의 결과에 변화가 없으면 다시 계산하지 않고 저장된 값(캐시된 값)을 사용합니다.

useMemo() 후크를 사용하여 구성 요소 최적화

useMemo 후크를 사용하는 방법과 사용 시기에 대한 예를 살펴보겠습니다.

먼저 반응 앱을 만들어야 합니다. 아래 명령을 사용하여 그렇게 할 수 있습니다
npx create-react-app myApp
다음으로 동일한 이름의 js 파일에 ExpensiveCalculation이라는 함수를 생성했습니다.

function ExpensiveCalculation(num) {
    console.log("calculating...");
    for (let i = 0; i < 1000000000; i++) {
      num += 1;
    }
    return num;
}

export default ExpensiveCalculation;



위의 기능은 부품의 성능을 떨어뜨리는 고가의 기능입니다. 위의 함수는 ExpensiveCalculation에서 매개변수로 전달되는 num에 1을 더합니다.

for 루프는 i의 값이 1000000000보다 작은지 확인하고, 이것이 참이면 이전 값num에 1을 더한 다음 함수가 업데이트된 값num을 반환합니다.

그런 다음 src 폴더에 AddItems.js라는 구성 요소를 만들었습니다. useMemo가 없는 컴포넌트의 성능은 어떤지 봅시다.

import { useState} from "react";

function AddItems() {
    const [items, setItems] = useState([]);
    const [count, setCount] = useState(1);

    // without memoization --> expensive calculation
    const calculation = ExpensiveCalculation(count)

    const addItems = () => {
        setItems((prev) => [...prev, `New item`]);
    };

    const incrementCount = () => {
        setCount((c) => c + 1);
    };

    return (
        <div>
            {items.map((item) => (
                <li>{item}</li>
            ))}
            <button onClick={addItems}>Add items</button>
            <div style={{ display: "flex" }}>
                <h2>Expensive Calculation</h2>
                <button onClick={incrementCount}>calculate</button>
                {calculation}
            </div>
        </div>
    );
}

export default AddItems;


ExpensiveCalculation은 const 계산에 할당됩니다. 여기서는 메모이제이션을 사용하지 않습니다.

새 항목을 추가하는 버튼Add Item이 있으며 브라우저에 표시됩니다.
calculate를 증가시키는 또 다른 버튼count이 있습니다.

이제 버튼calculate을 클릭할 때마다 개수가 증가하고 개수가 ExpensiveCalculation의 인수로 전달됩니다.
const calculation = ExpensiveCalculation(count)
파일에서 ExpensiveCalculation for 루프가 실행되고 i가 1000000000보다 작은지 확인합니다. 1000000000이 큰 값이므로 AddItem이 업데이트된 값을 다시 렌더링하는 데 시간이 걸리기 때문에 시간이 걸립니다.

이제 Add Item 버튼을 클릭하면 ExpensiveCalcution도 실행되고 AddItem 구성 요소는 새 항목을 추가하고 표시하려고 했지만 다시 렌더링하는 데 더 오래 걸립니다.



ExpensiveCalculation으로 인해 실행이 지연되고 AddItem 구성 요소를 다시 렌더링하는 데 시간이 오래 걸립니다. 이 성능 문제를 해결하기 위해 useMemo 후크를 사용합니다.

반응에서 메모이제이션을 사용하려면 반응에서 useMemo 후크를 가져와야 합니다.

const calculation = useMemo(()=>ExpensiveCalculation(count),[count])


useMemo 후크는 종속성을 선언하기 위해 두 번째 매개변수를 허용합니다. 위의 코드에서 ExpensiveCalculation 함수는 횟수가 변경될 때만 호출됩니다.



카운트 값이 변경되지 않으면 함수가 캐시된 값을 반환하고 항목 추가 버튼을 클릭할 때 지연이 없음을 알 수 있습니다.

다음은 useMemo 후크를 사용한 후의 전체 코드입니다.

import { useState, useMemo } from "react";
import ExpensiveCalculation from "./ExpensiveCalculation";

function AddItems() {
    const [items, setItems] = useState([]);
    const [count, setCount] = useState(1);

    //with useMemo hook
    const calculation = useMemo(() => ExpensiveCalculation(count), [count])

    const addItems = () => {
        setItems((prev) => [...prev, `New item`]);
    };

    const incrementCount = () => {
        setCount((c) => c + 1);
    };

    return (
        <div style={{ display: "flex", displayDirection: "row", gap: "5rem" }}>
            <div>
                {items.map((item, idx) => (
                    <li key={idx}>{item}</li>
                ))}
                <button onClick={addItems}>Add items</button>
            </div>
            <div>
                <h2>Expensive Calculation</h2>
                <button onClick={incrementCount}>calculate</button>
                {calculation}
            </div>
        </div>
    );
}

export default AddItems;


React는 이전에 메모한 값을 잊어버리고 다음 렌더링에서 메모리를 확보할 때 다시 계산합니다. useMemo 없이도 계속 작동하도록 코드를 작성한 다음 추가하여 성능을 최적화하십시오.

좋은 웹페이지 즐겨찾기