I want to push an object into an array a random amount of times and have each object have it's own unique id. Currently, I am able to push that object into the array a random amount of times but am getting "Each child in a list should have a unique "key" prop." error. When I console.log the array, I do see that every object has the same key.
I have some code set up to generate a unique ID, but it doesn't seem to work.
Here is my data object that I am calling:
let id = Math.random().toString(16).slice(2);
export const data = {
key: id,
asylumOffice: 'AyS',
citizenship: 'h',
raceOrEthnicity: 'other',
caseOutcome: 'pending',
completion: 'n',
currentDate: 'f',
};
And the code where I am calling it and generating a random amount:
let dataArray = [];
let randomNum = Math.floor(Math.random() * 10);
for (let i = 0; i < randomNum; i++) {
dataArray.push(data);
}
I understand that the for loop is pushing the same instance of data and that's why they all have the same id, but I don't know how to make it so that they each have their own. Any suggestions?
If you want to generate really unique id’s, you should use uuid.
Here is the npm package. It is fairly easy to setup and use.
From the React docs for Lists and Keys:
The best way to pick a key is to use a string that uniquely identifies a list item among its siblings.
So keys don't need to be random: they just need to be unique amongst siblings. And for that reason, using a plain integer for a fixed key is just fine:
const count = Math.floor(Math.random() * 10);
const dataArray = [...new Array(count).keys()].map(key => ({...data, key}));
If you don't mind taking the chance of random number collision on the ids, then just spread new random ids into your objects as you build the array. I might do it like this:
const randomCopies = (data) => [...Array (Math .floor (Math .random () * 10))] .map(() => ({
id: Math .random() .toString(16) .slice (2),
... data
}))
const data = {asylumOffice: 'AyS', citizenship: 'h', raceOrEthnicity: 'other', caseOutcome: 'pending', completion: 'n', currentDate: 'f'}
console .log (randomCopies (data))
.as-console-wrapper {max-height: 100% !important; top: 0}
But if this is just to avoid collisions, then a sequential number will be cleaner, and you could do this instead:
const seqNumber = ((n) => () => ++n) (0)
const randomCopies = (data) => [...Array (Math .floor (Math .random () * 10))] .map(() => ({
id: seqNumber(),
... data
}))
const data = {asylumOffice: 'AyS', citizenship: 'h', raceOrEthnicity: 'other', caseOutcome: 'pending', completion: 'n', currentDate: 'f'}
console .log (randomCopies (data))
.as-console-wrapper {max-height: 100% !important; top: 0}
In either case, this will choose a random number of copies from 0 to 9. If you want from 1 to 10, then you will need to add 1 to the results of the Math.floor call.