티스토리 뷰

Client/React.js

[React] useCallback

무화과(Fig) 2023. 8. 25. 19:51


목차

 

1. useCallback과 Memoization

2. useCallback 구조와 특징

3. useCallback 사용하기


 

 

 

1. useCallback과 Memoization


useCallback은 Memoization 기법으로 컴포넌트의 성능을 최적화시켜주는 도구이다.

Memoization

자주 사용되는 값을 받아오기 위해 반복적으로 계산을 해야한다면 이전에 이미 계산해둔 값을 캐싱해서 메모리에서 꺼내서 재사용하는 최적화기법이. 필요할때마다 매번 계산을 하는 것이 아니라 useMemo를 통해 캐싱해둔 값을 메모리에서 꺼내와서 재사용할 수 있다

 

 

아래와 같이 useMemo의 인자로 콜백함수를 넣어주면 이 함수가 return하는 값을 Memoization 해준다.

useMemo(() => {
	return value
},[item])

 

 

그렇다면 useCallback은 무엇일까?

 

useCallback도 useMemo와 똑같은데 대신 인자로 전달한 콜백함수 그 자체를 메모이제이션 해준다. 재사용하고 싶은 함수를 useCallback으로 감싸주면 필요한 곳에서 재사용할 수 있다.

 

 

 

 

2. useCallback 구조와 특징


useCallback은 두개의 인자를 받는다.

첫번째 인자로는 메모이제이션 해줄 콜백함수 그리고 두번째 인자는 의존성 배열이다.

const calculate = useCallback((num) => {
	return num + 1;
}, [item])

 

이렇게 함수를 useCallback으로 감싸주면 이제 calculate 변수는 메모이제이션 된 함수를 가지고 있게 된다. 이 메모이제이션 된 calculate 함수는 두번째 인자인 의존성 배열 내부의 값이 변경되지 않는 이상 다시 초기화되지 않는다.

만약 의존성 배열 내부의 값이 변경된다면 그제서야 calculate 함수는 새로 만들어진 새로운 함수로 초기화 된다.

 

또한 함수형 컴포넌트는 렌더링이 되면 그 컴포넌트 함수가 다시 호출되기 때문에 컴포넌트 내부 모든 변수가 초기화 된다.하지만 이때 useCallback을 사용해서 함수를 감싸서 메모이제이션을 해주면 컴포넌트가 다시 랜더링 되더라도 내부 변수가 초기화되는 것을 막을 수 있다.

 

그래서 컴포넌트가 맨처음 랜더링 될때만 함수 객체를 만들어서 초기화 해주고 이후에는 이미 할당받은 함수 객체를 계속 가지고 있으면서 재사용 할 수 있다.

 

 

 

 

3. useCallback 예제


버튼 누르기 전

 

버튼 누른 후

 

박스 사이즈를 변경할 수 있는 input과 버튼을 누르면 배경색이 변경되는 페이지를 만들었다.

 

useCallback 함수를 사용하기 전에는 Change Theme 버튼을 누르면 <Box />의 useEffect가 계속 호출되었다.

 

따라서 박스 사이즈가 변경될 때만 <Box /> useEffect가 실행되게 만들기 위해 createBoxStyle 함수를 useCallback으로 감싸주었다. 그리고 두번째 인자인 의존성 배열에 size를 넣어 박스 크기가 변경 될 때만 createBoxStyle함수가 재사용 되도록 해주었다.

 

 

 

전체 코드

 

App.js

import React, { useState, useCallback } from 'react';
import Box from './Box';


const App = () => {
  const [size, setSize] = useState(100);
  const [isdark, setisDark] = useState(false);
  
  const createBoxStyle = useCallback(() => {
    return {
      backgroundColor: 'pink',
      width: `${size}px`,
      height: `${size}px`,
    }
  }, [size])

  return (
    <div 
      style={{
        background: isdark ? 'black' : 'white'
      }}>
      <input 
        type='number'
        value={size}
        onChange={(e)=> setSize(e.target.value)}
      />
      <button onClick={()=> setisDark(!isdark)}>Change Theme</button>
      <Box createBoxStyle={createBoxStyle} />
    </div>
  );
};

export default App;

 

 

 

Box.js

import React, { useState, useEffect } from 'react';

const Box = ({createBoxStyle}) => {
  const [style, setStyle] = useState({});

  useEffect(() => {
    console.log('박스 키우기');
    setStyle(createBoxStyle());
  }, [createBoxStyle])

  return (
    <div style={style}></div>
  );
};

export default Box;

 

'Client > React.js' 카테고리의 다른 글

[React] Axios 인터셉터 사용법  (0) 2023.08.30
[React] Redux 이해하기  (0) 2023.08.28
[React] 1. React-app 설치방법  (0) 2023.08.21
[React] useMemo  (0) 2023.08.18
[React] useReducer  (0) 2023.08.14
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/02   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28
글 보관함