본문 바로가기
React

React(76) TypeScript - 채팅목록에서 마지막 메시지 보여주기

by 새발개발JA 2022. 6. 27.
반응형

 

 

요즘 새발자는 한창 채팅 기능을 유지보수 하는 중이다. (매우어렵 🤯)

채팅 기능에서 중요한 요소 중 하나는 마지막 메시지이다.

마지막 메시지를 채팅리스트에 출력하거나, 마지막 메시지를 통해 읽기 표시 등의 알림 설정 등을 할 수 있기 때문이다.

오늘은 채팅리스트에서 마지막 메시지를 함께 출력하는 기능을 공부한 내용을 토대로 포스팅해보려고 한다.

그럼 시작해보도록 하자

 

이미지 출처(카카오)

 

 

 


 

React(76) 채팅목록에서 마지막 메시지 보여주기

 

채팅리스트에 마지막 메시지를 가져와 채팅목록에서 같이 보여주자.

 

 

 MessageList.tsx

먼저, api 로 채팅리스트를 get 해서 채팅방 목록을 배열로 받아오고,

각각의 채팅방의 정보를 또 받아와서 마지막 메시지를 추가해줄 것이다.

interface MessageProps {
  msg: Message;			// 부모로 받은 props 타입 인터페이스를 선언
}

interface MessageInfo {	 	// MsgItem 객체 값의 타입 인터페이스를 선언
  id: string;
  memberID: string;
  memberName: string;
  lastMsg?: string | null;
}

const MessageList = (props: MessageProps): ReactElement => {
  const [chatMsgList, setChatMsgList] = useState<MesssageInfo[]>([]); // props 로 받아온 객체를 담을 변수
  const history = useHistory();		// url 이동을 할 수 있는 useHistory() 를 선언하자
  const dispatch = useDispatch();	// 리덕스를 소환할 수 있는 useDispatch() 를 선언하자
  
  useEffect(() => {
    getMsgList(props.msg); 		// 첫 렌더링 시 props 데이터를 넣고 아래 함수를 실행
  }, []);

  async function getMsgList(msg: Message) {
    const chatMsgs: MessageInfo[] = [];		// 메시지 객체를 담을 빈 배열을 선언
    
    if (!msg || msg.length === 0) {		// 메시지 객체가 없을 때의 예외 처리
      return;
    }
   
    for (let i = 0; i < msg.length; i++) {	// props 배열 안의 객체를 하나씩 검사하기
      let dup = false;				// dup 이라는 변수를 false 로 두고 

      for (let j = 0; j < msg.length; j++) {	// 한번 더 객체 배열을 돌려서 
        if (msg.id === chatMsgs[j].id) {	// 만약 props의 id 값과 chatMsgs 의 id 값이 같으면
          dup = true;				// dup 를 true 로 바꾸고
          break;				// 빠져나오자
        }
      }

      if (!dup) {				// dup이 false 이라면
        chatMsgs.push({				// chatMsgs 에 props 객체의 값을 추가
          id: msg.id,
          memberID: msg.member.id, 
          memberName: msg.member.name
        });
      });
      }
    }
    
    await setLastMsg(chatMsgs);	// 마지막 메시지를 같이 불러오자
    setChatMsgList(chatMsgs);   // 위에서 만든 chatMsgs 배열을 chatMsgList 변수 안에 담자
    return;
  }

  // 라스트 메시지 불러오는 로직
  async function setLastMsg(msgs: MessageInfo[]) { // 위 로직에서 생성한 배열
    if (msgs.length === 0) {		           // 매개변수인 chatMsgs 의 내용이 없을 때 예외처리
      return;
    }

    let query = '';				// query 변수를 빈칸으로 선언
    for (let i = 0; i < msgs.length; i++) { // chatMsgs 객체를 검사하기
      query += `&id=${msgs[i].id}`;		// 쿼리문을 만들기 위해 id를 추가 또 추가한다
    }
    query = query.replace('&', '?');		// replace 함수를 통해 & 를 ? 로 변경해준다.

    try {
      const res = await http.get( 
        `${API}/message${query}` 		// 위에서 완성한 query 변수를 넣어온 api 로 데이터를 받아온다
      );
      if (res.status !== 200) {
        throw new Error(`Response status is "${res.status}"`);
      }
      if (res.data.resultCode !== '0200') {
        throw new Error(`ResultCode is "${res.data.resultCode}"`);
      }

      for (let i = 0; i < res.data.resultData.length; i++) {
        const chat: Chat = JSON.parse( 			// chat 객체안에 받아온 데이터를 하나씩 담아보자
          JSON.stringify(res.data.resultData[i])
        );
        if (chat.lastMsg) { 				// 만약 통신로직으로 받아온 chat 객체에 lastMsg가 있으면
          for (let j = 0; j < chats.length; j++) {      // 검사를 한바퀴돌리고 
            if (chat.lastMsg.id === chatMsgs[j].id) {   // chat의 lastMsg의 id 와 chatMsg의 id 가 같으면
              chatMsgs[j].lastMsg = chat.lastMsg;       // chatMsgs의 lastMsg를 chat.lastMsg 로 넣어주고
              break;				  	// 빠져나오기
            }
          }
        }
      }
    } catch (e) {				// 통신 실패시
      alert('정보를 가져오는데 실패하였습니다.')   	// 안내 경고창과 함께
      console.error(e) 				// 콘솔에 에러 메시지 출력 
    } 
  }
  
    return (
    <li>
      {chatMsgList.map(chatMsg => (
        <div onClick={() => selectChatRoom(props.msg, chatMsg.id) key={chatMsg.id}}>     
       	  <div className="profile"><img src={memberImage} /></div>    
          <div className="name">{chatMsg.memberName}</div>
          <div className="last-msg">{chatMsg.lastMsg}</div>
        </div> 
      )}
    </li>
  );
};

export default MessageList;

 

 

 

반응형

댓글