React Leaflet : ugly Warning: Each child in a list should have a unique "key" prop

306 Views Asked by At

I've set an leaflet map component that iterate through users fetched from db that contains, for each of them, coordinates. Devtool throw me:

Warning: Each child in a list should have a unique "key" prop.

Not the first time I got this warning and I usually find easily how to fix it but this time I can't find a solution.

All is working fine but this warning keeps triggering me

Console Warning: Console Warning

I've tried to put the key as Marker component identifier, Popup component identifier, both of them.

I've seen a post that recommend to put the key as Fragment identifier for each element of my map function. I tried in a div component (seems equal to Fragment to me?) still not working.

<MapContainer  id={!isMobile ? "browser-leaflet" : "mobile-leaflet"} center={POSITION} zoom={15} scrollWheelZoom={true}>
    <TileLayer
    attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
    url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png?lang=fr"
    />
    {contacts.map(contact => (
        <div key={contact.email}> <-- last try here
            <Marker //also tried here// position={[contact.lat, contact.lon]} icon={new Icon({iconUrl: contact.is_client ? markerIconClient : markerIconProspect, iconSize: [25, 41], iconAnchor: [12, 41]})}>
                <Popup //also tried here// offset={[0, -15]}>
                    <p style={{marginBottom: "1vh", textAlign: "center", fontSize: "1.5em"}}>
                        {contact.raison_sociale}
                    </p>
                    <Button variant="sub" className="mx-auto" style={{border: "teal", borderRadius: "15px", fontSize: "1em", display: "flex", justifyContent: "center"}}>
                        <a 
                        href={"https://www.waze.com/fr/live-map/directions?navigate=yes&to=ll." + contact.lat + "%2C" + contact.lon}
                        style={{textDecoration: "none", color: "black", backgroundColor: "#D0FCB3"}}
                        >
                            Allez-y
                        </a>
                    </Button>
                </Popup>
            </Marker>
        </div>
    ))}
    <SetMap />
</MapContainer>

Error seems to be located @Geolocalisation.jsx (my whole page compo) line:102 which is where I set style and navbar based on client device.

return ( <--- here l:102
        <>
            {!isMobile ? (
                [
                    <BrowserSidenav />, 
                    <style>
                        {browserLeafletContainer}
                    </style>
                ]
            ) : (
                <style>
                    {mobileLeafletContainer}
                </style>
            )}

Does someone knows how to fix it? (P.S: sorry for bad English, not native and not using online translator)

Whole return from my component Geolocalisation.jsx : (funcs are just a users fetch, a useEffect that delete users with no lat/lon.

return (
        <>
            {!isMobile ? (
                [
                    <BrowserSidenav />, 
                    <style>
                        {browserLeafletContainer}
                    </style>
                ]
            ) : (
                <style>
                    {mobileLeafletContainer}
                </style>
            )}

            <MapContainer  id={!isMobile ? "browser-leaflet" : "mobile-leaflet"} center={POSITION} zoom={15} scrollWheelZoom={true}>
                <TileLayer
                attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
                url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png?lang=fr"
                />
                {contacts.map(contact => (
                    <div key={contact.email}>
                        <Marker position={[contact.lat, contact.lon]} icon={new Icon({iconUrl: contact.is_client ? markerIconClient : markerIconProspect, iconSize: [25, 41], iconAnchor: [12, 41]})}>
                            <Popup offset={[0, -15]}>
                                <p style={{marginBottom: "1vh", textAlign: "center", fontSize: "1.5em"}}>
                                    {contact.raison_sociale}
                                </p>
                                <Button variant="sub" className="mx-auto" style={{border: "teal", borderRadius: "15px", fontSize: "1em", display: "flex", justifyContent: "center"}}>
                                    <a 
                                    href={"https://www.waze.com/fr/live-map/directions?navigate=yes&to=ll." + contact.lat + "%2C" + contact.lon}
                                    style={{textDecoration: "none", color: "black", backgroundColor: "#D0FCB3"}}
                                    >
                                        Allez-y
                                    </a>
                                </Button>
                            </Popup>
                        </Marker>
                    </div>
                ))}
                <SetMap />
            </MapContainer>
        </>
    )
2

There are 2 best solutions below

8
On BEST ANSWER

Check if there are same emails in data 'contacts'. Make sure each key for div is unique.

0
On

Remember that undefined is also a key-value.

If you have unique emails in your DB, but not required, then there might be several people without email.

I normally go for the _id/id or concider using several fields to build a key. You could also do key={contact.email ?? contact.phone} Or another attribute if email is undefined...