How To Generate Unique IDs Easily in React
Ever built a React app where users can add items to a list before saving them? Those temporary items need unique IDs for React keys and form associations, but they don’t exist in your database yet. Here’s how to handle this properly.
Why You Need Unique IDs
React needs stable keys for efficient list rendering, and you need IDs for accessibility (linking labels to inputs) and managing component state. Without proper IDs, React will unnecessarily re-render components and lose state.
The Wrong Way ❌
// Don't do this - generates new ID every render!
function BadList() {
const items = data.map(item => ({
...item,
id: Math.random() // New ID every time!
}));
return items.map(item => <li key={item.id}>{item.text}</li>);
}
This breaks React’s reconciliation and causes performance issues.
The Right Way ✅
Generate IDs once when you create the object, not during rendering:
import { useState } from 'react';
function generateId() {
return crypto.randomUUID();
}
function TodoApp() {
const [todos, setTodos] = useState([]);
const [input, setInput] = useState('');
function addTodo() {
if (!input.trim()) return;
const newTodo = {
id: generateId(), // Generated once, stored forever
text: input,
completed: false
};
setTodos(prev => [...prev, newTodo]);
setInput('');
}
function toggleTodo(id) {
setTodos(prev =>
prev.map(todo =>
todo.id === id
? { ...todo, completed: !todo.completed }
: todo
)
);
}
return (
<div>
<input
value={input}
onChange={e => setInput(e.target.value)}
placeholder="Add todo"
/>
<button onClick={addTodo}>Add</button>
<ul>
{todos.map(todo => (
<li key={todo.id}>
<input
type="checkbox"
id={`todo-${todo.id}`}
checked={todo.completed}
onChange={() => toggleTodo(todo.id)}
/>
<label
htmlFor={`todo-${todo.id}`}
style={{ textDecoration: todo.completed ? 'line-through' : 'none' }}
>
{todo.text}
</label>
</li>
))}
</ul>
</div>
);
}
Use the Web Crypto API
Modern browsers provide crypto.randomUUID() which generates a universally unique identifier (UUID) string:
const id = crypto.randomUUID();
// Example: "550e8400-e29b-41d4-a716-446655440000"
This is built-in, secure, and has virtually zero collision probability.
Key Takeaways
- Generate unique IDs when creating objects, not during renders
- Use crypto.randomUUID() for modern browsers
- Store the ID on the object to keep it stable
- This ensures React can efficiently track your list items
Your temporary client-side data deserves the same care as server data when it comes to unique identification. Generate once, use everywhere!