리액트에서 코드 재활용하기(HoC, Custom Hooks)
리액트에서 컴포넌트를 만들다보면, A, B, C에서 공통으로 사용되는 로직들을 재활용해야 하는 일이 생깁니다. 예를들어, 유저가 로그인 했는지 안했는지 확인하는 로직이 A, B, C컴포넌트에서 모두 필요할때 그 로직을 복붙으로 3개의 컴포넌트에 다 넣을 수도 있겠지만 공통화 시켜서 반복할 수 있으면 좋겠죠?
High Order Component(HOC)
HOC를 한마디로 정의하면 다음과 같습니다.
컴포넌트를 입력받아서 그 컴포넌트를 강화해서 내보내는 함수
const HOC = ReactComponent => EnhancedReactComponent;
인자로 들어간 ReactComponent가 리턴될때는 강화된채로(Enhanced) 내보내지게 됩니다.
강화된다는것은 그냥 제가 이해하기 쉽게 표현한것이고, 강화의 정확한 의미는 다음과 같습니다.
인자로 전달된 컴포넌트(ReactComponent)에
- 새로운 props를 내려준다.
- 어떤 새로운 기능을 추가한다.
예를들어, 비동기로 데이터를 가져와서 UI에 바인딩해서 보여준다고 할때 데이터가 아직 서버로부터 도착하지 않으면 빙글빙글 돌아가는 스피너를 보여주고, 데이터가 도착하면 그 데이터를 콘솔에 찍는 Fetch라는 이름의 HOC로 만들 수 있습니다. 원래 아무런 기능이 없던 컴포넌트가 Fetch HOC를 거치면 다음과 같은 두 기능이 생기는것이죠.
- 데이터를 기다리는 동안 스피너를 보여주는 기능.
- 데이터가 도착하면 그 데이터를 콘솔에 찍는 기능.
그리고 보통 HOC는 with라는 이름과 함께 사용됩니다. (HOC의 이름을 짓는 규칙입니다.) 즉 위의 Fetch라고 하는 HOC는 사실 withFetch라고 하는게 더 좋은거죠.
그래서 HoC는 어떻게 생겼는데요?
아까 위에서 말했던 HoC를 구현해봅시다. https://codesandbox.io/s/nifty-bhabha-yphlt
Test컴포넌트가 withLoading이라는 HoC를 거쳐서 두가지 기능을 얻었습니다.
데이터를 로드 하는 동안 스피너가 보이고 로드되는 순간 전달된 테스트용 컴포넌트가 렌더링 됩니다.