PaulLeCam / react-leaflet

React components for Leaflet maps
https://react-leaflet.js.org
Other
5.18k stars 887 forks source link

Is everything okay with Nextjs v14.1.0 + React v18? Maps doesn't render #1127

Closed AndresMpa closed 9 months ago

AndresMpa commented 9 months ago

What I'm doing

I just copy pasted the example from react-leaflet

src/app/page.tsx


import { MapContainer, Marker, Popup, TileLayer } from "react-leaflet"

export default function Main() { return ( <> <MapContainer center={[40.8054, -74.0241]} zoom={14} scrollWheelZoom={false} style={{ height: "100%", width: "100%" }}

<TileLayer attribution='© OpenStreetMap contributors' url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" /> <Marker position={[40.8054, -74.0241]} draggable={true}>

A pretty CSS3 popup.
Easily customizable.

</> ) }

Expected behaviour

Redender a map on Nextjs v14 from a default template project

Current behaviour

Fatal error:

Server Error
Error: (0 , react__WEBPACK_IMPORTED_MODULE_0__.createContext) is not a function

This error happened while generating the page. Any console logs will be displayed in the terminal window.

Dependencies

Package.json

"leaflet": "^1.9.4",
"leaflet-defaulticon-compatibility": "^0.1.2",
"leaflet-geosearch": "^3.11.0",
"next": "14.1.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",

My desire

Not to downgrade Netxjs version

PoppySari-RGA commented 9 months ago

Hey, You might want to add "use client" on the map component (a.k.a make it client component) based on the docs on introduction section, react leaflet is incompatible with SSR

Leaflet makes direct calls to the DOM when it is loaded,
therefore React Leaflet is not compatible with server-side rendering.
AndresMpa commented 9 months ago

Hey, You might want to add "use client" on the map component (a.k.a make it client component) based on the docs on introduction section, react leaflet is incompatible with SSR

Leaflet makes direct calls to the DOM when it is loaded,
therefore React Leaflet is not compatible with server-side rendering.

That solved its first render. now there's an error on what it renders. I want to achieve something like this: https://next-leaflet-starter.netlify.app/

But what I'm getting is just a set of chunks or pieces of a map bug

I'm actually rendering it using this:

    const Map = useMemo(() => dynamic(
        () => import('@/components/map/simple-map'),
        {
            loading: () => <p>A map is loading</p>,
            ssr: false
        }
    ), [])

    return (
        <>
            <h2>My map</h2>
            <div className="bg-orange-700 mx-auto w-11/12 h-[480px]">
                <Map />
            </div>
        </>
    )
theNailz commented 9 months ago

Looks like you forgot the CSS!

import "leaflet/dist/leaflet.css";
import "leaflet-defaulticon-compatibility/dist/leaflet-defaulticon-compatibility.css";
import "leaflet-defaulticon-compatibility";

import {MapContainer, Marker, TileLayer} from "react-leaflet";
// etc.

I'm not sure if using https://www.npmjs.com/package/leaflet-defaulticon-compatibility is required. Your results may vary.

worked for me.

AndresMpa commented 9 months ago

I finally got a working component, actually half of the blame was due to what @theNailz said. I decided to wrote a medium article explaining my mistakes, so I will leave it here:

https://andresprieto-25116.medium.com/how-to-use-react-leaflet-in-nextjs-with-typescript-surviving-it-21a3379d4d18

It must be enough for the specific version I mentioned in the title of this issue

Thanks guys, you rock it 👍🏼

shasherazi commented 5 months ago

This was very helpful, specially because the autocomplete doesn't show the CSS file for some reason.

image