Skip to content

Missing unique key prop in Choropleth legends (React 19) #2801

@MoisesCamacho01

Description

@MoisesCamacho01

Bug Report: "Missing unique key prop" Warning in Choropleth Legends with React 19

Library: @nivo/geo
Version: ^0.99.0
React Version: 19.1.0


Bug Description

When using the <ResponsiveChoropleth> component, providing a valid configuration to the legends prop causes React 19 to throw a "Each child in a list should have a unique 'key' prop" warning in the developer console.

The warning's stack trace clearly indicates that the issue originates from an internal Array.map call within the Choropleth.js file of the @nivo/geo library. It appears the list of legend items is being rendered without the required unique key prop.

Steps to Reproduce

  1. Set up a Next.js project using [email protected] and [email protected].
  2. Install @nivo/geo@^0.99.0.
  3. Implement a <ResponsiveChoropleth> component, passing a standard configuration object to the legends prop as shown in the code snippet below.
  4. Run the development server and observe the browser's developer console.

Expected Behavior

The map and its legend should render without any console warnings from React.

Actual Behavior

A "Missing unique key prop" warning is logged for each item in the legend.

Minimal Reproducible Example

This component reliably reproduces the warning.

// app/components/GeoChart.tsx
'use client';

import { useState, useEffect } from 'react';
import { ResponsiveChoropleth } from '@nivo/geo';
import * as topojson from "topojson-client";
import { Feature, FeatureCollection } from 'geojson';
import { Topology } from 'topojson-specification';

// Data using ISO 3166-1 numeric-3 codes
const geoData = [
    { "id": "840", "value": 450000 }, // USA
    { "id": "356", "value": 210000 }, // IND
    { "id": "826", "value": 180000 }, // GBR
];

const worldCountriesUrl = 'https://cdn.jsdelivr.net/npm/world-atlas@2/countries-110m.json';

export function GeoChart() {
  const [features, setFeatures] = useState<Feature[]>([]);

  useEffect(() => {
    const fetchData = async () => {
      const response = await fetch(worldCountriesUrl);
      const world = await response.json() as Topology;
      if (world.objects && world.objects.countries) {
        const countries = topojson.feature(world, world.objects.countries) as FeatureCollection;
        setFeatures(countries.features);
      }
    };
    fetchData();
  }, []);

  return (
    <div style={{ height: "400px" }}>
      <ResponsiveChoropleth
        data={geoData}
        features={features}
        margin={{ top: 0, right: 0, bottom: 0, left: 0 }}
        colors="purples"
        domain={[0, Math.max(...geoData.map(d => d.value))]}
        unknownColor="#E5E7EB"
        label="properties.name"
        valueFormat=".2s"
        projectionTranslation={[0.5, 0.6]}
        projectionRotation={[0, 0, 0]}
        borderWidth={0.5}
        borderColor="#ffffff"
        // The warning is triggered by this 'legends' prop
        legends={[
          {
            anchor: 'bottom-left',
            direction: 'column',
            justify: true,
            translateX: 20,
            translateY: -60,
            itemsSpacing: 0,
            itemWidth: 94,
            itemHeight: 18,
            itemDirection: 'left-to-right',
            itemTextColor: '#444444',
            itemOpacity: 0.85,
            symbolSize: 18,
          },
        ]}
      />
    </div>
  );
}

Relevant Stack Trace

The key frames from the stack trace pointing to the library code:

<unknown>
node_modules/@nivo/geo/src/Choropleth.js (124:33)
Array.map
<anonymous>
<unknown>
node_modules/@nivo/geo/src/Choropleth.js (123:44)
Array.map
<anonymous>
<unknown>
node_modules/@nivo/geo/src/Choropleth.js (106:21)
t.render
node_modules/@nivo/core/src/hocs/withContainer.js (25:21)

I attach an image of the bug

Image

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions