[Next.js] react-google-autocomplete 이용하여 도시이름 자동완성 구현

JunSeok·2023년 8월 21일
0

PlannerBot 프로젝트

목록 보기
2/3
post-thumbnail

상황

사용자가 도시 이름을 입력할 때, 정확한 도시 이름을 입력값으로 받아오기 위해 도시 자동완성을 구현하고자 했다.
그리고 react-google-autocomplete라는 라이브러리를 찾았다.
깃헙 document

react-google-autocomplete 사용 이유

  1. 내가 원하는 기능과 정확히 일치했다.
  2. npm 다운로드 수 14만을 넘겼고(8월 21일 기준), 마지막 업데이트가 1년 이내에 이루어져 사용하기에 안정성이 있다고 판단했다.
  3. 문서 설명이 친절해서 사용하기 간편했다.

구현과정

라이브러리 설치

npm i react-google-autocomplete --save

or

yarn add react-google-autocomplete

API Key 발급

  1. google cloud console에 가서 새 project를 만든다.
  2. API 및 서비스 탭의 사용자 인증 정보 화면에서 사용자 인증 정보 만들기를 클릭하여 API키를 만든다.
  3. 라이브러리 탭에 들어가서 Places API를 찾아 ENABLE 또는 사용 버튼을 누른다. 관리버튼으로 되어 있으면 이미 사용중인 상태이다.

코드 구현

전체적인 코드 구조는 깃헙 document의 Example를 참고했고, 나머지는 내 프로젝트에 맞게 커스텀했다.

useGoogle hook

useGoogle hookgoogle place autocomplete service를 이용하고, 이 서비스로 이용 가능한 기능을 return 해준다. 또한 input 값으로 구글에 요청을 보내는 수를 줄일 수 있는 debounce prop을 설정할 수 있다.
현재는 debounce 기능을 lodash 라이브러리를 통해 구현하고 있다고 한다.

  • return value
    -placePredictions: input값을 통해 Prediction한 Places array
    -getPlacePredictions: 장소 예측을 하고 싶을 때마다 호출 즉, input값이 바뀔 때마다 이 함수를 호출, placePrediction 값 업데이트
    -isPlacePredictionsLoading: 예측 중이면 true, 끝났으면 false
import React, { useState } from 'react'

import { List } from "antd";
import useGoogle from "react-google-autocomplete/lib/usePlacesAutocompleteService";

type Props = {
    place: string,
    setPlace: React.Dispatch<React.SetStateAction<string>>
}

const AutoComplete = ({ place, setPlace }: Props) => {
    const {
        placePredictions,
        getPlacePredictions,
        isPlacePredictionsLoading,
    } = useGoogle({
        apiKey: process.env.NEXT_PUBLIC_GOOGLE_MAPS_API_KEY,
    });
    const [chosen, setChosen] = useState("")
    return (
        <div className="relative flex flex-col w-full">
            <span>여행지</span>
            <input
                className="w-full p-2 my-2 border rounded"
                value={place}
                placeholder="여행지 입력"
                onChange={(evt: any) => {
                    getPlacePredictions({ input: evt.target.value });
                    setChosen(evt.target.value);
                    setPlace(evt.target.value);
                }}
            />
            {chosen && <div className="absolute h-[10rem] left-0 overflow-x-hidden flex whitespace-nowrap flex-col w-full my-1 bg-white border z-[9999] rounded top-20">
                {!isPlacePredictionsLoading && (
                    <List className="px-2"
                        dataSource={placePredictions}
                        renderItem={(item: any) => (
                            <List.Item className="cursor-pointer" onClick={() => {
                                setChosen("")
                                setPlace(item.description)
                            }
                            }>
                                <List.Item.Meta title={item.description} />
                            </List.Item>
                        )}
                    />
                )}
            </div>}
        </div>
    );
}

export default AutoComplete

코드 보기

프론트엔드 코드 깃헙

profile
최선을 다한다는 것은 할 수 있는 한 가장 핵심을 향한다는 것

0개의 댓글