List Type State에서 2번 set할 때 유의사항

1Jui.ce·2023년 4월 5일
0

챗봇과의 소통에서 채팅을 봇과 유저를 구분하기 위해서 하나의 함수에서 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 함수가 한번 호출되어 이전 배열을 새로운 배열로 업데이트한 후에 다시 호출되면, 또 다시 이전 배열을 기반으로 새로운 배열을 생성하고 두 배열을 병합하는 방식으로 업데이트를 수행하게 됩니다. 이렇게 되면, 이전에 추가된 요소가 새로운 배열에서 누락될 수 있습니다.

그렇다고 한다..!

profile
옷에 기름기 닦는 사람

0개의 댓글