Skip to content

게임 종료된 상태에서 사용자 게임 참여 여부에 따른 FinalResult 분기 처리

최수연 (SooYeon Choi) edited this page Aug 22, 2024 · 1 revision

현재 이벤트에 대한 선착순 밸런스 게임이 종료된 상태에서 사용자의 게임 참여 여부에 따라 결과 창을 다르게 보여주도록 구현했다.

원래는 해당 부분에 있어서 아예 사용자가 참여하지 않은 경우에는 /event/rush/result API 에서 400 오류가 발생했다. 하지만 사용자가 참여하지 않은 경우에도 결과 데이터가 필요하기 때문에 백엔드와 상의한 결과, 우선 서버에서는 /event/rush/result API에서 사용자가 게임을 참여하지 않은 경우에 isWinner, rank, totalParticipants 이 3개의 값에 대해서 null로 처리되도록 결정됐다.

클라이언트에서는 비록 isWinner, rank, totalParticipants 이 3개의 값이 null로 오지만, 애초에 사용자 게임 참여 여부가 boolean 값으로 응답오는 getRushUserParticipationStatus API가 있기 때문에 해당 API를 처음 게임 화면 진입할 때에 호출하여 Context에 gameState.userParticipatedStatus를 설정해주도록 하였다.

따라서, 다음과 같이 useFetch 훅을 통해 getRushUserParticipationStatus API를 호출해주고 다음과 같이 isSuccessUserParticipationStatus가 true일 때만 setUserParticipationStatus 함수가 호출되도록 했다.

그리고 isSuccessUserParticipationStatus가 fasle일 때는 화면을 Loading 처리해주고, true되면 컴포넌트가 보여지도록 구현했다.

const { gameState, setUserParticipationStatus } = useRushGameContext();

const { 
	data: userParticipatedStatus, 
	isSuccess: isSuccessUserParticipationStatus, 
	fetchData: getRushUserParticipationStatus
} = useFetch<
    GetRushUserParticipationStatusResponse,
    string
>((token) => RushAPI.getRushUserParticipationStatus(token));

useEffect(() => {
    getRushUserParticipationStatus(cookies[COOKIE_KEY.ACCESS_TOKEN]);
}, []);

useEffect(() => {
    if (isSuccessUserParticipationStatus) {
        setUserParticipationStatus(userParticipatedStatus);
    }
}, [userParticipatedStatus, isSuccessUserParticipationStatus]);

const renderRushGameContent = () => {
    switch (gameState.phase) {
        case CARD_PHASE.NOT_STARTED:
            return <Countdown />;
        case CARD_PHASE.IN_PROGRESS:
		        if (!isSuccessUserParticipationStatus) {
			        return <div>Loading...</div>;
		        } else {
	            if (!gameState.userParticipatedStatus) {
	                return <CardOptions />;
	            } else {
	                return <SelectedCard unblockNavigation={unblockNavigation} />;
	            }
            }
        case CARD_PHASE.COMPLETED:
            return <FinalResult unblockNavigation={unblockNavigation} />;
        default:
            return null;
    }
};

그러나 문제는 제대로 동작하지 않는다는 것이었는데, 그 이유가 userParticipatedStatus 데이터 값 자체가 그냥 true/false만 오기 때문에 useFetch 내부에서는 아예 isSuccess를 반환할 때 setIsSuccess(!!data); 이런 방식으로 데이터 자체를 boolean으로 바꾸어서 내보낸다. 따라서 사용자가 아직 참여하지 않은, 즉 data가 false 이면 isSuccess 자체가 false로 반환되어 동작을 안하는 것이었다.

그래서 아예 isSuccess를 사용하지 않고 데이터가 null 이 아닌 경우에만 setUserParticipationStatus 함수가 호출되도록 바꿔주었다.

const { gameState, setUserParticipationStatus } = useRushGameContext();

const { data: userParticipatedStatus, fetchData: getRushUserParticipationStatus } = useFetch<
    GetRushUserParticipationStatusResponse,
    string
>((token) => RushAPI.getRushUserParticipationStatus(token));

useEffect(() => {
    getRushUserParticipationStatus(cookies[COOKIE_KEY.ACCESS_TOKEN]);
}, []);

useEffect(() => {
    if (userParticipatedStatus !== null) { // 조건문 수정
        setUserParticipationStatus(userParticipatedStatus);
    }
}, [userParticipatedStatus]); // 의존성 배열 수정

const renderRushGameContent = () => {
    switch (gameState.phase) {
        case CARD_PHASE.NOT_STARTED:
            return <Countdown />;
        case CARD_PHASE.IN_PROGRESS:
		        if (userParticipatedStatus === null) return <></>; // 조건문 수정
		        else {
	            if (!gameState.userParticipatedStatus) {
	                return <CardOptions />;
	            } else {
	                return <SelectedCard unblockNavigation={unblockNavigation} />;
	            }
            }
        case CARD_PHASE.COMPLETED:
            return <FinalResult unblockNavigation={unblockNavigation} />;
        default:
            return null;
    }
};

📚 학습 정리

🗂️ 멘토링

Clone this wiki locally