일단 코드를 한번 보자.
const 페이지컴포넌트 = () => {
const {
state: {
상태1,
상태2,
상태3,
상태4,
},
ref: {
// ref...
},
handler: {
// handler 함수...
},
} = 페이지커스텀훅();
if (상태1이 없다면) {
return <Loading />
}
return(
// UI 로직...
)
}
컴포넌트의 구조는 State Waterful방식으로 최상단 페이지 컴포넌트에서 모든 API 요청을 응답받고 그에 대한 상태로 화면을 그려주는 방식이다. 즉, 최상단 컴포넌트인 페이지 컴포넌트에서 모든 상태를 관리하고 하위 컴포넌트로 내려주는 구조이다.
이 구조는 장단점이 존재한다.
또한 단점도 존재한다.
Suspense
를 활용하지 못한다. Suspense
의 children이 promise가 pending 상태면 fallback을 렌더링하고 promise가 fulfilled되면 children을 다시 렌더링한다. 그런데 children에서는 promise를 실행하지 않기에 Suspense
가 동작하지 않는다. 그렇게 되면 선언적으로 코드를 작성하기 어렵다. loading
상태와 error
상태는 useState
를 통해 정의하고 if문으로 분기처리하여 loading
, error
상태에 따라 화면을 보여줘야 하기 때문이다. Suspense
의 내부 코드를 살펴보면 if문으로 분기처리를 하면서 상태를 throw한다. 결국 선언적인 코드는 명령적인 코드를 추상화한 것이다. 그래서 Suspense
대신해서 loading
, error
처리하는 컴포넌트로 children(화면에 보이는 컴포넌트)를 감싸주어도 Suspense와 비스무리하게 동작할 수 있다.const 페이지컴포넌트 = () => {
const {
state: {
상태1로딩,
상태2로딩,
상태3로딩,
상태1,
상태2,
상태3,
},
ref: {
// ref...
},
handler: {
// handler 함수...
},
} = 페이지커스텀훅();
return(
<CustomSuspense
상태1로딩={상태1로딩}
상태2로딩={상태2로딩}
상태3로딩={상태3로딩}
>
// UI 로직...
</CustomSuspense>
)
이처럼 loading과 error를 상태로 만들고 CustomSuspense
라는 컴포넌트에 props로 상태를 넣어주면 Suspense와 비스무리하게 동작한다. 그러나 이 또한 세가지 문제가 남아있다.
loading
과 error
상태를 만들어줘야하는 문제가 발생한다. 커스텀 훅에서 CustomSuspense
으로 props 또한 넘겨줘야 한다.CustomSuspense
에서 loading
컴포넌트를 띄워주고 API 요청이 성공해 loading
상태가 false가 되었다면 그제서야 children을 그려주는 문제가 있다. 사용자 측면에서 불편을 느낄 수 있다는 것이다.const 페이지컴포넌트 = () => {
const {
상태1,
상태1hadnler함수
} = 상태1커스텀훅();
return(
<>
// UI 로직 ...
<Suspense fallback={<Loading />}
<상태2와3보여주는컴포넌트 />
</Suspense>
</>
)
const 상태2와3보여주는컴포넌트 = () => {
const { 상태2 } = 상태2커스텀훅();
const { 상태3 } = 상태3커스텀훅();
return (
// UI 로직...
)
}
이제 페이지 컴포넌트에서 모든 상태를 지니고 있지 않는다. 컴포넌트에 종속되어야하는 상태는 해당 컴포넌트에 존재한다. API 요청으로 상태를 결정하는 경우에는 Suspense를 동작시킨다.
리펙터링을 마치고 나니 코드가 간결하지고 선언적으로 작성됨을 느낄수 있었다. 그렇다고 이전의 구조 틀렸다고는 생각하지 않는다. 왜냐하면 현재 리펙터링한 페이지는 모든 컨텐츠가 로드되야 사용자가 정상적으로 사용할 수 있는 페이지이기 때문이다. 여러 컨텐츠 중에 하나라도 로드되지 않는다면 사용하는 입장에서는 사용 의미가 퇴색되기 때문이다. 컴포넌트 구조, 커스텀 훅 구조에는 정답이 없지만 React를 쓰는 입장으로 React가 추구하려는 방향으로 프로그래밍을 하는 것이 React를 잘 쓴다고 할 수 있지 않을까?