next.jsarcgisesriarcgis-js-apiesri-maps

Esri ArcGIS Map in Next.js app not working for me


Im having an issue getting a map to display via arcgis and next.js, perhaps if i had more eyes on it i might understand. Here is the code:

Main Page:

'use client'


import Header from './components/Header';
import DynamicMap from './components/map/DynamicMap';
import { store } from './store';
import { Provider } from 'react-redux';

const Home = () => {
  return (
    <>
      <Provider store={store}>
      <Header />
      <DynamicMap />
      </Provider>
    </>
  )
}

export default Home;

Dynamic Middleman component:

import dynamic from 'next/dynamic'
 
const DynamicHeader = dynamic(() => import('../../components/map/Map'), {
    ssr: false,
})
 
export default () => <DynamicHeader />

And finally a simple esri map:

'use client'

import React, { useRef, useEffect } from "react";
import Map from "@arcgis/core/Map.js";
import MapView from "@arcgis/core/views/MapView";

const EsriMap = () => {

  const mapRef = useRef(null);

    useEffect(() => {

      const baseMap = new Map({
        basemap: "topo-vector",
      });
    
      const view = new MapView({
        container: "viewDiv",
        map: baseMap,
        center: [-118.805, 34.027],
        zoom: 1,
      });

    }, []);

    return (
      <>
        <div id='viewDiv' ref={mapRef}></div>
      </>
    )
}

export default EsriMap;

It should be simple, the view is using the viewDiv id, but it keeps coming up with it cant find the element, or the map goes berzerk.

by berzerk i mean it has something to do with violations and webgl2d. i can post an image, but the above put into a next.js app with arcgis core imported should reproduce the issue.

Do i need to use a useEffect? Should i be using ref? Not sure why it wont work


Solution

  • Your MapView should be using the useRef for the container, don't rely on ids in a React application like that.

    useEffect(() => {
      if (mapRef.current) {
        const baseMap = new Map({
          basemap: "topo-vector",
        });
      
        const view = new MapView({
          container: mapRef.current,
          map: baseMap,
          center: [-118.805, 34.027],
          zoom: 1,
        });
      }
    }, [mapRef]);
    

    Also, if you notice the map is in a continuous scroll and you don't see the zoom widgets, make you have imported the CSS correctly in your application.

    Here is an example of importing the css.