메시지를 전송하면 화면에 2개씩 뜬다.
내가 뭔가 잘못 설정한 게 있는지 어제 한참 찾아봤었는데, 개발 환경에서는 원래 그런 것이었다.
useEffect
를 쓰면 개발 환경에서는 자동으로 2번 호출된다고 한다.
개발자의 실수를 막기 위해 그렇게 설정되어 있고, 설정을 끌 수도 있다고는 한다.
프론트엔드에서 보내는 chatMessage
객체와 백엔드의 Message
엔티티 간 필드가 일치하지 않을 수 있다.
그런 경우가 아니더라도 DTO를 사용하면 좋을 것 같기도 하다.
아무튼 이럴 때 형식에 맞게 처리하기 위해 DTO를 사용할 수 있다.
DTO로 받은 데이터를 백엔드에서 적절히 처리해서 Message
데이터를 저장하면 된다.
프론트엔드에 데이터를 전송할 때도 DTO를 사용한다.
필요한 정보만 포함해서 구성할 수 있다.
@Getter
@AllArgsConstructor
@NoArgsConstructor(access = PRIVATE)
public class ChatMessageRequest {
private String content;
private String sender;
}
@Getter
@RequiredArgsConstructor(access = PRIVATE)
public class ChatMessageResponse {
private final String content;
private final String sender;
private final LocalDateTime timestamp;
public static ChatMessageResponse of(final Message message) {
return new ChatMessageResponse(
message.getMessageText(),
message.getSender().getNickname(),
message.getCreatedAt()
);
}
}
@Transactional
public ChatMessageResponse saveMessage(final Long roomId, final ChatMessageRequest chatMessageRequest) {
ChatRoom chatRoom = chatRoomRepository.findById(roomId).orElseThrow(() -> new ChatException(NOT_FOUND_CHATROOM_ID));
Member sender = memberRepository.findByNickname(chatMessageRequest.getSender()).orElseThrow(() -> new AuthException(INVALID_AUTHORITY));
Message message = new Message(
chatRoom,
sender,
chatMessageRequest.getContent()
);
Message messageResult = messageRepository.save(message);
return ChatMessageResponse.of(messageResult);
}
현재 채팅방 정보를 불러와서 현재 유저 정보와 비교하면 연락하는 상대를 알 수 있다.
현재 채팅방 데이터를 가져오기 위해 사용자 정의 훅을 생성했다.
메시지 전송 시간을 표시하기 위해 메시지가 저장된 후 생성되는 createdAt
필드를 사용하기로 했다.
따라서 메시지를 전송하는 함수(sendMessage
)에 있는 setMessages
를 제거했다.
서버로부터 메시지를 수신하는 부분에서만 setMessages
를 사용해서 메시지 상태를 업데이트하게 변경했다.