DEV Community

Cover image for Add a unique id and use it as a key
Ahmed Yagoub
Ahmed Yagoub

Posted on • Edited on

Add a unique id and use it as a key

Introduction

If you use Vue or React, you must know about keys. They are mostly used with lists such as

const todoItems = todos.map((todo) =>
  <li key={todo.id}>
    {todo.text}
  </li>
);
Enter fullscreen mode Exit fullscreen mode

and in Vue:

<ul>
  <li v-for="todo in todos" :key="todo.id">
    {{ todo.text }}
  </li>
</ul>
Enter fullscreen mode Exit fullscreen mode

Avoid using index as key

Both React and Vue advice against using the index as a key especially if the order of items may change. As if you want to allow users to reorder items.

// not recommended to use index as key
<ul>
  <li v-for="(todo, index) in todos" :key="index">
    {{ todo.text }}
  </li>
</ul>
Enter fullscreen mode Exit fullscreen mode

Sometimes we are lucky enough that our data comes with a unique id that identifies each of the items.

Other times, we are not so lucky. The items don't have unique ids. Or they do, but we want to render the item more than once. In that case, if we use the id as a key, we will run into duplicate keys issue.

We will have to create unique ids for the items and use them as keys.

Generate keys

There are many ways to do that. I will choose Lodash's uniqueId method since Lodash is used in the project I am working on and there is no need to load another library

import uniqueId from 'lodash/uniqueId';
Enter fullscreen mode Exit fullscreen mode

Before rendering todos, loop through it and add a uniquekey

todos.forEach((todo) => {
  todo.uniqueKey = uniqueId();
});
Enter fullscreen mode Exit fullscreen mode

Then, you can use todo.uniqueKey as a key. uniqueId() will generate a unique id for each todo. However, sometimes those ids might clash with other ids for a different list in the page. We can take it further and add an argument to uniqueId('todo_') to avoid duplicate keys.

Final thoughts

This uniqueKey was only added to do a particular job in the frontend. We probably wouldn't need to send it to the backend. So, before sending todos to the backend, make sure to delete the uniqueKey

todos.forEach((todo) => {
  todo.uniqueKey && delete todo.uniqueKey;
});
Enter fullscreen mode Exit fullscreen mode

Thanks for reading

Top comments (2)

Collapse
 
lexlohr profile image
Alex Lohr

Unless you can make use of tree-shaking, you should use a dedicated package instead of lodash, because otherwise all of lodash is going to be included in your package.

Collapse
 
ahyagoub40 profile image
Ahmed Yagoub

Correct,
can probably 'cherry pick' the method
npm i --save lodash.uniqueid
and import it in the file as so
import uniqueId from 'lodash.uniqueid'
The main reason I went with lodash because it might already be used in the project, if it is not, I agree with you on using a dedicated package
Thanks for reading and for your comment