ReferenceError: Cannot access 'xxx' before initialization

henry·2024년 9월 25일

문제 상황

함수를 호출하는 코드가, 해당 함수를 정의하기 전에 실행되었기 때문에 발생된 에러.


문제 분석

const handleSubmit = async (e) => {
      e.preventDefault();

      //메세지 입력 없이 전송한 경우
      if (!content) {
         setErrors((prev) => prev.concat('메세지 내용을 입력해 주세요.'));
         return; //에러 발생 시, 이 위치에서 진행 종료
      }
      setLoading(true);

      //farebase에 message를 저장하는 부분
      try {
         console.log('currentChatRoom.id : ', currentChatRoom.id);
         console.log('messagesRef : ', messagesRef);
         await set(
            push(child(messagesRef, currentChatRoom.id)),
            createMessage(),
         );
         setLoading(false);
         setContent('');
         setErrors([]);
      } catch (error) {
         console.log(error);
         setErrors((prev) => prev.concat(error.message));

         setLoading(false);
         setTimeout(() => {
            setErrors([]);
         }, 5000);
      }

      const createMessage = (fileUrl = null) => {
         const message = {
            timestamp: serverTimestamp(),
            user: {
               id: currentUser.uid,
               name: currentUser.displayName,
               image: currentUser.photoURL,
            },
         };
         if (fileUrl !== null) {
            message['image'] = fileUrl;
         } else {
            message['content'] = content;
         }
      };
   };

소스 코드를 보면,
createMessage 함수가 handleSubmit 함수 내부에서 호출되고 있지만
실제로는 그 함수가 handleSubmit 함수 내에서 선언된 후에 호출되어야 한다.
즉, createMessage를 먼저 선언한 뒤에 사용해야한다.


문제 해결

수정된 소스 코드

//외부에 함수 선언
const createMessage = (fileUrl = null) => {
      const message = {
         timestamp: serverTimestamp(),
         user: {
            id: currentUser.uid,
            name: currentUser.displayName,
            image: currentUser.photoURL,
         },
      };
      if (fileUrl !== null) {
         message['image'] = fileUrl;
      } else {
         message['content'] = content;
      }
   };

   const handleSubmit = async (e) => {
      e.preventDefault();

      //메세지 입력 없이 전송한 경우
      if (!content) {
         setErrors((prev) => prev.concat('메세지 내용을 입력해 주세요.'));
         return; //에러 발생 시, 이 위치에서 진행 종료
      }
      setLoading(true);

      //farebase에 message를 저장하는 부분
      try {
         console.log('currentChatRoom.id : ', currentChatRoom.id);
         console.log('messagesRef : ', messagesRef);
         await set(
            push(child(messagesRef, currentChatRoom.id)),
            createMessage(),
         );
         setLoading(false);
         setContent('');
         setErrors([]);
      } catch (error) {
         console.log(error);
         setErrors((prev) => prev.concat(error.message));

         setLoading(false);
         setTimeout(() => {
            setErrors([]);
         }, 5000);
      }
   };

0개의 댓글