React Hook은 렌더링 최적화를 위한 Hook도 존재하며 그 역할을 하는 Hook이 바로 useCallback과 useMemo이다.
useCallback Hook에 대하여 알아보고, useMemo 와 useCallback의 차이에 대하여 작성해보았다.
useCallback 이란?
useCallback 또한 useMemo와 마찬가지로 메모이제이션 기법을 이용한 Hook이다.
useCallback은 함수의 재사용을 위해 사용하는 Hook이다.
useCallback만 사용해서는 useMemo에 비해 괄목할 만한 최적화를 느낄 수는 없다. 왜냐하면 useCallback은 함수를 호출을 하지 않는 Hook이 아니라, 그저 메모리 어딘가에 함수를 꺼내서 호출하는 Hook이기 때문이다.
따라서 단순히 컴포넌트 내에서 함수를 반복해서 생성하지 않기 위해서 useCallback을 사용하는 것은 큰 의미가 없거나 오히려 손해인 경우도 있다.
그러면 언제 사용하는 게 좋을까? 자식 컴포넌트의 props로 함수를 전달해 줄 때 이 useCallback을 사용하기가 좋다.
useCallback과 참조 동등성
useCallback은 참조 동등성에 의존합니다.JavaScript에서 함수는 객체입니다. 객체는 메모리에 저장할 때 값을 저장하는 게 아니라 값의 주소를 저장하기 때문에, 반환하는 값이 같을지라도 일치연산자로 비교했을 때 false가 출력됩니다.
function doubleFactory(){
return (a) => 2 * a;
}
const double1 = doubleFactory();
const double2 = doubleFactory();
double1(8); // 16
double2(8); // 16
double1 === double2; // false
double1 === double1; // true
double1과 double2는 같은 함수를 할당했음에도 메모리 주소 값이 다르기 때문에 같다고 보지 않습니다. JavaScript에서 함수는 객체입니다. 따라서 두 개의 함수는 동일한 코드를 공유하더라도 메모리 주소가 다르기 때문에, 메모리 주소에 의한 참조 비교 시 다른 함수로 봅니다.
이는 React 또한 같습니다. React는 리렌더링 시 함수를 새로이 만들어서 호출을 합니다. 새로이 만들어 호출된 함수는 기존의 함수와 같은 함수가 아닙니다. 그러나 useCallback을 이용해 함수 자체를 저장해서 다시 사용하면 함수의 메모리 주소 값을 저장했다가 다시 사용한다는 것과 같다고 볼 수 있습니다. 따라서 React 컴포넌트 함수 내에서 다른 함수의 인자로 넘기거나 자식 컴포넌트의 prop으로 넘길 때 예상치 못한 성능 문제를 막을 수 있습니다
useCallback 예시
import { useState } from "react";
import "./styles.css";
import List from "./List";
export default function App() {
const [input, setInput] = useState(1);
const [light, setLight] = useState(true);
const theme = {
backgroundColor: light ? "White" : "grey",
color: light ? "grey" : "white"
};
const getItems = () => {
return [input + 10, input + 100];
};
const handleChange = (event) => {
if (Number(event.target.value)) {
setInput(Number(event.target.value));
}
};
input 창에 숫자를 입력하면 콘솔에 "아이템을 가져옵니다." 가 출력되는 것을 확인 할 수 있다. 하지만 옆의 button dark mode도 눌러봤을 때 "아이템을 가져옵니다."가 콘솔에 출력되는 것을 볼 수 있다.
이렇게 동작하는 이유는 버튼을 누를 때도 앱이 리렌더링 되므로, App 내부의 getItems() 함수가 다시 만들어지기 때문이다.
useCallback 사용
import { useState } from "react";
import "./styles.css";
import List from "./List";
import { useCallback } from "react";
export default function App() {
const [input, setInput] = useState(1);
const [light, setLight] = useState(true);
const theme = {
backgroundColor: light ? "White" : "grey",
color: light ? "grey" : "white"
};
const getItems = useCallback(() => {
return [input + 10, input + 100];
}, [input]);
const handleChange = (event) => {
if (Number(event.target.value)) {
setInput(Number(event.target.value));
}
};
useCallback을 이용하여 컴포넌트를 최적화시켰다.
usMemo 와 useCallback 의 차이점
- useMemo는 값의 재사용을 위해 사용하는 Hook
- useCallback은 함수의 재사용을 위해 사용하는 Hook
'React' 카테고리의 다른 글
[React]Toast UI source map 에러 (0) | 2023.06.22 |
---|---|
Styled-Components 설치 오류 (0) | 2023.06.13 |
[React] useMemo알아보기! (0) | 2023.05.20 |
[React] Diffing 알고리즘 (0) | 2023.05.19 |
[React] Virtual DOM (0) | 2023.05.19 |