챗봇과의 소통에서 채팅을 봇과 유저를 구분하기 위해서 하나의 함수에서 set함수를 두번 사용하더니 첫번째로 호출한 것은 없어지고, 그 위로 두번째 호출한 set함수만 적용되는 현상을 발견했다!
type MessageType = {
text: string;
user: boolean;
};
const [message, setMessage] = useState<MessageType[]>([
{ text: "안녕하세요! 반갑습니다. 무엇이든 물어보세요!", user: false },
]);
다음과 같이 상태를 정의하였고, 이를 어떻게 message list에 추가했냐!
const Chat = () => {
const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
const userMessage = { text: event.currentTarget.message.value, user: true };
/* 1번 */
setMessage([...message, userMessage]);
const data = await postChatGpt(event.currentTarget.message.value);
const botMessage = { text: data.message, user: false };
/* 2번 */
setMessage([...message, botMessage]);
};
간단하다. message를 상태를 가져오고 뒤에 userMessage, botMessage를 붙여 추가했다
setMessage([...message, userMessage]);
이렇게 하면 안된다!!! 1번에서 추가한 다음에, 2번에서 또 추가하는게 아니라, 1번에서 추가한 것이 없어진다. 그냥!
이유에 대해서 하나씩 생각해보도록 하자!
message의 배열 참조를 다르게 보는 것 같다. 그렇다면 참조하는 것을 동일하게 보게 해주기 위해서 이전 message 배열을 보고, 그 배열을 그대로 넣어달라고 해야겠다라고 생각했다!
setMessage((prevMessage) => [...prevMessage, userMessage]);
매우 간단하게 해결!
대략적으로 찾아보니깐
setState 함수가 한번 호출되어 이전 배열을 새로운 배열로 업데이트한 후에 다시 호출되면, 또 다시 이전 배열을 기반으로 새로운 배열을 생성하고 두 배열을 병합하는 방식으로 업데이트를 수행하게 됩니다. 이렇게 되면, 이전에 추가된 요소가 새로운 배열에서 누락될 수 있습니다.
그렇다고 한다..!