Google Map
$ yarn 1219 한 것만으로는 거동 확인을 할 수 없으므로, 이하 순서로 셋업하고 나서 시험해 주세요.code: github/
$ yarn 1219

setup
Google Map API를 사용하려면 api_key가 필요합니다. 환경 변수에서 script tag에 api_key를 삽입합니다. 리포지토리 루트에 .env를 만들고 얻은 api_key를 넣습니다.
GOOGLE_MAP_API_KEY=XXXXXX
샘플에는 parcel을 사용하고 react-async-script로 환경 변수에서 script 태그를 생성합니다 (parcel의 경우).
app.tsx
import * as React from 'react'
import { render } from 'react-dom'
import Root from './components/index'
// @ts-ignore
import makeAsyncScriptLoader from 'react-async-script'
const URL = `https://maps.googleapis.com/maps/api/js?key=${
process.env.GOOGLE_MAP_API_KEY
}`
const AsyncScriptRoot = makeAsyncScriptLoader(URL)(Root)
render(<AsyncScriptRoot />, document.getElementById('app'))
진행 상황에 따른 View 분기
geolocation API를 사용하여 사용자의 현재 위치를 사용합니다. 현재 위치를 얻을 수 있을 때까지 3개의 View로 분기합니다.
components/index.tsxexport default () => (
<GeolocationWrapper
renderProcessView={() => <ProcessView />}
renderSuccessView={coords => (
<GoogleMapView coords={coords} />
)}
renderErrorView={() => <ErrorView />}
/>
)
navigator.geolocation.getCurrentPosition 를 call 하면, 현재 위치 취득의 허가가 요구됩니다. 현재 위치도 에러도 null 이면 진행중의 View 를, 에러가 있으면 에러 View 를, 현재 위치 취득이 할 수 있으면 GoogleMap API 이용의 View 를 마운트합니다.
components/geolocationWrapper.tsxexport default (props: Props) => {
const [coords, setCoords] = useState<Coordinates | null>(
null
)
const [error, setError] = useState<PositionError | null>(
null
)
useEffect(() => {
navigator.geolocation.getCurrentPosition(
({ coords }) => {
setCoords(coords)
},
setError
)
}, [])
return (
<>
{useMemo(
() => {
if (coords === null) return
return props.renderSuccessView(coords)
},
[coords]
)}
{useMemo(
() => {
if (error === null) return
return props.renderErrorView(error)
},
[error]
)}
{useMemo(
() => {
if (!(error === null && coords === null)) return
return props.renderProcessView()
},
[coords, error]
)}
</>
)
}
useEffect 및 GoogleMap API
GoogleMap API에 따라 마운트 중에 얻은 현재 위치 coords로 API를 치십시오. 맵을 마운트하는 태그는 ref 로 참조해, API callback 시에 useState 의 갱신 함수로 재묘화 시킵니다.
components/googleMapView.tsxconst View = (props: Props) => {
const [addressLabel, setAddressLabel] = useState(
'...取得しています'
)
const ref = useRef({} as HTMLDivElement)
useEffect(
() => {
if (ref.current === null) return
const { latitude, longitude } = props.coords // 取得した現在位置
const center = { lat: latitude, lng: longitude }
const mapOptions: google.maps.MapOptions = {
center,
zoom: 16
}
const map = new google.maps.Map(
ref.current,
mapOptions
)
const markerOptions: google.maps.MarkerOptions = {
position: center,
map
}
new google.maps.Marker(markerOptions)
const geocoder = new google.maps.Geocoder()
geocoder.geocode({ location: center }, function(
results,
status
) {
if (status == google.maps.GeocoderStatus.OK) {
setAddressLabel(results[1].formatted_address)
} else {
setAddressLabel('取得に失敗しました')
}
})
},
[props.coords]
)
return (
<div className={props.className}>
<div className="map" ref={ref} />
<p className="addressLabel">
現在住所:
{addressLabel}
</p>
</div>
)
}
export default () => (
<GeolocationWrapper
renderProcessView={() => <ProcessView />}
renderSuccessView={coords => (
<GoogleMapView coords={coords} />
)}
renderErrorView={() => <ErrorView />}
/>
)
export default (props: Props) => {
const [coords, setCoords] = useState<Coordinates | null>(
null
)
const [error, setError] = useState<PositionError | null>(
null
)
useEffect(() => {
navigator.geolocation.getCurrentPosition(
({ coords }) => {
setCoords(coords)
},
setError
)
}, [])
return (
<>
{useMemo(
() => {
if (coords === null) return
return props.renderSuccessView(coords)
},
[coords]
)}
{useMemo(
() => {
if (error === null) return
return props.renderErrorView(error)
},
[error]
)}
{useMemo(
() => {
if (!(error === null && coords === null)) return
return props.renderProcessView()
},
[coords, error]
)}
</>
)
}
GoogleMap API에 따라 마운트 중에 얻은 현재 위치 coords로 API를 치십시오. 맵을 마운트하는 태그는 ref 로 참조해, API callback 시에 useState 의 갱신 함수로 재묘화 시킵니다.
components/googleMapView.tsx
const View = (props: Props) => {
const [addressLabel, setAddressLabel] = useState(
'...取得しています'
)
const ref = useRef({} as HTMLDivElement)
useEffect(
() => {
if (ref.current === null) return
const { latitude, longitude } = props.coords // 取得した現在位置
const center = { lat: latitude, lng: longitude }
const mapOptions: google.maps.MapOptions = {
center,
zoom: 16
}
const map = new google.maps.Map(
ref.current,
mapOptions
)
const markerOptions: google.maps.MarkerOptions = {
position: center,
map
}
new google.maps.Marker(markerOptions)
const geocoder = new google.maps.Geocoder()
geocoder.geocode({ location: center }, function(
results,
status
) {
if (status == google.maps.GeocoderStatus.OK) {
setAddressLabel(results[1].formatted_address)
} else {
setAddressLabel('取得に失敗しました')
}
})
},
[props.coords]
)
return (
<div className={props.className}>
<div className="map" ref={ref} />
<p className="addressLabel">
現在住所:
{addressLabel}
</p>
</div>
)
}
Reference
이 문제에 관하여(Google Map), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/Takepepe/items/1c01a821b0112c440e3c텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)