Search code examples
javascriptreactjsleafletuse-effect

React.js / Leaflet -- Run useEffect on Mount only in DevServer


i'm running into the behavior, that i must run the useEffect Hook only once in react. the reason is mainly because i have to init a leaflet.js map which must not happen more than once.

but whenever i change something in the components jsx, the "Hot Reload" feature of the DevServer seems to ignore useEffects 2nd argument [] and re-run it anyway, although the state of coachmap persists. This behavior throws an error: map is already initialised which can only be fixed by reloading the browser tab.

Do you have any Idea how I can prevent react to re-initialise leaflet?

I've already tried to check if typeof coachmap == 'undefined' which strangely still re-initialises the map.

Here is my Component Code:

import * as L from "leaflet/dist/leaflet";
import "leaflet/dist/leaflet.css";
import { useEffect } from "react";

function CoachMap() {
  useEffect(() => {
    if (typeof coachmap == "undefined") {
      // Initialise Leaflet.js Map
      const coachmap = L.map("coach-map").setView([51.505, -0.09], 13);
    }
  }, []);

  return (
    <div className="container mx-auto my-4 ab">
      <div id="coach-map"></div>
    </div>
  );
}

export default CoachMap;


Solution

  • Since your component is called in App.js directly, why don't you wrap the component using React.memo. (This will prevent unnecessary re renders)

    export default React.memo(CoachMap);
    

    Don't forget to import 'React'

    import React, {useEffect} from "react"

    you could also replace useEffect with useMemo since you intend to memoize the value and not actually fire side effects.

    const coachmap = React.useMemo(()=>{
      return L.map("coach-map").setView([51.505, -0.09], 13)
    }, []);