Chapter 4. Escape Hatches
#8 커스텀 훅으로 로직 재사용하기
학습 목차
1. 커스텀 훅: 컴포넌트간의 로직 공유
2. 훅 사이에 반응형 값 전달하기
3. 언제 커스텀 훅을 사용할 것인가
1. 커스텀 훅: 컴포넌트간의 로직 공유
- 대부분의 앱이 그렇듯이 네트워크에 크게 의존하는 앱을 개발한다고 가정해 보자.
사용자가 앱을 사용하는 동안 실수로 네트워크 연결이 끊어진 경우 사용자에게 주의를 줄 경우 어떻게 하면 좋을까?
이럴 경우에 컴포넌트에는 두 가지가 필요하다.
- 네트워크가 온라인 상태인지 여부를 추적하는 state
- 전역
online
및 offline
이벤트를 구독하고, state를 업데이트하는 Effect
- 이렇게 하면 컴포넌트가 네트워크 state와 동기화된 상태로 유지된다.
1-1. 컴포넌트에서 커스텀 훅 추출하기
- 컴포넌트 내부의 코드가 (브라우저 이벤트에 가입하여) 어떻게 할 것인가가 아니라 무엇을 할 것인가(온라인 상태 사용!)를 설명한다는 점이다.
- 로직을 커스텀 훅으로 추출하면 외부 시스템이나 브라우저 API를 처리하는 방법에 대한 지저분한 세부 사항을 숨길 수 있다.
컴포넌트의 코드는 구현이 아니라 의도를 표현한다.
1-2. 훅의 이름은 언제나 use로 시작된다.
- React 애플리케이션은 컴포넌트로 빌드된다.
- 컴포넌트는 빌트인이든 커스텀이든 상관없이 훅으로 빌드된다.
- 다른 사람이 만든 커스텀 훅을 사용하는 경우가 많지만, 가끔은 직접 작성할 수도 있다.
이때는 다음 명명 규칙을 따라야 한다.
- React 컴포넌트 이름은
StatusBar
나 SaveButton
과 같이 대문자로 시작해야한다.
또한 React 컴포넌트는 JSX와 같이 React가 표시하는 방법을 알고 있는 것을 반환해야한다.
- 훅의 이름은
useState
(빌트인)이나 useOnlineStatus
(커스텀)처럼 use
로 시작해야 하고, 그 다음의 첫글자는 대문자여야 합니다. 훅은 임의의 값을 반환할 수 있습니다.
- 이 규칙은 컴포넌트를 보고 state, Effect 및 기타 React 기능이 어디에 “숨어 있는지” 항상 알 수 있도록 보장합니다.
KeyNote
1-3. 커스텀 훅은 state 자체가 아닌 상태적인 로직(stateful logic)을 공유한다.
- 커스텀 훅을 사용하면 상태 로직(stateful logic)은 공유할 수 있지만 state 자체는 공유할 수 없다.
- 각 훅 호출은 동일한 훅에 대한 다른 모든 호출과 완전히 독립적이다.
- 여러 컴포넌트 간에 state 자체를 공유해야 하는 경우, 대신 끌어올려 전달하기를 사용하자.
2. 훅 사이에 반응형 값 전달하기
- 컴포넌트를 다시 렌더링할 때마다 커스텀 훅 내부의 코드가 다시 실행된다.
이것이 컴포넌트와 마찬가지로 커스텀 훅도 순수해야 하는 이유이다.
커스텀 Hook의 코드를 컴포넌트 본문의 일부로 생각하자.
- 커스텀 훅은 컴포넌트와 함께 다시 렌더링되기 때문에 항상 최신 props와 state를 받는다.
2-1. 커스텀훅에게 이벤트 핸들러 전달하기
3. 언제 커스텀 훅을 사용할 것인가
- 중복되는 모든 코드에 대해 커스텀 훅을 추출할 필요는 없다. 약간의 중복은 괜찮다.
- 하지만 Effect를 작성할 때마다 커스텀 훅으로 감싸는 것이 더 명확할지 고려하자.
Effect는 자주 필요하지 않으므로, 만약 Effect를 작성한다면 외부 시스템과 동기화하거나 React에 빌트인 API가 없는 작업을 수행하기 위해 “React 외부로 나가야 한다”는 뜻이다.
- Effect를 커스텀 훅으로 감싸면 의도와 데이터 흐름 방식을 정확하게 전달할 수 있다.
3-1. 커스텀 훅은 더 나은 패턴으로 마이그레이션하는데 도움을 준다.
- 마이그레이션을 위해 컴포넌트를 변경할 필요가 없다.
- Effect는 “탈출구”:이다.
“React를 벗어나야 할 때”, 그리고 사용 사례에 더 나은 빌트인 솔루션이 없을 때 사용한다.
시간이 지남에 따라 React 팀의 목표는 더 구체적인 문제에 대한 더 구체적인 솔루션을 제공함으로써 앱에서 Effect의 수를 최소한으로 줄이는 것이다.
Effect를 커스텀 훅으로 감싸면 이러한 솔루션이 제공될 때 코드를 더 쉽게 업그레이드할 수 있다.
- 아래가 커스텀 훅으로 Effect를 감싸는 것이 좋은이유 중 하나이다.
- Effect와의 데이터 흐름을 매우 명확하게 만들 수 있다.
- 컴포넌트가 Effect의 정확한 구현보다는 의도에 집중할 수 있다.
- React가 새로운 기능을 추가할 때 컴포넌트를 변경하지 않고도 해당 Effect를 제거할 수 있다.
- 디자인 시스템과 유사하게 앱의 컴포넌트에서 공통된 관용구를 추출하여 커스텀 훅으로 만드는 것이 도움이 될 수 있다.
이렇게 하면 컴포넌트의 코드가 의도에 집중할 수 있고, 원시 Effect를 자주 작성하는 것을 피할 수 있다.
React 커뮤니티에서 관리하고 있는 훌륭한 커스텀 훅도 많이 있다.
요약
- 커스텀 훅을 사용하면 컴포넌트 간에 로직을 공유할 수 있다.
- 커스텀 훅의 이름은 use로 시작하고 대문자로 끝나야한다.
- 커스텀 훅은 상태적 로직만 공유하며 state 자체는 공유하지 않는다.
- 반응형 값을 한 훅에서 다른 훅으로 전달할 수 있으며 최신 state로 유지된다.
- 컴포넌트가 다시 렌더링될 때마다 모든 훅이 다시 실행된다.
- 커스텀 훅의 코드는 컴포넌트의 코드와 같이 순수해야한다.
- 커스텀 훅이 수신한 이벤트 핸들러를 Effect Event로 감싸자.
- useMount와 같은 커스텀 훅을 만들지 마세요. 용도를 명확히 하라.
- 코드의 경계를 어디에서 어떻게 선택할지는 여러분이 결정할 수 있다.
회고
- 공식문서를 정독하며 정답이지만 모든 것이 정답은 아닌듯 했다.
- 여러 예시들이 있어 정리하기 힘들었지만 이해하기에는 그보다 더 용이했다.
- 당장 프로젝트에 적용하여 사용할 수는 있겠지만 러닝커브로 인해 다소 걸릴 것으로 보인다.
- React를 사용한다면, 학생 때 영어 단어 외우듯 자주 공식문서를 봐줘야겠다는 생각이 든다.
React 공식 문서
https://react.dev/
React 비공식 번역 문서
https://react-ko.dev/
MDN
https://developer.mozilla.org/ko/
Wikipedia
https://ko.wikipedia.org/wiki/