스파게티 코드 파티~

2024. 1. 29. 07:21개발

스파게티 코드는 겉으로 보기에는 작동 자체는 제대로 하거나 하는 것 처럼 보인다. 하지만 해당 코드는 추후 유지보수가 매우 어려워진다. 코드의 작동 방식을 변경하거나 버그를 찾거나 개선하는 등 코드를 수정하는 모든 작업에 방해가 된다.

 

특히 이러한 코드는 프로그래밍 초보자들이 많이 작성한다

보통 계획없이 바로 코딩을 시작하거나 요구사항이 원래 기획한 범위를 크게 벗어날 때  프로그래머알고리즘 구현 실력이 지나치게 떨어질 때 주로 출현한다  

-나무위키-

 

팀프로젝트,

명확한 초기 플랜 없이 바로 시작했고, 요구사항이 회의를 통해 원래 기획에서 벗어나서 귓속말이었지만 채팅이 되었고, 

알고리즘 구현 실력이 지나치게 떨어지는 ~

3관왕 달성~

 

하나의 useEffect에 여러개의 기능들이 혼재된 모습, 분리가 시급하다.

 

useEffect는 리액트 컴포넌트가 렌더링될 때마다 특정 작업을 수행하도록 설정할 수 있는 Hook이라고만 

알고 있었지, 하나의 useEffect에 하나의 기능만 의도 한다는 건 몰랐다.

 

이제 알았으니, 우선 아래 있는 코드부터 분리하고, 앞으로 코드 작성할때마다 계획을 명확히 하고, 하나의 기능만!! 이라고

