Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions src/components/Common/GameListCarousel/GameListCarousel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,13 @@ import {
GameListCard,
} from '@/components';
import { PATH } from '@/constants/router';
import { SOCKET } from '@/constants/websocket';
import { useToast } from '@/hooks/useToast';
import { cn } from '@/lib/utils';
import { createRoom } from '@/services/rooms';
import useModalStore from '@/store/useModalStore';
import useRoomStore from '@/store/useRoomStore';
import useSocketStore from '@/store/useSocketStore';
import { GameResponse } from '@/types/api';

interface GameListCarouselProps {
Expand All @@ -29,8 +31,9 @@ const GameListCarousel = ({ games }: GameListCarouselProps) => {
const router = useRouter();
const { toast } = useToast();

const { setRoomId, setGameId } = useRoomStore();
const { setRoomId } = useRoomStore();
const { closeModal } = useModalStore();
const { sendMessage } = useSocketStore();

const [isClicked, setIsClicked] = useState(false);

Expand Down Expand Up @@ -62,7 +65,16 @@ const GameListCarousel = ({ games }: GameListCarouselProps) => {

const handleChangeGame = (gameId: string) => {
if (isClicked) return;
setGameId(gameId);

if (sendMessage) {
sendMessage({
destination: `${SOCKET.ROOM.CHANGE_GAME}`,
body: {
gameId,
},
});
}

closeModal();
setIsClicked(true);
};
Expand Down
29 changes: 9 additions & 20 deletions src/components/Common/GameRoom/GameRoomController.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ import { useEffect } from 'react';

import { Spinner } from '@/components';
import { PATH } from '@/constants/router';
import { SOCKET } from '@/constants/websocket';
import { useFetchRoomDetail } from '@/hooks/queries';
import { useToast } from '@/hooks/useToast';
import { EnterRoomProps } from '@/hooks/useWebSocket';
import useRoomStore from '@/store/useRoomStore';
import useSocketStore from '@/store/useSocketStore';
import { ChatMessage } from '@/types';

import GameRoomView from './GameRoomView';
Expand All @@ -37,14 +37,21 @@ const GameRoomController = ({

const { data: roomDetail, error, isError } = useFetchRoomDetail(roomId);

const { myName, setHostName, gameId } = useRoomStore();
const { myName, setHostName } = useRoomStore();
const { setSendMessage } = useSocketStore();

const isRoomManager = roomDetail.players.some(
(player) => player.name === myName && player.isHost
);
const isSelfInPlayers =
roomDetail.players.findIndex((user) => user.name === myName) !== -1;

useEffect(() => {
if (sendMessage) {
setSendMessage(sendMessage);
}
}, [sendMessage, setSendMessage]);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

setSendMessage 함수는 Zustand store에서 반환된 setter 함수로, 컴포넌트의 생명주기 동안 항상 동일한 참조를 유지합니다. 따라서 useEffect의 의존성 배열에 포함하지 않아도 괜찮습니다. 의존성 배열을 간소화하여 코드 가독성을 높이고 불필요한 재실행 가능성을 줄일 수 있습니다.

  useEffect(() => {
    if (sendMessage) {
      setSendMessage(sendMessage);
    }
  }, [sendMessage]);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

완료


useEffect(() => {
if (roomDetail.players.length > 0) {
const host = roomDetail.players.find((player) => player.isHost);
Expand All @@ -69,24 +76,6 @@ const GameRoomController = ({
}
}, [myName, roomDetail]);

useEffect(() => {
sendMessage({
destination: `${SOCKET.ROOM.CHANGE_PLAYER_NAME}`,
body: {
name: myName,
},
});
}, [myName]);

useEffect(() => {
sendMessage({
destination: `${SOCKET.ROOM.CHANGE_GAME}`,
body: {
gameId,
},
});
}, [gameId]);

// @TODO: 더 선언적으로 error를 처리할 수 있는 방법 찾기
useEffect(() => {
if (isError) {
Expand Down
19 changes: 16 additions & 3 deletions src/components/ModalList/CreateUserNameModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,18 @@ import {
ModalShell,
} from '@/components';
import { STORAGE_KEY } from '@/constants/storage';
import { SOCKET } from '@/constants/websocket';
import { useLocalStorage } from '@/hooks/useLocalStorage';
import { useToast } from '@/hooks/useToast';
import useModalStore from '@/store/useModalStore';
import useRoomStore from '@/store/useRoomStore';
import useSocketStore from '@/store/useSocketStore';

const CreateUserNameModal = () => {
const { closeModal } = useModalStore();
const { setItem } = useLocalStorage();
const { myName, setMyName } = useRoomStore();
const { sendMessage } = useSocketStore();
const { toast } = useToast();

const formSchema = z.object({
Expand Down Expand Up @@ -52,14 +55,24 @@ const CreateUserNameModal = () => {
description: '기존 닉네임과 다른 닉네임을 입력해주세요.',
});
} else {
setMyName(values.username);
setItem(STORAGE_KEY.NICKNAME, values.username);
closeModal();

if (sendMessage) {
sendMessage({
destination: `${SOCKET.ROOM.CHANGE_PLAYER_NAME}`,
body: {
name: values.username,
},
});
}

toast({
variant: 'success',
title: '닉네임 변경 성공',
description: `${values.username}님, 그루파이별에 오신 것을 환영해요!`,
});
setMyName(values.username);
setItem(STORAGE_KEY.NICKNAME, values.username);
closeModal();
}
};

Expand Down
10 changes: 0 additions & 10 deletions src/store/useBalanceGameStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ interface BalanceGameStoreProps {
round: BalanceGameRoundResponse;
selectedPlayers: string[];
setRound: (round: BalanceGameRoundResponse) => void;
setTotalRounds: (count: number) => void; // @TODO: 추후에 완전 삭제 필요
addSelectedPlayers: (player: string) => void;
resetSelectedPlayers: () => void;
}
Expand All @@ -20,20 +19,11 @@ const useBalanceGameStore = create<BalanceGameStoreProps>((set) => ({
currentRound: 0,
playSeconds: 0,
},

selectedPlayers: [],
setRound: (round: BalanceGameRoundResponse) =>
set({
round,
}),

setTotalRounds: (count) =>
set((state) => ({
round: {
...state.round,
totalRounds: count,
},
})),
addSelectedPlayers: (player) =>
set((state) => ({
selectedPlayers: [...state.selectedPlayers, player],
Expand Down
8 changes: 0 additions & 8 deletions src/store/useQnaGameStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ interface BalanceGameStoreProps {
round: QnaGameRoundResponse;
submittedPlayers: string[];
setRound: (round: QnaGameRoundResponse) => void;
setTotalRounds: (count: number) => void; // @TODO: 추후에 완전 삭제 필요
addSubmittedPlayer: (playerId: string) => void;
clearSubmittedPlayers: () => void;
reset: () => void;
Expand All @@ -23,13 +22,6 @@ const useQnaGameStore = create<BalanceGameStoreProps>((set) => ({
set({
round,
}),
setTotalRounds: (count) =>
set((state) => ({
round: {
...state.round,
totalRounds: count,
},
})),
addSubmittedPlayer: (playerId) =>
set((state) => ({
submittedPlayers: [...state.submittedPlayers, playerId],
Expand Down
2 changes: 0 additions & 2 deletions src/store/useRoomStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ interface RoomStoreProps {
myName: string;
setRoomStatus: (status: roomStatusType) => void;
setRoomId: (id: string) => void;
setGameId: (id: string) => void;
setHostName: (name: string) => void;
setMyName: (name: string) => void;
getHostName: () => string | null;
Expand All @@ -26,7 +25,6 @@ const useRoomStore = create<RoomStoreProps>((set, get) => ({
myName: '',
setRoomStatus: (status) => set({ roomStatus: status }),
setRoomId: (id) => set({ roomId: id }),
setGameId: (id) => set({ gameId: id }),
setHostName: (name) => set({ hostName: name }),
setMyName: (name) => set({ myName: name }),
getHostName: () => get().hostName,
Expand Down
22 changes: 22 additions & 0 deletions src/store/useSocketStore.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import * as StompJS from '@stomp/stompjs';
import { create } from 'zustand';

interface SocketStoreProps {
sendMessage:
| (<T>(params: Omit<StompJS.IPublishParams, 'body'> & { body?: T }) => void)
| null;
setSendMessage: (
sendFn:
| (<T>(
params: Omit<StompJS.IPublishParams, 'body'> & { body?: T }
) => void)
| null
) => void;
}

const useSocketStore = create<SocketStoreProps>((set) => ({
sendMessage: null,
setSendMessage: (sendFn) => set({ sendMessage: sendFn }),
}));

export default useSocketStore;