반응형
요즘 새발자는 한창 채팅 기능을 유지보수 하는 중이다. (매우어렵 🤯)
채팅 기능에서 중요한 요소 중 하나는 마지막 메시지이다.
마지막 메시지를 채팅리스트에 출력하거나, 마지막 메시지를 통해 읽기 표시 등의 알림 설정 등을 할 수 있기 때문이다.
오늘은 채팅리스트에서 마지막 메시지를 함께 출력하는 기능을 공부한 내용을 토대로 포스팅해보려고 한다.
그럼 시작해보도록 하자
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;
반응형
'React' 카테고리의 다른 글
React(78) useEffect 에서 스크롤 이벤트 동작원리(feat. addEventListener) (0) | 2022.07.18 |
---|---|
React(77) 스크롤 시, 하위메뉴를 헤더 아래로 고정하기 (0) | 2022.07.12 |
React(75) shift + enter 줄바꿈 (feat. 두번씩 출력되는 버그처리) (1) | 2022.06.26 |
React(74) StoryBook으로 UI 컴포넌트 작업하기 (0) | 2022.06.20 |
React - useState 동작원리 이해하기 (0) | 2022.06.15 |
댓글