-
Notifications
You must be signed in to change notification settings - Fork 0
Context와 HOC를 사용할 때 발생하는 타입 재검증 문제 #8
Comments
Main에서 사용되는 useUserState에서는 타입이 TS에서 인식되는 타입은 |
function temp(a: string | number) {
return a;
}
const b = 'wanted';
const c = temp(b); // c 는 여전히 string | number 입니다 useState 의 타입 function useState<S>(initialState: S | (() => S)): [S, Dispatch<SetStateAction<S>>];
// 이 경우 S 는 UserState useState 의 state 를 참조하는곳 에서는 UserState 의 두 가지 타입을 모두 고려하기 때문에 |
@yeongi @powercording 두 분 다 답변 고맙습니다. HOC에서 이미 검증을 거치고 있기에 |
@ohcmadah 그렇군요. Profile.tsx 의 Main 도 함수이니 항상 withAuth 안에서만 호출되지 않고 다른 곳 에서도 호출될 수 있다는 상황을 생각해 본다면 어떨까요 |
@powercording 그 부분은 고려하지 못했었네요. 그렇게 생각하면 오히려 narrowing이 필요한 상황이네요. |
안녕하세요, 다들 적극적으로 의견 교환하시는 모습이 너무 보기좋네요 :), 질문 및 의견들 읽어보고 검토해본 결과 제 의견도 기존에 나온 의견들과 대부분 일치하는 것 같네요, 저의 개인적인 생각과 왜 그렇게 생각하는지에 대해서 말씀드릴테니, 다른 동기분들도 다른 의견 있으시면 적극적으로 남겨주시면 좋을 것 같아요 일단 결론부터 말씀드리자면, 저는 지금처럼 컴포넌트에서 검증과정을 거치는 방향으로 진행할 것 같습니다. 그 이유는 일단 useUserState는 user가 있을때와 없을 때 둘다 사용되어야 하는 상황이기에 지금처럼 user가 null이거나, User타입일 수 있도록 설정해주는 것이 맞아 보입니다. 그러다보니, Main 컴포넌트에서도 useUserState를 사용할 때 user가 null이거나, User타입인 경우를 모두 처리하는 것이 맞아보이고요, 여러분들의 의견 남겨주신 것 처럼 지금은 전체 코드의 리다이렉트 과정을 모두 연관해서 생각하고 있기에 Main이 user의 정보가 있을때만 사용된다고 가정하고 있지만 Main만 별도로 떼서 독립적으로 봤을 때 Main은 본인이 user의 정보가 있을 때 사용되는지, 없을 때 사용되는지 확신할 수 없기에 여기서는 지금처럼 user의 정보가 있는지 확인하는 과정을 거치는 게 좋아보입니다. 그래야지 Main이 정확히 동작한다는 확신을 가질 수 있고, 다른 컴포넌트나 로직들과 결합되지 않고 독립적으로 스스로의 동작을 유지할 수 있을 것 같고 추후 다른 코드의 변경에 영향을 받지 않을 수 있을 것 같네요 지금은 Main에서 검증 과정을 빼버리면, Main이 제대로 동작하기 위해서는 "Main이 Profile의 자식이다." 그리고 "Profile은 withAuth 처리가 되어있다." 라는 두가지 다른 정보들을 모두 이해하고 이게 전제되었을때만 제대로 동작하고 만약 저 둘 중 하나라도 변경되게 된다면 Main 컴포넌트가 런타임에서 의도한대로 동작하지 않게 되는 상황이 발생할 것 같네요. 다만, Main 컴포넌트에서 검증은 하되, Main에서 필요한 검증은 사실 내가 쓰려고 하는 const Main = () => {
const userState = useUserState();
return <main>id: {userState.user?.id}</main>;
}; 또는 user.property로 접근하는 코드가 많을 경우 일괄 처리하기 위해서 하나의 if문으로 처리 const Main = () => {
const userState = useUserState();
if (userState.user) {
return (
<main>
<div>id: {userState.user.id}</div>
<div>name: {userState.user.name}</div>
</main>
);
}
}; 이렇게 하면 Redirect에 대한 책임은 온전히 withAuth로 분리되고, Main의 경우에는 user의 필요한 정보를 렌더링하는 책임만을 가지고 그 과정에서 필요한 정보가 제대로 있는지 확인하는 과정만 거치기에 역할이 잘 분리되었다고 판단되고, 추후 Main이 User가 없는 상황에서 접근되는 일이 발생하더라도 잘못된 동작(null의 속성에 접근하려고 하는)이 발생하지 않기 때문에 런타임에서 오류도 발생하지 않을 것이라 확신할 수 있을 것 같네요 위와 동일한 이유로, 다른 User에 대한 정보에 접근하는 컴포넌트들도 동일한 처리를 진행해줄 것 같네요 그리고 이러한 과정이 너무 자주 반복된다라고 생각이 된다면 지금 처리하신 것 처럼useAuthenticatedState 같은 User의 정보가 있을때만 user를 리턴해주고 아니면 예외를 던지는 함수를 만들어서 처리하는 방법도 옵션으로 고려해볼 만한다고 봅니다. |
안녕하세요! TypeScript 세션 시간에 드렸던 질문인데, 예시 코드 첨부하여 재질문 드립니다.
로그인 여부에 따른 Redirect를 HOC로 구현하였습니다. 로그인 검증이 완료된 컴포넌트 내에서 유저 정보를 사용할 때는 Props Drilling 해결을 위해 만든 UserContext의 state를 커스텀 훅을 통해 가져오는 방식입니다. state type은 다음과 같습니다.
검증이 완료된(isAuthenticated === true) 컴포넌트 내에서의 state는
{ isAuthenticated: true; user: User }
인데, 막상 커스텀 훅을 통해 가져오면{ isAuthenticated: true; user: User } | { isAuthenticated: false; user: null }
이라 또 검증을 거쳐야 하는 문제가 발생했습니다.이 경우 다시 검증하는 게 최선인지 궁금합니다.
저는
useAuthenticatedState
라는 커스텀 훅을 하나 더 만들어서 검증이 완료되었을 때의 state만을 가져오는 방식으로 해결해 두었었는데, 더 나은 방법이 있을까요?코드는 프리온보딩 이전에 작성했던 거라 부족한 점이 많은데 양해 부탁드립니다.
UserContext.tsx
withAuth
Profile.tsx
The text was updated successfully, but these errors were encountered: