Posts Usecallback
Post
Cancel

Usecallback

https://react-ko.dev/reference/react/useCallback 리렌더링 사이에 함수 정의를 캐시할 수 있게 해주는 React Hook

1
2
3
4
5
6
const handleSubmit = useCallback((orderDetails) => {  
	post('/product/' + productId + '/buy', {  
		referrer,  
		orderDetails,  
	});  
}, [productId, referrer]);

Caveats

  • useCallback은 성능 최적화를 위해 사용해야한다. useCallback 없이 코드가 동작하지 않는다면 근본적인 문제를 찾아 수정해야한다.
  • useCallback으로 함수를 캐싱하는 건 몇가지 경우에만 유용하다
    • memo로 감싼 컴포넌트에 prop으로 전달하는 경우.
    • 함수가 다른 훅의 dependencies로 사용되는 경우
  • 몇 가지 원칙으로 memoization이 불필요해질 수 있다
    • 컴포넌트가 다른 컴포넌트를 시각적으로 감쌀 때, JSX를 children으로 받아들여라.
      • wrapper 컴포넌트가 변경되더라도 자식이 리렌더링 되지 않음
    • local state를 선호하고, 필요이상으로 state를 끌어올리지마라.
      • ex) 최상위 트리나 전역 state에 아이템이 호버되었는지와 같은 일시적 state를 두지마라
    • 렌더링 로직을 순수하게 유지하라.
      • 컴포넌트를 리렌더링했을 때 문제가 발생하면 버그가 있는 것이므로, memoization 대신 버그를 수정하라
    • state를 업데이트하는 불필요한 Effect를 피하라
      • React 앱의 대부분의 성능 문제는 컴포넌트를 반복해서 렌더링하게 만드는 Effect에서 발생하는 업데이트 체인으로 인해 발생
    • Effect에서 불필요한 의존성을 제거하라
      • memoization 대신 object나 함수를 Effect 내부나 컴포넌트 외부로 이동시키는게 더 간단할 수도 있음.

Usage

Optimizing a custom Hook

커스텀 훅을 사용하는 경우에 반환하는 모든 함수를 useCallback으로 감싸는 것이 좋다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function useRouter() {  
	const { dispatch } = useContext(RouterStateContext);  
	
	const navigate = useCallback((url) => {  
		dispatch({ type: 'navigate', url });  
	}, [dispatch]);  
	
	const goBack = useCallback(() => {  
		dispatch({ type: 'back' });  
	}, [dispatch]);  
	
	return {  
		navigate,  
		goBack,  
	};  
}

이렇게하면 훅의 소비자가 필요할 때 자신의 코드를 최적화할 수 있다.

This post is licensed under CC BY 4.0 by the author.