TypeScript
TypeScript union type으로 로딩 상태 깔끔하게 관리하기
로딩 상태를 여러 boolean으로 나누면 동기화 문제가 생긴다. union type으로 한 번에 하나의 상태만 가능하게 하자.
React에서 로딩, 에러, 성공 상태를 관리할 때 여러 boolean을 쓰면 항상 문제가 생긴다.
좋지 않은 방식: 여러 boolean
const [isLoading, setIsLoading] = useState(false);
const [isError, setIsError] = useState(false);
const [isSuccess, setIsSuccess] = useState(false);
문제는 이 상태들이 동시에 true일 수도 있다는 점이다. isLoading과 isError가 동시에 true면 화면에 뭘 보여줘야 할까?
좋은 방식: union type
type LoadingState = 'idle' | 'loading' | 'success' | 'error';
const [state, setState] = useState<LoadingState>('idle');
// 사용할 때
if (state === 'loading') {
return <Spinner />;
} else if (state === 'error') {
return <ErrorMessage />;
} else if (state === 'success') {
return <Success />;
}
이렇게 하면 한 번에 하나의 상태만 가능하고, 개발자가 실수할 수 없다.
데이터까지 포함하면 더 좋다
type LoadingState =
| { status: 'idle' }
| { status: 'loading' }
| { status: 'success'; data: User[] }
| { status: 'error'; error: Error };
이렇게 하면 success일 때만 data에 접근할 수 있고, error일 때만 error 메시지를 볼 수 있다. 타입 안정성이 최고다.