render prop 패턴으로 자식 컴포넌트에 데이터 주입하기
계기
같이 듣자 프로젝트의 내가 만든 채널들과 구독한 채널들을 볼 수 있는 사이드바이다. 몇달전에 만든 거라 지금 보니 쑥쓰러울 정도로 이상하고 복잡하다.
코드 스플리팅을 하는 겸 괜찮은 아이디어가 떠올라서 블로깅해보려한다.
문제점
위의 코드에는 다음과 같은 문제점들이 있다.
- 데이터 패칭이 ChannelContainer 컴포넌트에서 이루어질 수 있음에도 부모에서 이루어져 불필요한 prop drilling이 생긴다는 것
- 1번과 이어져 ChannelContainer에서 데이터 패칭을 하려하는데 공통 컴포넌트라 몇가지 작업이 필요하는 것
- 프론트엔드에서 비동기 데이터 패칭 컴포넌트는 매우 중요하지만 바깥에서는 명시적으로 알 수 없다는 것
해결법 생각해보기
- ChannelContainer에 props로 문자열을 넘겨줘서 내부에서 분기처리하기
- ChannelContainer를 MyChannelContainer와 SubscribedChannelContainer로 나누기
- 이번 블로깅의 목적인 데이터 패칭 컴포넌트로 데이터 주입하기
선택과 이유
3번 아이디어를 선택했는데 이유는 다음과 같다
- 데이터 패칭 컴포넌트와 기존 컴포넌트를 분리해서 비동기 데이터 패칭 컴포넌트임을 더 명시적으로 보여주고 싶다.
- 만들어진 라이브러리를 사용할 때를 제외하고 타입스크립트의 제네릭을 제대로 써본적이 없어 한번 제대로 써보고 싶다.
- 1, 2번 아이디어는 너무 쉽다.
구현
DataFetcher 컴포넌트 코드
- render prop 패턴으로 구현 했다
- cloneElement으로도 구현할 수 있지만 공식문서에서 사용할 것을 추천하지 않는다.
- 제네릭
- T에는 비동기 데이터 패칭 컴포넌트에 주입될 데이터의 타입을 지정해줬다.
- P에는 비동기 데이터 패칭에 필요한 파라미터들의 타입을 지정해줬다.
- props
- fetchFunction은 구현해둔 리액트 쿼리 훅이 들어간다.
- params에는 리액트 쿼리 훅에 들어갈 파라미터들이 들어간다.
- render에는 실제로 렌더링 될 컴포넌트가 리턴이 될 화살표 함수가 들어간다
DataFetcher 컴포넌트 사용
후기
오히려 더 가독성이 안좋아지고 특별한 장점도 없는 것 같아서 안쓰기로 했다.
그래도 타입스크립트의 제네릭을 제대로 써보고, 여러가지 고민도 해본 것 같다.
Reference
https://ko.react.dev/reference/react/cloneElement