어디부터 어디까지가 view의 영역인가?
React를 이용해 어플리케이션을 만들다 보면, 보통 컴포넌트 단위로 코드를 작성하게 된다. 이 때 컴포넌트는 최대한 단순하게, 다시 말해 view 레이어(사용자 화면에 어떻게 표시될 것인지) 만을 담당할 수 있도록 설계하는 것이 좋다는 이야기를 들었다.
http 통신 로직 분리하기
예를 들어 백엔드로부터 event list 데이터를 받아오고, 이를 메인 페이지에 렌더링해서 보여주는 코드가 있다고 해보자. EventList 컴포넌트를 만들 때에는 다음과 같은 패턴이 가장 보편적이다.
export default function HomePage() {
const eventList = getAllEventList()
return <EventList list={eventList} />
}
- eventList를 요청하는 것과 관련된 모듈(파일, 클래스...)을 만든다. 여기에는 전체 list를 받아오거나, id를 이용해 특정 item 만을 받아오는 함수 등이 포함될 수 있다.
- EventList의 부모 컴포넌트(페이지 단위 컴포넌트)에서 함수를 호출하고, 그 데이터를 EventList의 props으로 전달한다.
- list 데이터를 EventList 컴포넌트에서만 사용하는 경우에도 컴포넌트를 최대한 단순하게 유지하기 위해 props을 이용하는 게 맞는걸까?
- EventList 컴포넌트 안에서 getAllEvents를 호출하는 것은 냄새나는 코드일까?
- page 단위의 상위 컴포넌트에서만 데이터를 받아오는 함수를 호출하는 것은 코드 일관성과 관련된 부분일까?
- EventList는 전달받은 prop을 가지고 페이지를 퍼블리싱하는(html + css) 역할만 한다.
아직 궁금한 점이 남아있기는 하지만, 결론은 http 통신은 view와 관련된 로직이 아니기 때문에, 컴포넌트 밖으로 분리한다는 것이다.
사용자와 상호 작용하는 로직 분리하기
사실 내가 진짜 궁금했던 것은 사용자와 상호 작용하는 로직이 View 레이어에 포함되는지, 아닌지이다.
// 1.
const handleSubmit = (event) => {
event.preventDefault()
const selectedYear = yearRef.current.value
const selectedMonth = monthRef.current.value
router.push(`/events/${selectedYear}/${selectedMonth}`)
}
// 2.
const handleSubmit = (event) => {
event.preventDefault()
const selectedYear = yearRef.current.value
const selectedMonth = monthRef.current.value
props.handleSearch(selectedYear, selectedMonth)
}
<FilterForm> 안에 작성된 handleSubmit 함수는 사용자가 form을 제출했을 때, 선택한 year/month에 맞는 데이터만 보여주는 filtered route로 페이지를 이동시키는 역할을 한다. 나는 첫 번째와 같이 코드를 작성했었는데, 강의 중에 강사님이 작성한 코드는 두 번째와 같았고, 그 이유가 무엇인지 궁금했다.
- 함수는 한 가지 일만 해야 하기 때문이다?
- 페이지를 이동하는 것은 view 레이어와 관련 없는 일이기 때문이다?
- <FilterForm> 컴포넌트가 하는 일이 페이지를 이동하는 것과 직접적인 관련이 없기 때문이라면, 관련이 있고 없고는 어떻게 결정하면 될까?
이게 내가 생각해 본 이유이긴 한데, 고민이 시원하게 해결된 것 같지는 않았다. 그런데 강의에서 나왔던 방식으로 코드를 리팩토링 하다보니 두번째 방식에서 다음과 같은 장점들을 찾아냈다.
- <FilterForm> 컴포넌트 안에서 useRouter를 호출하지 않아도 된다.
- router는 페이지 단위 컴포넌트에서 호출하는 것이 더 논리적이다.
- form의 상위 컴포넌트인 페이지 컴포넌트에서 router를 호출하고, handleSearch 함수를 prop으로 전달한다.
- <FilterForm> 컴포넌트는 input과 관련된 로직만 담당하게 된다.
결론
컴포넌트 안에서 코드를 작성할 때, 이 컴포넌트에서 이 로직을 다루는 것이 논리적인지, 아닌지 생각해 보는 것은 조금 어려웠다. 기준이 명확하지 않아서 그랬던 것 같다. 대신 여러가지 방식으로 일단 코드를 작성하고 나니까, 어떤 코드가 더 나은 코드인지 눈에 보이는 게 재미있었다!
'Study > React' 카테고리의 다른 글
react-firebase | authentication (0) | 2022.08.16 |
---|---|
Deployment | firebase hosting (0) | 2022.07.04 |
Validation (0) | 2022.06.27 |
custom Hooks (0) | 2022.06.24 |
HTTP Request (0) | 2022.06.23 |