Closed si4dev closed 5 years ago
Reading more on useEffect() and the hints in the warning learned me to define libraries outside the functional component like this:
const libraries = ['places'];
And then use this
const { isLoaded, loadError } = useLoadScript({
googleMapsApiKey: GOOGLE_API_KEY,
libraries,
});
which will prevent useEffect() from triggering each rerender. So with this my issues is solved.
I tried what @si4dev suggested and the warning did not go away, however, when using
const [ libraries ] = useState(['places']);
the warning goes away.
I tried what @si4dev suggested and the warning did not go away, however, when using
const [ libraries ] = useState(['places']);
the warning goes away.
indeed
Having the same issue. What if we use useRef?
const libraries = ['places']
..
..
const libraries = ['places']
const App = () => {
let libRef = React.useRef(libraries)
const {isLoaded, loadError} = useJsApiLoader({
googleMapsApiKey: process.env.REACT_APP_MAP_API,
libraries: libRef.current,
})
}
The warning went away, but i was wondering if there something wrong with this?
@SachinMaharana Why so complicated? use just:
const libraries = ['places']
function App() {
const {isLoaded, loadError} = useJsApiLoader({
googleMapsApiKey: process.env.REACT_APP_MAP_API,
libraries,
})
return isLoaded ? <GoogleMap /> : <></>
}
export default React.memo(App)
I have tried all of this but none of them is working for me. Any thoughts?
const libraries: Libraries = ['drawing']
const {isLoaded} = useJsApiLoader({ id: 'google-map-script', googleMapsApiKey: 'Your API Key', libraries: libraries, });
Libraries
when importing the Libraries
typing, it results in an error:
Unable to resolve path to module '@react-google-maps/api/dist/utils/make-load-script-url'.
Is there a better way to define the TypeScript typing of Libraries
?
please provide minimal reproduction in codesandbox.io
Libraries
when importing the
Libraries
typing, it results in an error:Unable to resolve path to module '@react-google-maps/api/dist/utils/make-load-script-url'.
Is there a better way to define the TypeScript typing of
Libraries
?
I didn't meet this error, but you can also try: type Libraries = ("drawing | "geometry" | "localContext" | "places" | visualization)[];
please provide minimal reproduction in codesandbox.io
I'll see what I can do...in the interim here's a screenshot:
For TypeSctipt if you need! outside component: export const libraries = String(['places']); And inside: const { isLoaded, loadError } = useLoadScript({ googleMapsApiKey: GOOGLE_MAP_API,
});
const [ libraries ] = useState(['places']);
After quite some headbanging and disregarding the useState hook as a vialble solution It has been solved by holding libraries array in state. Thanks @tonyjaimep
const [ libraries ] = useState(['places']);
This one has solved my issue
you can just move it out of the component as const libraries = ['places'];
I found this warning, thank you everyone this issue is solved, with your all answer and solution.
Reading more on useEffect() and the hints in the warning learned me to define libraries outside the functional component like this:
const libraries = ['places'];
And then use this
const { isLoaded, loadError } = useLoadScript({ googleMapsApiKey: GOOGLE_API_KEY, libraries, });
which will prevent useEffect() from triggering each rerender. So with this my issues is solved.
both of the solutions worked for me... Either define const libraries = ['places']
outside component or define const [libraries] = useState(['places'])
inside component.
const libraries = ['places'] outside component resolved my problem
const libraries: ("drawing" | "geometry" | "localContext" | "places" | "visualization")[] = ["places"];
Using this variable outside the component fixed my issue!
I am using NextJS 13 with Typescript
I am using React TypeScript, it works! but idk if it is a good practice. Please can someone enlighten me!
const libraries = ['places']; Declaring it outside a functional component worked for me.
However I wonder why it actually came up with error in the first place.
@Jukes312 cos you should not pass new objects/arrays/functions as props directly, without caching it, else you causing a redirect. It is javascript reference comparison issue.
Oh thanks for the reply I was actually looking deep into it and figured it out. You are right about reference comparison issue, It goes back difference between primitive and reference types and how react rendering works. I found another way to solve the problem which was using the useMemo hook.
@Jukes312 useMemo is over-engineering. simple const outside of function scope is enough.
That's true thanks for the help 👊🏽
import type { Libraries } from '@googlemaps/js-api-loader';
const libraries = useRef<Libraries>(['places']);
const { isLoaded } = useLoadScript({
libraries: libraries.current
});
or
import type { Libraries } from '@googlemaps/js-api-loader';
const libraries = useMemo<Libraries>(() => (['places']), []);
const { isLoaded } = useLoadScript({
libraries: libraries.current
});
If you are using typescript, this might be the easiest way to enforce type safety:
// SomeComponent.tsx
import type { LoadScriptProps } from "@react-google-maps/api"
import { useLoadScript } from "@react-google-maps/api"
const libraries: LoadScriptProps["libraries"] = ["places"]
const SomeComponent = () => {
useLoadScript({
googleMapsApiKey: env.GOOGLE_MAPS_API_KEY,
libraries,
})
// Rest of the component
}
All of the above do not work for me, I'm using the StandaloneSearchBox. Does anyone have any suggestions?
@SeanMH8911 I was just about to reply the exact same, I'm using StandaloneSearchBox
and useJsApiLoader
, but I forgot to put
const libraries = ['places']
OUTSIDE the functional component, like literally underneath the import { StandaloneSearchBox, useJsApiLoader } from '@react-google-maps/api'
@winniepukki
Tysm. This is what finally did it for me. The solutions from the other comments like [libraries]=libraries fixed the rerendering but I wasn't able to use the library I needed. This is what finally worked
For TypeSctipt if you need! outside component: export const libraries = String(['places']); And inside: const { isLoaded, loadError } = useLoadScript({ googleMapsApiKey: GOOGLE_MAP_API, [libraries]: libraries, });
This one has solved my issue
Reading more on useEffect() and the hints in the warning learned me to define libraries outside the functional component like this:
const libraries = ['places'];
And then use this
const { isLoaded, loadError } = useLoadScript({ googleMapsApiKey: GOOGLE_API_KEY, libraries, });
which will prevent useEffect() from triggering each rerender. So with this my issues is solved.
This technique resolved my issue
For typescript:
import type { Libraries } from '@googlemaps/js-api-loader'; const libraries = useRef<Libraries>(['places']); const { isLoaded } = useLoadScript({ libraries: libraries.current });
or
import type { Libraries } from '@googlemaps/js-api-loader'; const libraries = useMemo<Libraries>(() => (['places']), []); const { isLoaded } = useLoadScript({ libraries: libraries.current });
thanks this helped for TS users. i am using useJsApiLoader, it worked too. life saver.
I have tried all of this but none of them is working for me. Any thoughts?
"use client"
import { Libraries, useLoadScript } from "@react-google-maps/api"
import { PlacesAutoComplete } from "./components/PlacesAutoComplete"
import { useRef } from "react"
export default function Home() {
// dance arounding to fix stupid performance warning
const libraries = ["places"] as Libraries
const libRef = useRef(libraries)
const { isLoaded } = useLoadScript({
googleMapsApiKey: process.env.NEXT_PUBLIC_GOOGLE_MAPS_API_KEY,
libraries: libRef.current,
})
return (
<div>
{isLoaded ? (
<>
<PlacesAutoComplete />
</>
) : (
<div>loading...</div>
)}
</div>
)
}
This approach work as well
const libraries = useRef<Libraries>(["places"])
const { isLoaded } = useLoadScript({
googleMapsApiKey: process.env.NEXT_PUBLIC_GOOGLE_MAPS_API_KEY,
libraries: libraries.current,
})
What if i have google map and parts of it like distance tracking stuff all over places, i should use "useLoadScript" multiple times or should i use it only on top level of my app?
What if i have google map and parts of it like distance tracking stuff all over places, i should use "useLoadScript" multiple times or should i use it only on top level of my app?
Try to use it once - in case it doesn't work when you use it once - use it twice
I tried what @si4dev suggested and the warning did not go away, however, when using
const [ libraries ] = useState(['places']);
the warning goes away.
This approach solved it for me
I'm using a library with useLoadScript like this:
And on rerender it always shows: Performance warning! Loadscript has been reloaded unintentionally! You should not pass
libraries
prop as new array. Please keep an array of libraries as static class property for Components and PureComponents, or just a const variable outside of component, or somewhere in config files or ENV variablesI've reviewed the code and it seems to use wrong comparison for arrays. When I change
libraries !== prevLibraries.current
intoJSON.stringify(libraries) !== JSON.stringify(prevLibraries.current)
then it works as expected without performance warnings. However the real solution is probably more complex as the useEffect shouldn't trigger on the array libraries as it is not changed.