Reputation: 23780
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 customer
s I have all have unique id
s 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>
</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}
/>
)
}
Upvotes: 3
Views: 461
Reputation: 80041
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
.
Upvotes: 3