Why is React complaining I do not have unique keys if my keys typeof number?

Koray Tugay :

I have the following iteration of option elements for a select list:

{allCustomers.map(customer => {
    console.log(customer.id);
    console.log(typeof(customer.id));
    return (
        <option
            key={customer.id}
        >
            {customer.name}
        </option>
    );
})}

The list of customers I have all have unique ids and the id property is of type number. Here is what I see in the console for the logs statements I have:

1
number
2
number
3
number
4

With the snippet above I kept getting:

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

Then I tried the following and React was happy:

key={'' + customer.id}

Is this the proper way to use numbers as key in React? What is the reason that React is thinking I have duplicate keys in case I leave them as numbers?

Edit This is the allCustomers list I have:

[
  {id: 1, name: "Test Customer - 1", orderSchedules: Array(1)}
  {id: 2, name: "Test Customer - 2", orderSchedules: Array(0)}
  {id: 3, name: "Another Test Customer", orderSchedules: Array(1)}
  {id: 4, name: "Foo Bar Baz", orderSchedules: Array(1)}
]

Edit - Full Code

import React from "react";

export default (props) => {
    const {
        orderSchedule,
        setOrderSchedule,
        allCustomers,
        saveHandler,
    } = props;

    return (
        <>
            <h3>Order Schedule Details</h3>
            <hr/>
            <form onSubmit={saveHandler}>
                <div className="form-group row">
                    <label htmlFor="order-schedule-detail-description-input">Order Schedule Description</label>
                    <input
                        id="order-schedule-detail-description-input"
                        type="text"
                        className="form-control"
                        value={orderSchedule.description}
                        onChange={(event) => {
                            setOrderSchedule({
                                ...orderSchedule,
                                description: event.target.value
                            })
                        }}/>
                    <br/>
                    <br/>
                    <select
                        className="custom-select"
                        onChange={event => {
                            setOrderSchedule({
                                ...orderSchedule,
                                customer: {
                                    id: event.target.value
                                }
                            });
                        }}
                    >
                        {allCustomers && allCustomers.map(customer => {
                            return (
                                <option
                                    value={customer.id}
                                    key={customer.id}
                                >
                                    {customer.name}
                                </option>
                            );
                        })}
                    </select>
                </div>
                <div className="form-group row">
                    <button type="submit"
                            className="btn btn-primary"
                    >
                        Save
                    </button>
                    &nbsp;
                </div>
            </form>
        </>
    );
}

Edit - My Container Class

import React, {useEffect, useState} from "react";
import {useParams} from "react-router-dom";
import * as orderScheduleController from "./orderScheduleController";
import * as customerController from "./../customer/customerController";
import OrderScheduleDetails from "./OrderScheduleDetails";

export default ({history}) => {
    let {id} = useParams();

    const [orderSchedule, setOrderSchedule] = useState({
        description: '',
        customer: {}
    });

    const [allCustomers, setAllCustomers] = useState([{}]);

    useEffect(() => {
        if (id) {
            orderScheduleController.getOrderSchedule(id)
                .then(response => {
                    setOrderSchedule(response.data);
                });
        }
    }, []);

    useEffect(() => {
        customerController.getAllCustomers()
            .then(response => {
                setAllCustomers(response.data);
            });
    }, []);

    function saveHandler(event) {
        event.preventDefault();
        if (!orderSchedule.description) {
            return;
        }
        orderScheduleController
            .createOrderSchedule(orderSchedule)
            .then(() => {
                history.push('/orderSchedules');
            });
    }

    return (
        <OrderScheduleDetails
            orderSchedule={orderSchedule}
            setOrderSchedule={setOrderSchedule}
            allCustomers={allCustomers}
            saveHandler={saveHandler}
        />
    )
}
coreyward :

Keys have to be unique across their siblings. It's possible that you have other children that are being rendered inside of the parent container that share one or more of the keys you’re specifying here. Your '' + customer.id hack would work because 1 === '1' is false.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=18277&siteId=1