React로 카카오 맵 API 사용하신분 꼭 조언주세요

안녕하세요,

React Gatsby로 카카오 맵 API를 사용하려고 합니다.
몆일동안 , static, require(), dangerouslySetInnerHTML, gatsby-ssr.js, setHeadComponents, useEffect() 등 수많은 조언을 받았으나 다 되지 않았습니다.

가능하면 작동되는 React로 카카오 맵API를 사용한 코드를 공유 부탁드립니다. 염치없지만, 워낙 버그가 많아서 그냥 버그없이 작동되는 코드가 절실히 필요합니다.

감사합니다.

import React from "react"
    
export default class Home extends React.Component {
      render() {
        return (
          <div style={{ color: `purple` }}>
            <div id="map" style={{ height: '2000px',width: '2000px'}}></div>
            <script src="../js/kakaoapi.js" type="text/javascript"></script>
            <script src="../js/map.js" type="text/javascript"></script>
          </div>
      )}
}

안녕하세요
아래 페이지가 참고가 될까요?

그리고 글은 하나로만 작성해주세요



1개의 좋아요

이 전 버전 리액트로는 다음과 같이 시작합니다.

/*global kakao*/

import React, { Component } from 'react';
import './App.css';

class App extends Component {

    componentDidMount() {
        const script = document.createElement('script');
        script.async = true;
        script.src = "https://dapi.kakao.com/v2/maps/sdk.js?appkey=XXXXXXXXXXXXXXXXXXXX&autoload=false";
        document.head.appendChild(script);

        script.onload = () => {
            kakao.maps.load(() => {
                let el = document.getElementById('map');
                let map = new kakao.maps.Map(el, {
                    center: new kakao.maps.LatLng(/* latitude */, /* longitude */)
                });
            });
        };
    }

    render() {
        return (
            <div className="App" id="map"></div>
        );
    }
}

export default App;

리액트의 render 함수에서 스크립트를 import하는 방식은 프레임워크 설계 특성상 동작하지 않을 확률이 큽니다.

autoload=false 방식은 비동기이기 때문에
혹시라도 정적인 스크립트를 작성하기 원하신다면,

autoload=false 파라메터를 빼고
리액트 App 자체를 부르는 HTML 템플릿 페이지에

<script src="https://dapi.kakao.com/v2/maps/sdk.js?appkey=제키"></script>

고정으로 위 스크립트 태그를 넣고

script.onload = () => { kakao.maps.load(() => { /*...*/ } }

위 문구 없이 사용하셔도 됩니다.

3개의 좋아요

답글 정말 감사합니다.

사실 도지님의 예전 글을 보고 따라했으나, 에러가 났던 기억이 납니다.
다시보니 여기선 HTML을 부르는 템플릿 페이지에 script를 넣으라고 하셨네요.
저 또한 같은방법으로 해결했습니다. 다만 전 componentDidMount()부분을 useEffect() 로 대신했습니다.

1개의 좋아요

해결방식을 적어주셔서 감사합니다.
비교적 최신의 리액트 ( >=16.8 )에서의 useEffect()가 기존의 componentDidMount()를 대신하고 있으니
아마 작성하신 코드가 맞을 겁니다.

갑자기 궁금해졌는데

리액트의 render 함수에서 스크립트를 import하는 방식은 프레임워크 설계 특성상 동작하지 않을 확률이 큽니다.

이건 왜 그런가요?

그리고

autoload=false 방식은 비동기이기 때문에

왜 autoload=false 하나만 뒤에 추가하면 html에 src를 안추가하고도 되는건가요?
React 구조가가 좀 이해가 안되는게 많네요.

  1. React는 View를 효율적으로 그리기 위해 사용하는 라이브러리(어떤 관점에서는 프레임워크) 입니다.
    그래서 React는 컴포넌트 개념을 만들었습니다. 이것은 화면에 직접 그려질 요소들을 추상화 한 개념인데,
    이 컴포넌트는 실제 문서에 표현되는 HTML DOM Element가 아니며 가상의 DOM Element를 의미합니다.
    제가 동작하지 않는 확률을 언급한 이유는,
    React가 결국 이 가상 DOM을 render() 함수를 통해 실제 DOM을 생성/조작 하여 DOM Tree에 반영하는데
    third party 라이브러리를 불러오는 스크립트 태그를 JSX로 넣어줘도
    React 구조의 이해 없이 사용하는 기본적인 기능만으로는 처리하기 힘들기 때문입니다.
    불러오려는 스크립트 내용이 어떻게 구성되어 있느냐에 따라서 더 복잡해 질 수 있고요.
    실제로도 별다른 트릭 사용(실제 DOM Ref를 가져와 라이프사이클에 맞게 조작) 이나
    특정 스크립트 로딩 모듈의 도움을 받지 않고 않고 질문하신대로만 쓰면 제대로 동작하지 않고요.
    정확하게 왜 그런지 확인하고 싶으시면 React 공식 문서를 살펴보시길 바랍니다.

  2. autoload=false 파라메터는 카카오 지도 JS SDK에서 제공해주는 기능이며
    지도가 필요한 상황에서 비동기로 스크립트를 로딩하여 쓸 수 있게 해 줍니다.
    JSX로 스크립트 태그(script src)를 쓰는 방식은
    React가 render() 시점에 실제 DOM에 엘리먼트를 만들어 잘 반영한다 해도
    스크립트 내용이 모두 다운로드 되고 실행이 끝난 시점을 알기 힘들기 때문에
    특정 라이프 사이클 hook에서 일반적으로 알려진 비동기 스크립트 로딩 방식으로 처리를 하는 것이 편합니다.
    하지만 카카오 지도 SDK는 로딩 구조상 일반적읜 비동기 스크립트 로딩 방식을 사용하면
    정확히 사용 가능한 시점을 컨트롤 하기 힘들기 때문에
    특별히 다음과 같은 방식으로 카카오 SDK에서 사용할 수 있도록 지원하고 있습니다.

    • 스크립트 로딩 파라메터에 autoload=false 세팅
    • kakao.maps.load()를 사용하여 지도를 사용할 수 있는 시점 제공
1개의 좋아요

그렇군요… 기본적인 html/javascript만 알았는데 React구조는 거의 다른언어라고 느낄정도로 다르네요.

카카오 개발자는 다르구나… 코린이는 벽느끼고 갑니다…