우리가 일반적인 함수의 형태로 컴포넌트에 함수를 선언하게 되면 해당 컴포넌트가 렌더링 될때 (lifeCycle에 따라서)
일반적인 함수로 선언된 모든 함수가 새롭게 렌더링이 된다. 이는 사실상 쓸데 없는 메모리를 잡아먹는 행위이고,
이런 문제를 해결하기 위한 방법으로 React에서는 결과값 하나를 리턴해야하는 것의 경우에는 useMemo, 특정한 동작자체를 리턴해야한다면 useCallBack를 사용해 그 메모리 소모를 줄이는 방법이 있다.
대부분 구글링을 해봐도 콜백을 설명하는게 명확하지가 않고 진짜 애매모호하고 이해가 잘 안돼서 상당히 어려움을 겪었는데(이런 이유로 그냥 콜백 안썼다.) 콜백이라는 개념 자체를 제대로 이해하고, lifecycle에 대한 이해만 명확하다면 제대로 사용할 수 있게 된다.
Memoization
이 React의 useMemo와 useCallBack은 메모이제이션이라는 개념까지 이해를 해야하는데, 단순하게 설명해서 이전에 사용했던 값을 재사용한다고 설명할 수 있다.
그러니까 해당 함수에서 사용되었던 값이나 함수들이 어떠한 변화도 없는데 새롭게 렌더링하고 만들어내야한다면 그건 메모리적으로 손해이기때문에 그 내용들을 기억하고 있다가 다시 재사용한다는의미라고 보면 된다.
useMemo
useMemo는 useCallBack에 비하면 상당히 쉽게 이해할 수 있는데 그냥 이 useMemo에 넘겨준 함수가 연산하여 도출하는 값을 리턴해주는 훅이다보니, deps에도 어떤걸 넣어줘야할지 상당히 명확하게 감이 온다. 간단히 코드로 들여다보자.
const [state, setState] = useState(1);
const value = useMemo(() => {
return state + 1
},[state])
대충 이렇게 사용한다는 느낌이다. 이렇게 하면 state의 초기값이 1이고 setState를 하지 않았다는 가정하에 value의 값은 2가 될 것이다. 근데 state를 변경할때마다 결과 값이 달라지니까 그때마다 렌더링을 하도록 state를 deps에 걸어주고 새로운 값을 리턴해주도록 하는 것.
useCallBack
useCallBack의 경우가 이제 정말 대부분 이해하기 힘들어하고 사용해도 제대로 동작하지 않는 경우가 허다한데,
이거도 제대로 이해만 하면 아무런 문제가 없다. 말그대로 Memo는 value를 리턴하고 있다는 것, CallBack은 CallBack함수로 넘겨준 함수를 리턴한다는 것. 이 차이인데 이것 조차도 모호한 사람들이 있을거다.
자 그럼 흔히 useCallBack을 처음 썼을때 발생하는 상황을 기준으로 사용 방법 설명을 하겠다.
최적화도 잘하고 최대한 효율적으로 메모리를 사용하는 멋진 개발자가 되겠단 꿈을 가진 나는 거국적으로다가 useCallBack을 쓰기 시작했다. 근데 useCallBack을 사용한 함수들을 이벤트에다가 붙여놓고 이벤트를 발생시켜도 전혀 동작을 하지 않는거임! 왜 동작하지 않는걸까?
이유는 deps에 있다. 기본적으로 useMemo든 useCallBack이든 이 들은 deps에 의존한다. 즉, 기억할 함수를 전달해줘야하는데, deps에 아무것도 안넣어주면 함수가 만들어지지도 않는다는거임.
즉, 함수에서 사용되고 있는 값들이 변화하는 것을 감지하도록 정해두지 않으면, 그 콜백은 받은 함수가 없으니 리턴을 해주지 않는거고, 같은 말로 영원히 그 함수가 렌더링 되지 않는다는 뜻이되고, 그 뜻은 함수가 만들어지지 않았으니 실행시킬 함수가 없다는게 된다.
그러니 해당 함수가 렌더링 될 수 있는 상황을 만들어주고 useCallBack을 호출해야한다는 의미가 되겠다.
'Dev > React.js' 카테고리의 다른 글
[React] Custom Hooks (0) | 2023.06.28 |
---|---|
[FrameWork] Next.js를 시작하기 전에 (SSR은 무엇인가?) (0) | 2023.06.02 |
[React] MobX (0) | 2023.05.30 |
[React] React Query (0) | 2023.05.24 |
[상태관리] 상태관리(State) (0) | 2023.05.18 |