useCallback
함수를 memoization하기 위해 사용되는 hook함수 → useMemo와 비슷한 Hook
💡 useMemo는 특정 결과값을 재사용 할 때 사용
useCallback은 특정 함수를 새로 만들지 않고 재사용하고 싶을 때 사용
- 컴포넌트에서 props가 바뀌지 않으면 Virtual DOM에 새로 렌더링하는 것도 하지 않고, 컴포넌트의 결과물을 재사용하는 최적화 작업 → 함수 재사용
기본 구조
const memoizedCallback = useCallback(함수, 배열);
첫 번째 파라미터: 인자로 넘어온 함수
두 번째 파라미터: 넘어온 배열 내의 값이 변경될 때까지 저장해놓고 재사용할 수 있게 해줌
- 해당 컴포넌트가 렌더링되어도 그 함수가 의존하는 값들이 바뀌지 않는 한 기존 함수 계속 반환
const add = () => x+y;
const add = useCallback(() => x+y, [x,y]);
// x 또는 y 값이 바뀌면 새로운 함수가 생성되어 add변수에 할당되고, x와 y값이 동일하다면
// 다음 렌더링 때 함수 재사용
import React, { useRef, useState, useMemo, useCallback } from "react";
const onChange = useCallback(
(e) => {
const { name, value } = e.target;
setInputs({
...inputs,
[name]: value,
});
},
[inputs]
);
const onCreate = useCallback(() => {
const user = {
id: nextId.current,
username,
email,
};
setUsers(users.concat(user));
setInputs({
username: "",
email: "",
});
nextId.current += 1; //값 수정 시, .current 값 수정하면 되고, 조회할 때도 .current조회하면 됨
}, [users, username, email]);
const onRemove = useCallback(
(id) => {
//user.id가 파라미터로 일치하지 않는 원소만 추출하여 새로운 배열을 만듦
//=user.id가 id인 것을 제거
setUsers(users.filter((user) => user.id !== id));
},
[users]
);
const onToggle = useCallback(
(id) => {
setUsers(
users.map((user) =>
user.id === id ? { ...user, active: !user.active } : user
)
);
},
[users]
);
❗️ 함수 안에서 사용하는 상태 혹은 props가 있다면 deps 배열 안에 포함시켜야 함
→ 만약 deps 배열 안에 해당 값을 넣지 않으면, 함수 내에서 해당 값들을 참조할 때 가장 최신 값을 참조한다고 보장 못함
❗️ props로 받아온 함수 있으면, 이 함수도 deps에 넣어야 함
useCallback은 useMemo 기반으로 만들어짐
const onToggle = useMemo(
() => () => {
/* ... */
},
[users]
);
→ useCallback을 사용하였을 때, 눈에 띄는 최적화는 없음 → 컴포넌트 렌더링 최적화 작업해주어야 성능이 최적화 됨(React DevTools: 어떤 컴포넌트가 렌더링되고 있는지 확인하기 위한 프로그램)
React.memo를 사용한 컴포넌트 리렌더링 방지
컴포넌트의 props가 바뀌지 않았을 때, 리렌더링 방지하여 컴포넌트의 리렌더링 성능 최적화 해주는 함수 → 컴포넌트에서 리렌더링이 필요한 상황에서만 리렌더링 하도록 설정
사용법
export default React.memo(UserList); //컴포넌트 이름을 React.memo로 감싸주면 됨
React.memo에서 두 번째 파라미터에 propsAreEqual 이라는 함수를 사용하여 특정 값들만 비교 가능 → 잘못 사용하면 의도치 않은 버그 발생하기 쉬움
export default React.memo(
UserList,
(prevProps, nextProps) => prevProps.users === nextProps.users
);
주의할 점
useMemo, useCallback, React.memo는 컴포넌트 성능을 실제로 개선할 수 있는 상황에서만 사용하길 권장
ex) 렌더링 최적화 하지 않을 컴포넌트에 React.memo를 사용하는것은 불필요한 props 비교하는 것임
'프론트엔드 > React' 카테고리의 다른 글
커스텀 Hooks 만들기 (0) | 2022.11.24 |
---|---|
useReducer (0) | 2022.11.24 |
useEffect와 useMemo (0) | 2022.11.23 |
컴포넌트 렌더링 (0) | 2022.11.23 |
✅ 배열 내장 함수(자바스크립트) (0) | 2022.11.17 |