11// eslint-disable-next-line node/no-extraneous-import
2- import { type CSSProperties , memo , useCallback , useMemo , useRef , useState , type ChangeEventHandler as ReactChangeEventHandler , type MouseEventHandler as ReactMouseEventHandler } from 'react'
3- import PropTypes from 'prop-types'
42import {
5- GoogleMap ,
6- DirectionsService ,
73 DirectionsRenderer ,
4+ DirectionsService ,
5+ GoogleMap ,
86} from '@react-google-maps/api'
7+ import * as PropTypes from 'prop-types'
8+ import {
9+ memo ,
10+ useCallback ,
11+ useMemo ,
12+ useRef ,
13+ useState ,
14+ type CSSProperties ,
15+ } from 'react'
916
1017const ExampleDirectionsPropTypes = {
1118 styles : PropTypes . shape ( {
@@ -25,66 +32,117 @@ interface Props {
2532}
2633
2734function ExampleDirections ( { styles } : Props ) : JSX . Element {
28- const [ response , setResponse ] = useState < google . maps . DirectionsResult | null > ( null )
29- const [ travelMode , setTravelMode ] = useState < google . maps . TravelMode > ( google . maps . TravelMode . DRIVING )
30- const [ origin , setOrigin ] = useState ( '' )
31- const [ destination , setDestination ] = useState ( '' )
35+ const [ response , setResponse ] = useState < google . maps . DirectionsResult | null > (
36+ null
37+ )
38+
39+ const [ directionsFormValue , setDirectionsFormValue ] = useState ( {
40+ origin : '' ,
41+ destination : '' ,
42+ travelMode : google . maps . TravelMode . DRIVING ,
43+ } )
44+
3245 const originRef = useRef < HTMLInputElement | null > ( null )
3346 const destinationRef = useRef < HTMLInputElement | null > ( null )
3447
35- const directionsCallback = useCallback ( ( result : google . maps . DirectionsResult | null , status : google . maps . DirectionsStatus ) => {
36- console . log ( result )
37-
38- if ( result !== null ) {
39- if ( status === 'OK' ) {
40- setResponse ( result )
41- } else {
42- console . log ( 'response: ' , result )
48+ const directionsCallback = useCallback (
49+ (
50+ result : google . maps . DirectionsResult | null ,
51+ status : google . maps . DirectionsStatus
52+ ) => {
53+ if ( result !== null ) {
54+ if ( status === 'OK' ) {
55+ setResponse ( result )
56+ } else {
57+ console . log ( 'response: ' , result )
58+ }
4359 }
44- }
45- } , [ ] )
46-
47- const checkDriving = useCallback < ReactChangeEventHandler < HTMLInputElement > > ( ( { target : { checked } } ) => {
48- checked && setTravelMode ( google . maps . TravelMode . DRIVING )
49- } , [ ] )
60+ } ,
61+ [ ]
62+ )
5063
51- const checkBicycling = useCallback < ReactChangeEventHandler < HTMLInputElement > > ( ( { target : { checked } } ) => {
52- checked && setTravelMode ( google . maps . TravelMode . BICYCLING )
53- } , [ ] )
64+ const checkDriving = useCallback < React . ChangeEventHandler < HTMLInputElement > > (
65+ ( { target : { checked } } ) => {
66+ checked &&
67+ setDirectionsFormValue ( ( currentValue ) => ( {
68+ ...currentValue ,
69+ travelMode : google . maps . TravelMode . DRIVING ,
70+ } ) )
71+ } ,
72+ [ ]
73+ )
5474
55- const checkTransit = useCallback < ReactChangeEventHandler < HTMLInputElement > > ( ( { target : { checked } } ) => {
56- checked && setTravelMode ( google . maps . TravelMode . TRANSIT )
75+ const checkBicycling = useCallback <
76+ React . ChangeEventHandler < HTMLInputElement >
77+ > ( ( { target : { checked } } ) => {
78+ checked &&
79+ setDirectionsFormValue ( ( currentValue ) => ( {
80+ ...currentValue ,
81+ travelMode : google . maps . TravelMode . BICYCLING ,
82+ } ) )
5783 } , [ ] )
5884
59- const checkWalking = useCallback < ReactChangeEventHandler < HTMLInputElement > > ( ( { target : { checked } } ) => {
60- checked && setTravelMode ( google . maps . TravelMode . WALKING )
61- } , [ ] )
85+ const checkTransit = useCallback < React . ChangeEventHandler < HTMLInputElement > > (
86+ ( { target : { checked } } ) => {
87+ checked &&
88+ setDirectionsFormValue ( ( currentValue ) => ( {
89+ ...currentValue ,
90+ travelMode : google . maps . TravelMode . TRANSIT ,
91+ } ) )
92+ } ,
93+ [ ]
94+ )
6295
63- const onClick = useCallback < ReactMouseEventHandler < HTMLButtonElement > > ( ( ) => {
64- if ( originRef . current && originRef . current . value !== '' && destinationRef . current && destinationRef . current . value !== '' ) {
65- setOrigin ( originRef . current . value )
96+ const checkWalking = useCallback < React . ChangeEventHandler < HTMLInputElement > > (
97+ ( { target : { checked } } ) => {
98+ checked &&
99+ setDirectionsFormValue ( ( currentValue ) => ( {
100+ ...currentValue ,
101+ travelMode : google . maps . TravelMode . WALKING ,
102+ } ) )
103+ } ,
104+ [ ]
105+ )
66106
67- setDestination ( destinationRef . current . value )
107+ const onClick = useCallback <
108+ React . MouseEventHandler < HTMLButtonElement >
109+ > ( ( ) => {
110+ if (
111+ originRef . current &&
112+ originRef . current . value !== '' &&
113+ destinationRef . current &&
114+ destinationRef . current . value !== ''
115+ ) {
116+ setDirectionsFormValue ( ( currentValue ) => ( {
117+ ...currentValue ,
118+ origin : originRef . current ?. value ?? '' ,
119+ destination : destinationRef . current ?. value ?? '' ,
120+ } ) )
68121 }
69- } , [ ] )
122+ } , [ originRef . current ?. value , destinationRef . current ?. value ] )
70123
71124 const onMapClick = useCallback ( ( e : google . maps . MapMouseEvent ) => {
72125 console . log ( 'onClick args: ' , e )
73126 } , [ ] )
74127
75- const directionsServiceOptions = useMemo < google . maps . DirectionsRequest > ( ( ) => {
76- return {
77- destination,
78- origin,
79- travelMode,
80- }
81- } , [ ] )
128+ const directionsServiceOptions =
129+ useMemo < google . maps . DirectionsRequest > ( ( ) => {
130+ return {
131+ destination : directionsFormValue . destination ,
132+ origin : directionsFormValue . origin ,
133+ travelMode : directionsFormValue . travelMode ,
134+ }
135+ } , [
136+ directionsFormValue . origin ,
137+ directionsFormValue . destination ,
138+ directionsFormValue . travelMode ,
139+ ] )
82140
83- const directionsRendererOptions = useMemo ( ( ) => {
141+ const directionsResult = useMemo ( ( ) => {
84142 return {
85143 directions : response ,
86144 }
87- } , [ ] )
145+ } , [ response ] )
88146
89147 return (
90148 < div className = 'map' >
@@ -126,7 +184,10 @@ function ExampleDirections({ styles }: Props): JSX.Element {
126184 className = 'custom-control-input'
127185 name = 'travelMode'
128186 type = 'radio'
129- checked = { travelMode === 'DRIVING' }
187+ checked = {
188+ directionsFormValue . travelMode ===
189+ google . maps . TravelMode . DRIVING
190+ }
130191 onChange = { checkDriving }
131192 />
132193 < label className = 'custom-control-label' htmlFor = 'DRIVING' >
@@ -140,7 +201,10 @@ function ExampleDirections({ styles }: Props): JSX.Element {
140201 className = 'custom-control-input'
141202 name = 'travelMode'
142203 type = 'radio'
143- checked = { travelMode === 'BICYCLING' }
204+ checked = {
205+ directionsFormValue . travelMode ===
206+ google . maps . TravelMode . BICYCLING
207+ }
144208 onChange = { checkBicycling }
145209 />
146210 < label className = 'custom-control-label' htmlFor = 'BICYCLING' >
@@ -154,7 +218,10 @@ function ExampleDirections({ styles }: Props): JSX.Element {
154218 className = 'custom-control-input'
155219 name = 'travelMode'
156220 type = 'radio'
157- checked = { travelMode === 'TRANSIT' }
221+ checked = {
222+ directionsFormValue . travelMode ===
223+ google . maps . TravelMode . TRANSIT
224+ }
158225 onChange = { checkTransit }
159226 />
160227 < label className = 'custom-control-label' htmlFor = 'TRANSIT' >
@@ -168,7 +235,10 @@ function ExampleDirections({ styles }: Props): JSX.Element {
168235 className = 'custom-control-input'
169236 name = 'travelMode'
170237 type = 'radio'
171- checked = { travelMode === 'WALKING' }
238+ checked = {
239+ directionsFormValue . travelMode ===
240+ google . maps . TravelMode . WALKING
241+ }
172242 onChange = { checkWalking }
173243 />
174244 < label className = 'custom-control-label' htmlFor = 'WALKING' >
@@ -190,15 +260,16 @@ function ExampleDirections({ styles }: Props): JSX.Element {
190260 center = { center }
191261 onClick = { onMapClick }
192262 >
193- { destination !== '' && origin !== '' && (
194- < DirectionsService
195- options = { directionsServiceOptions }
196- callback = { directionsCallback }
197- />
198- ) }
263+ { directionsFormValue . destination !== '' &&
264+ directionsFormValue . origin !== '' && (
265+ < DirectionsService
266+ options = { directionsServiceOptions }
267+ callback = { directionsCallback }
268+ />
269+ ) }
199270
200- { response !== null && (
201- < DirectionsRenderer options = { directionsRendererOptions } />
271+ { directionsResult . directions && (
272+ < DirectionsRenderer options = { directionsResult } />
202273 ) }
203274 </ GoogleMap >
204275 </ div >
0 commit comments