떠올리면서 작성을 해야겠다.

 

 

  useEffect(() => {
    const fetchChatRooms = async () => {
      console.log('123')
      try {
        // 채팅방 ID 가져오기
        const { data: chatRoomsData, error: chatRoomsError } = await supabase.from('chats').select('*');

        if (chatRoomsError) throw chatRoomsError;

        // 각 채팅방에 대해 사용자의 닉네임과 마지막 메시지를 가져오기
        const updatedChatRooms = await Promise.all(
          chatRoomsData.map(async (chatRoom) => {
            const { data: chatUser, error: chatUserError } = await supabase
              .from('chats_users')
              .select('*')
              .eq('chat_id', chatRoom.id);

            if (chatUserError) throw chatUserError;

            //챗방 마지막 메시지
            const { data: lastMessageData, error: lastMessageError } = await supabase
              .from('messages')
              .select(`content, users(nickname), author_id,item_id`)
              .eq('chat_id', chatRoom.id)
              .order('created_at', { ascending: false })
              .limit(1)
              .maybeSingle();

              let sendNickname = '알 수 없음';
              let user_img = '알 수 없음';
              let product_img = '알 수 없음';
              let unread_count = 0;
              const author_id = lastMessageData ? lastMessageData.author_id : '알 수 없음';

              if (lastMessageData) {
                // lastMessageData가 있는 경우에만 sendNickname과 user_img 설정
                if (lastMessageData.author_id) {
                  const { data: userData, error: userError } = await supabase
                    .from('users')
                    .select('*')
                    .eq('id', lastMessageData.author_id)
                    .single();
                   
                  // console.log('lastMessageData',lastMessageData)
                  if (userError) throw userError;
                  if (userData) {
                    sendNickname = userData.nickname;
                    user_img = userData.user_img;
                  }
                }
         
                // lastMessageData가 있는 경우에만 product_img 설정
                if (lastMessageData.item_id) {
                  const { data: productData, error: productError } = await supabase
                    .from('products')
                    .select('product_img')
                    .eq('id', lastMessageData.item_id)
                    .maybeSingle();
         
                  if (productError) throw productError;
                  if (productData) {
                    product_img = productData.product_img;
                  }
                }
         
                // lastMessageData가 있는 경우에만 unread_count 설정
                const { data, error } = await supabase.rpc('count_unread_messages', { user_id: lastMessageData.author_id });
               
 
                if (error) {
                  console.error('읽지 않은 수 업데이트 오류:', error);
                } else {
                  unread_count = data?.unread_count || 0;
                }
              }
         
              return chatUser.map((chatUser) => ({
                author_id:author_id,
                chat_id: chatRoom.id,
                user_id: chatUser.user_id || '알 수 없음',
                item_id: chatUser.item_id || '알 수 없음',
                lastMessage: lastMessageData ? lastMessageData.content : '메시지가 없습니다.',
                sendNickname: sendNickname,
                user_img: user_img,
                unread_count: unread_count,
                created_at: chatUser.created_at,
                product_img: product_img,
              }));
            }),
          );
 
        const flatChatRooms = updatedChatRooms.flat();
 
        setChatRooms(flatChatRooms as ChatRoom[]);
      } catch (error) {
        console.error('채팅방 가져오기 오류:', error);
      }
    };
    // console.log('chatroom', chatRooms);
    fetchChatRooms();

    //챗방 메시지 가져오기
    const fetchMessages = async () => {
      if (chatId) {
        // Fetch all messages for the chatId
        let { data: messagesData, error: messagesError } = await supabase
          .from('messages')
          .select('*,users(*)')
          .eq('chat_id', chatId);

        // console.log('messagesData', messagesData);
        if (messagesError) {
          console.error('메시지를 가져오는 중 오류가 발생했습니다:', messagesError);
          return;
        }

        if (!messagesData) {
          setMessages([]);
          return;
        }

        setMessages(messagesData);
      }
    };

    fetchMessages();

    // 기존에 있던 chatRoom 값에 구독한 payload 업데이트
    const handleNewMessage = (payload: MessagePayload) => {
      setChatRooms((prevChatRooms) =>
        prevChatRooms.map((chatRoom) => {
          if (chatRoom.chat_id === payload.new.chat_id) {
            const unreadCount = unreadCounts.find((uc) => uc.chat_id === chatRoom.chat_id)?.unread_count || 0;
            // 새 메시지가 도착한 채팅방에 대한 처리
            return {
              ...chatRoom,
              lastMessage: payload.new.content, // 마지막 메시지를 새 메시지로 업데이트
              unread_count: unreadCount, // 새 메시지 표시 업데이트
            };
          } else {
            // 다른 채팅방에 대한 처리는 그대로 유지
            return chatRoom;
          }
        }),
      );
    };

    const handleNewMessageCount = (payload: MessagePayload) => {
      // 채팅 모달이 열려 있지 않을 때만 새 메시지 수를 증가
      if (!ChatBtnOpen) {
        setNewMessagesCount((prevCount) => prevCount + 1);
      }
    };

    //읽지않음 카운팅
    async function updateUnreadCount() {
      const {
        data: { user },
      } = await supabase.auth.getUser();
 
      if (!user?.id) {
        console.log('user not found');
      }
      const { data, error } = await supabase.rpc('count_unread_messages', { user_id: user?.id });
/
      if (error) {
        console.log('읽지 않은 수 업데이트 오류:', error);
      } else {
        setUnreadCounts(data);
      }
    }

    updateUnreadCount();

    //새 메시지 생성시 감지할 채널 구독
    const changes = supabase
      .channel('schema-db-changes')
      .on(
        'postgres_changes',
        {
          event: 'INSERT',
          schema: 'public',
          table: 'messages',
        },
        async (payload) => {
          console.log('payload', payload);
          fetchMessages();
          handleNewMessageCount(payload as MessagePayload);
          updateUnreadCount();
          // 새 메시지 카운트를 증가시킬지 결정하는 함수 호출
          handleNewMessage(payload as MessagePayload);
          //이거 열면 안됨
          // fetchChatRooms();
        },
      )
      .subscribe();

    // 채팅방 변경사항을 감지할 채널 구독
    const chatChannel = supabase
      .channel('chat-channel')
      .on('postgres_changes', { event: 'INSERT', schema: 'public', table: 'chats' }, (payload) => {
        fetchChatRooms();
      })
      .subscribe();

    return () => {
      changes.unsubscribe();
      chatChannel?.unsubscribe();
    };
  }, [chatId, ChatBtnOpen]);

 

'개발' 카테고리의 다른 글

채팅 입력시 끝 단어 2번 입력되는 현상을 발견.  (0) 2024.01.31
컴포넌트 분리 작업 중  (0) 2024.01.30
아 중요한 걸 빼먹었네.  (2) 2024.01.26
챗 추가 기능 수정 중  (0) 2024.01.25
챗 기능 1차 수정 중  (1) 2024.01.22