퀴즈! 렌더링이 되지 않는 이유는? (Uncaught TypeError)

2024. 11. 19. 20:07·Develop/Frontend

카카오맵을 구현해보려고 하는데,  아래의 사진과 같은 에러가 뜨면서 렌더링이 되지 않았다!

콘솔에 찍힌 내용들을 차근 차근 읽어보고 검색해보아도, 별다른 해결책을 찾지 못했다.

 

코드는 아래와 같다.

import React, { useEffect, useState } from "react";

const KakaoMap = () => {
  const { kakao } = window;
  const [isLoaded, setIsLoaded] = useState(false);

  useEffect(() => {
    if (!kakao.maps) {
      return;
    }
    // 카카오 지도 객체 생성 예제
    const container = document.getElementById("map"); // 지도를 표시할 div
    const options = {
      center: new kakao.maps.LatLng(37.5665, 126.978), // 초기 위치
      level: 3, // 초기 확대 레벨
    };

    const map = new kakao.maps.Map(container, options);

    // // 지도에 마커 추가
    const marker = new kakao.maps.Marker({
      position: new kakao.maps.LatLng(37.5665, 126.978),
    });
    marker.setMap(map);

    setIsLoaded(true);
  }, [kakao.maps]);

  return (
    <div>
      {isLoaded ? (
        <div id="map" style={{ width: "100%", height: "400px" }}></div>
      ) : (
        <p>Loading map...</p>
      )}
    </div>
  );
};

export default KakaoMap;

 

여기서 문제점은 무엇일까요?

  1. 전역 객체인 kakao가 제대로 읽어들여지지 않았다.
  2. useEffect의 어떤 원리 때문에, 시간 차가 발생하여 kakao는 결국 읽어졌으나 kakao.maps가 state가 아니므로 리렌더링이 유발되지 않는다.
  3. useEffect의 어떤 원리 때문에, 렌더링 되고 난 후 useEffect의 콜백 함수 실행 과정에서 문제가 생겼다.

정답은?

.

.

.

.

.

.

.

.

.

.

.

3번! 

 

사실 1,2,3번 모두 문제의 원인 후보에 들만한 사유들입니다. 

따라서 전부 콘솔로그로 찍어보고, 주석화도 해보면서 디버깅을 해봤어요!

 

1. 전역 객체로 선언된 kakao의 경우 잘 읽혀지고 있었고(어느 시점에서든! → 사실 <script> 태그를 통해 <head>에 먼저 가져오므로 당연히 잘 읽혀집니다. 순서가 꼬이는 일은 없어요! - 스크립트가 실행이 안될 수도는 있어도..)

 

2. useEffect의 dependancy로 state와 같이 변하는 값이 아닌 전역 객체의 값을 넣어둔 것 또한 리렌더링을 발생시키지 않기에, 굉장히 이상한 코드인 것은 맞습니다.

 

그러나 3번이 원인인 것은.. 

 return (
    <div>
      {isLoaded ? (
        <div id="map" style={{ width: "100%", height: "400px" }}></div>
      ) : (
        <p>Loading map...</p>
      )}
    </div>
  );
};

 

바로 이 부분 때문입니다 ! isLoaded가 false이면 <p> 태그가 렌더링되는데 그렇게 된다면,

useEffect(() => {
    if (!kakao.maps) {
      return;
    }
    // 카카오 지도 객체 생성 예제
    const container = document.getElementById("map"); // 지도를 표시할 div
    const options = {
      center: new kakao.maps.LatLng(37.5665, 126.978), // 초기 위치
      level: 3, // 초기 확대 레벨
    };

    const map = new kakao.maps.Map(container, options);

    // // 지도에 마커 추가
    const marker = new kakao.maps.Marker({
      position: new kakao.maps.LatLng(37.5665, 126.978),
    });
    marker.setMap(map);

    setIsLoaded(true);
  }, [kakao.maps]);

 

이 useEffect 함수의 콜백 함수 내에서 

const container = document.getElementById("map"); // 지도를 표시할 div
    const options = {
      center: new kakao.maps.LatLng(37.5665, 126.978), // 초기 위치
      level: 3, // 초기 확대 레벨
    };

const map = new kakao.maps.Map(container, options);

 

여기! getElementById 해오는 부분이 null이 되어버리고, 그럼 kakao.maps.Map의 첫번째 인자로 null을 넘겨버리니까 타입 에러가 나면서 렌더링이 안되는겁니다! 이해 되셨나요? 

 

 

원인을 찾았으니, 쓸데없는 로직들 제외하면서 코드를 더욱 깔끔하게 만들어봅시다 ~!

import React, { useEffect, useState } from "react";

const KakaoMap = () => {
  const { kakao } = window;
  const [isLoaded, setIsLoaded] = useState(false);

  useEffect(() => {
    setIsLoaded(true); //다음 번에는 바로 로딩이 되도록 해당 위치에 정의
    if (!isLoaded) {
      //이래야 getElementById가 정상적으로 작동함
      return;
    }
    // 카카오 지도 객체 생성 예제
    const container = document.getElementById("map"); // 지도를 표시할 div
    const options = {
      center: new kakao.maps.LatLng(37.5665, 126.978), // 초기 위치
      level: 3, // 초기 확대 레벨
    };

    const map = new kakao.maps.Map(container, options);

    // // 지도에 마커 추가
    const marker = new kakao.maps.Marker({
      position: new kakao.maps.LatLng(37.5665, 126.978),
    });
    marker.setMap(map);
  }, [isLoaded]);

  return (
    <div>
      {isLoaded ? (
        <div id="map" style={{ width: "100%", height: "400px" }}></div>
      ) : (
        <p>Loading map...</p>
      )}
    </div>
  );
};

export default KakaoMap;

'Develop > Frontend' 카테고리의 다른 글

Web Socket을 도입하며 겪었던 트러블 슈팅들  (0) 2024.12.31
HTTP 그리고 Socket (Web Socket, 웹소켓)  (2) 2024.12.27
emotion에서 Theme 을 제대로 인식하지 못하는 에러 (+ 자동 완성도 불가능)  (7) 2024.11.10
React + Typescript 설치 시 생기는 에러 해결  (1) 2024.11.10
Next.js 톺아보기  (3) 2024.11.04
'Develop/Frontend' 카테고리의 다른 글
  • Web Socket을 도입하며 겪었던 트러블 슈팅들
  • HTTP 그리고 Socket (Web Socket, 웹소켓)
  • emotion에서 Theme 을 제대로 인식하지 못하는 에러 (+ 자동 완성도 불가능)
  • React + Typescript 설치 시 생기는 에러 해결
ocahs
ocahs
개발 내용을 담습니다.
  • ocahs
    ocahs 개발 블로그
    ocahs
  • 전체
    오늘
    어제
    • 분류 전체보기 (47)
      • Develop (47)
        • Frontend (25)
        • Javascript (7)
        • Algorithm (14)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    재귀타입
    JS
    Promise
    vite
    Working Set Model
    promise reject
    번들러
    line sweeping
    비트 연산자 활용 예시
    요청의 역사
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
ocahs
퀴즈! 렌더링이 되지 않는 이유는? (Uncaught TypeError)
상단으로

티스토리툴바