2023.01.31 useMemo( ) ,useCallback( )
useMemo( )와 useCallBack( ) 훅에서는 메모이제이션이라느 개념이 나온다.
메모이제이션이 된 결괏값을 메모이즈드 밸류라고 한다.
useMemo( ) 훅은 Memoized value(값)를 리턴하는 혹이다.
뒤에 나을 메모이제이션의 개념처럼
의존성 배열에 들어있는 변수가 변했을 경우에만 새로 create 함수를 호출하여 결괏값을 반환하며,
그렇지 않은 경우에는 기존 함수의 결괏값을 그대로 반환한다.
useMemo( ) 훅을 사용하면 컴포넌트가 다시 렌더링될 때마다 연산량이 높은 작업을 반복하는 것을 피할 수 있다.
결과적으로는 빠른 렌더링 속도를 얻을 수 있다.
useMemo(() => fn, [deps])
const memoizedValue = useMomo (
() => {
//연산량이 높은 작업을 수행하여 결과를 반환
return computeExpensiveValue(의존성 변수1, 의존성 변수2);
},
[의존성 변수1, 의존성 변수2]
);
useMemo( ) 훌을 사용할 떄 기억해야 할 점은
useMemo( )로 전달된 함수는 렌더링이 일어나는 동안 실행된다는 점이다.
그렇기 때문에 일반적으로 렌더링이 일어나는 동안 실행돼서는 안될 작업을 함수에 넣으면 안된다.
예를 들면 useEffect( ) 훅에서 실행돼야 할 사이드 이펙트 같은 것이 있다.
서버에서 데이터를 받아오거나 수동으로 DOM을 변경하는 작업 등은
렌더링이 일어나는 동안 실행돼서는 안되기 때문에 useMemo( )훅의 함수에 넣으면 안되고
useEffect( )훅을 사용해야한다.
const memoizedValue = useMemo(
() => computeExpensiveValue(a, b)
);
또한 위 코드와 같이 의존성 배열을 넣지 않을 경우
렌더링이 일어날 때마다 매번 함수가 실행된다.
따라서 useMemo( ) 훅에 의존성 배열을 넣지 않는 것은 아무런 의미가 없다.
그리고 만약 의존성 배열에 빈 배열을 넣게 되면 컴포넌트 마운트 시에만 함수가 실행된다.
seCallback( )은 useMemo( )훅과 유사한 역할을 한다.
한가지 차이점은 값이 아닌 함수를 반환 한다는 점이다.
의존성 배열에 따라 Memoized 값을 반환한다는 점에서
useMemo( ) 훅과 완전히 동일하다.
useCallback( function, dependencies )
useMemo( ( ) => function, dependencies)
useCallback( )훅은 파라미터로 함수,의존성 배열을 받는다.
파마리터로 받는 이 함수를 콜백 함수라고 부른다.
useCallback(fn, [deps])
const memoizedCallback = useCallback(
() => {
doSomething(의존성 변수1, 의존성 변수2);
},
[의존성 변수1, 의존성 변수2]
);
useCallback( ) 훅을 사용하여 특정 변수의 값이 변한 경우에만 함수를 다시 정의하도록
해서 불필요한 반복 작업을 없애주는 것이다.
import { useState } from "react";
function ParentComponent(props) {
const [count, setCount] = useState(0);
//재렌더링 될 때마다 매번 함수가 새로 정의됨
const handleClick = (event) => {
//클릭 이벤트 처리
};
return (
<div>
<button onClick={() => {
setCount(count + 1);
}}
>
{count}
</button>
<childComponent handleClick={handleClick} />
</div>
);
}
예를 들어 useCallback( ) 훅을 사용하지 않고 컴포넌트 내에서 정의한 함수를
자식 컴포넌트에 props로 넘겨 사용하는 경우,
부모 컴포넌트가 다시 렌더링 될 때마다 매번 자식 컴포넌트도 다시 렌더링 된다.
import { useState, useCallback } from "react";
function ParentComponent(props) {
const [count, setCount] = useState(0);
// 컴포넌트가 마운트 될 때만 함수가 정의됨
const handleClick = useCallback((event) => {
//클릭 이벤트 처리
}, []);
return (
<div>
<button onClick={() => {
setCount(count + 1);
}}
>
{count}
</button>
<childComponent handleClick={handleClick} />
</div>
);
}
하지만 useCallback( ) 훅을 사용하면 특정 변수의 값이 변한 경우에만 함수를 다시 정의하게 되므로,
함수가 다시 정의되지 않는 경우에 자식 컴포넌트도 재렌더링이 일어나지 않는다.
이 경우에는 의존성 배열에 빈배열이 들어갔기 때문에,
컴포넌트가 처음 마운트되는 시점에만 함수가 정의되고
이후에는 다시 정의되지 않으며 결국 다시 컴포넌트도 불필요하게 재렌더링이 일어나지 않는다.