-
항해99 75일차 TIL : 지도가 로드될 때, 마커는 바로 뜨지 않는 문제 해결(feat. useEffect)항해99_WIL 이따금씩 TIL 2021. 5. 15. 12:20
오래도록 해결 되지 않은 심각한 문제 : 마커가 바로 뜨지 않는다.
우리조가 개발중인 프로젝트에서는 지도가 로드 되고 마커도 바로 뜨게 해야 하지만, 지도는 로드 되는데 마커는 바로 뜨지 않고, 카테고리의 버튼을 클릭해야 그제서야 마커가 뜨는 문제점이 있었다. 분명 마커 관련 데이터는 서버에서 받아오는데, 그 데이터를 읽고 마커를 올리지 않는 것 같았다. 이 문제는 사용자들에게 처음부터 마커를 보여줘야 한다는 점에서 반드시 해결해야 하는 문제였다.
이렇게 카테고리를 클릭해야 그제서야 마커가 떴다. 그렇다면 데이터는 서버에서 제대로 받아 오는게 맞는데, 처음 페이지가 로드되거나 새로고침 될 때 처음에는 데이터를 갖고 마커를 띄우는 코드가 작동하지 않는다는 것이다. 다만 카테고리 버튼을 눌러야 비로소 코드가 작동했다. 그러니 데이터를 읽고 마커를 띄우는 코드 자체에는 문제점이 없어보였다.
그래서 혹시 페이지가 처음 로드 될 때 지도 데이터가 오는 시점과 마커데이터가 오는 시점에 시차가 큰 것이 문제가 아닐까 하는 가설을 세웠다. 이 가설을 검증하기 위해서 개발자도구의 Network를 열어서 분석했다.
개발자도구의 Network를 분석해보니, kakao.js, services.js, clusterer.js, drawing.js 등 카카오 지도 api에서 지도를 그려주는 용도로 제공하는 코드는 먼저 온다.
그리고 4.5초 정도에 마커데이터가 저렇게 온다.
이 시간차가 문제의 원인이라고 생각해서 여러가지 시도를 해보았다. 백엔드에서는 데이터를 빨리 보낼 수 있도록 최적화를 하려고 논의를 하기도 했다. 나는 마커를 띄우는 코드는 useEffect안에 있으므로, 렌더링이 바로 되면 해결되지 않을까하는 생각에 여러가지 시도를 했다. 예를들어 지도를 로드하는 코드를 한 useEffect안에 넣고 마커를 띄우는 코드는 다른 useEffect안에 넣는식으로 useEffect를 여러개 쓴다던가. 하지만 온갖 시도들을 다 했음에도 모두 실패로 돌아갔다.
내 지식으로는 해결 불가다라는 판단에 GG 선언을 하고 튜터님께 이 문제를 논의드려서 같이 문제를 찾아보았다. 튜터님이 보기에도 데이터는 잘 오고 그 데이터를 이용해서 마커를 띄우는 코드도 정상 작동하는 것이면, 렌더링 문제일 것 같다고 하셨다. 다시말해, 데이터는 제대로 오고 있고 있는데 마커를 바로 렌더링 하지 못한다는 것. 그리고 앞서 말한 시간차 4.5초도 원인이 아닌 것이, 4.5초 시점에서 '지도이미지' 같은 데이터와 마커데이터는 거의 같이 받고 있기 때문에 데이터를 지도이미지 같은 데이터보다 늦게 받는건 아니었다. 0.5초 시점에 받는건 지도이미지 같은 것이 아니라 지도 api와 관련된 코드들이었다.
그래서 다시 코드를 분석해보았다. 마커 데이터를 담은 리스트는 비동기 때문에 처음에는 비어 있다가 나중에 데이터로 채워진다. 그러니까 마커데이터를 담은 리스트가 비어 있는채로 렌더링이 끝나서 마커가 뜨지 않는 것이다. 그러니 데이터가 채워진 다음에 자동으로 리렌더링을 시킬 수 있다면 마커가 지도상에 뜨게 될 것이다. 다시말해서, 마커 데이터 리스트에 데이터가 채워지는 것을 감지해서 렌더링을 다시 일어나게 하면 마커가 지도에 뜨게 하는 작동을 하게 할 것이다. 이런 추정을 바탕으로 리렌더링하는 방법을 생각해봤는데, 그건 useEffect의 dependency에 마커데이터를 담은 리스트를 추가해서 그 리스트의 변화를 감지하면 바로 렌더링 되게 하는 것이었다.
이 부분은 useEffect의 dependency인데, 주석처리해놓은 map_post_list가 처음에는 없었다. map_post_list는 마커데이터를 담은 리스트인데, 저 부분이 dependency에 없으니 데이터가 처음에는 비어 있다가 생기는 변화를 이용할 수 없었다. 그래서 map_post_list를 dependency에 넣으면 데이터가 없다가 있게 되면 useEffect 내부 코드(데이터를 읽고 마커를 띄우는 코드)가 다시 작동해(=리렌더링) 마커를 띄울 것이다, 그리고 데이터가 없다가 채워지는 시간차는 얼마 안 되므로 마커가 바로 뜨는 것처럼 보일 것이다라는 결론을 내리게 되었고 정말로 그렇게 되었다.
짜잔!!
이 문제를 해결하면서, 역시 리액트는 소문대로 비동기 제어를 잘 이해하고 영리하게 사용할 줄 알아야 원하는 기능을 구현할 수 있다는 걸 다시 한번 문제를 해결하면서 느끼게 되었다. 앞으로는 리액트를 사용하면 비동기처리, 제어를 해야 한다는 점을 염두에 두고 개발을 하도록 하겠다.
'항해99_WIL 이따금씩 TIL' 카테고리의 다른 글