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?
CodePudding user response:
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.
CodePudding user response:
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}));
CodePudding user response:
simplelly call Math.floor(Math.random() * 10)
on every push and use spread syntaxs
// changed let to const cause it's not re-assigned
const dataArray = [];
for (let i = 0; i < randomNum; i ) {
// this copies the original data and overwrite key to a new randomly
// generated key
dataArray.push({ ...data, key: Math.floor(Math.random() * 10) });
}
CodePudding user response:
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.