Frontend / React / key_property.md

Key Property in React

Updated 4 interview angles 6 min read source
On this page8
  1. Table of Contents
  2. What is the Key Property?
  3. Why Keys are Important
  4. Best Practices
  5. Common Mistakes
  6. Common Interview Questions
  7. Summary
  8. Interview angle

Key Property in React

The key prop is a special attribute that helps React identify which items have changed, been added, or been removed in lists.

Table of Contents

What is the Key Property?

The key prop is a special string attribute that React uses to identify elements in lists. It helps React track which items have changed, been added, or been removed.

Basic Usage:

javascript
function TodoList({ todos }) {
  return (
    <ul>
      {todos.map(todo => (
        <li key={todo.id}>{todo.text}</li>
      ))}
    </ul>
  );
}

Key Characteristics:

  • Unique: Each key should be unique among siblings
  • Stable: Should not change between renders
  • Predictable: Should be based on item identity, not position

Why Keys are Important

1. Efficient Reconciliation:

javascript
// Without keys - React doesn't know which items changed
function BadList({ items }) {
  return (
    <ul>
      {items.map(item => (
        <li>{item.text}</li> // No key
      ))}
    </ul>
  );
}

// With keys - React can efficiently track changes
function GoodList({ items }) {
  return (
    <ul>
      {items.map(item => (
        <li key={item.id}>{item.text}</li> // Has key
      ))}
    </ul>
  );
}

2. State Preservation:

javascript
function UserList({ users }) {
  return (
    <div>
      {users.map(user => (
        <UserCard
          key={user.id} // Preserves component state
          user={user}
        />
      ))}
    </div>
  );
}

function UserCard({ user }) {
  const [isExpanded, setIsExpanded] = useState(false);

  return (
    <div>
      <h3>{user.name}</h3>
      {isExpanded && <p>{user.email}</p>}
      <button onClick={() => setIsExpanded(!isExpanded)}>
        {isExpanded ? 'Hide' : 'Show'} Email
      </button>
    </div>
  );
}

3. Performance Optimization:

javascript
// React can efficiently update only changed items
const todos = [
  { id: 1, text: 'Learn React' },
  { id: 2, text: 'Build app' },
  { id: 3, text: 'Deploy' }
];

// If we add a new todo at the beginning
const newTodos = [
  { id: 4, text: 'Plan project' }, // New item
  { id: 1, text: 'Learn React' },   // Existing item
  { id: 2, text: 'Build app' },     // Existing item
  { id: 3, text: 'Deploy' }         // Existing item
];

// React knows to only create the new element, not re-render existing ones

Best Practices

1. Use Stable IDs:

javascript
// Good: Use unique, stable IDs
function TodoList({ todos }) {
  return (
    <ul>
      {todos.map(todo => (
        <li key={todo.id}>{todo.text}</li>
      ))}
    </ul>
  );
}

// Good: Use unique identifiers
function UserList({ users }) {
  return (
    <ul>
      {users.map(user => (
        <li key={user.email}>{user.name}</li>
      ))}
    </ul>
  );
}

2. Avoid Array Index:

javascript
// Bad: Using array index as key
function BadList({ items }) {
  return (
    <ul>
      {items.map((item, index) => (
        <li key={index}>{item.text}</li> // Unstable key
      ))}
    </ul>
  );
}

// Good: Use stable identifiers
function GoodList({ items }) {
  return (
    <ul>
      {items.map(item => (
        <li key={item.id}>{item.text}</li> // Stable key
      ))}
    </ul>
  );
}

3. Generate Keys for Dynamic Lists:

javascript
// Good: Generate unique keys
function DynamicList({ items }) {
  return (
    <ul>
      {items.map((item, index) => (
        <li key={`${item.type}-${item.id}-${index}`}>
          {item.text}
        </li>
      ))}
    </ul>
  );
}

// Good: Use timestamp + random for truly unique keys
function UniqueList({ items }) {
  return (
    <ul>
      {items.map(item => (
        <li key={`${Date.now()}-${Math.random()}`}>
          {item.text}
        </li>
      ))}
    </ul>
  );
}

4. Keys in Nested Lists:

javascript
function NestedList({ categories }) {
  return (
    <div>
      {categories.map(category => (
        <div key={category.id}>
          <h2>{category.name}</h2>
          <ul>
            {category.items.map(item => (
              <li key={`${category.id}-${item.id}`}>
                {item.name}
              </li>
            ))}
          </ul>
        </div>
      ))}
    </div>
  );
}

Common Mistakes

1. Using Index as Key:

javascript
// Problem: Index changes when items are reordered
const items = ['Apple', 'Banana', 'Cherry'];

// Initial render
items.map((item, index) => <li key={index}>{item}</li>);
// Renders: key="0" -> Apple, key="1" -> Banana, key="2" -> Cherry

// After removing first item
items = ['Banana', 'Cherry'];
items.map((item, index) => <li key={index}>{item}</li>);
// Renders: key="0" -> Banana, key="1" -> Cherry
// React thinks Banana changed from "Apple" to "Banana"

2. Using Random Values:

javascript
// Problem: New key on every render
function BadList({ items }) {
  return (
    <ul>
      {items.map(item => (
        <li key={Math.random()}>{item.text}</li> // New key every time
      ))}
    </ul>
  );
}

// Solution: Use stable identifiers
function GoodList({ items }) {
  return (
    <ul>
      {items.map(item => (
        <li key={item.id}>{item.text}</li> // Stable key
      ))}
    </ul>
  );
}

3. Missing Keys:

javascript
// Problem: React warning and inefficient updates
function BadList({ items }) {
  return (
    <ul>
      {items.map(item => (
        <li>{item.text}</li> // No key
      ))}
    </ul>
  );
}

// Solution: Always provide keys
function GoodList({ items }) {
  return (
    <ul>
      {items.map(item => (
        <li key={item.id}>{item.text}</li> // Has key
      ))}
    </ul>
  );
}

4. Non-Unique Keys:

javascript
// Problem: Duplicate keys
function BadList({ items }) {
  return (
    <ul>
      {items.map(item => (
        <li key="item">{item.text}</li> // Same key for all items
      ))}
    </ul>
  );
}

// Solution: Unique keys
function GoodList({ items }) {
  return (
    <ul>
      {items.map(item => (
        <li key={item.id}>{item.text}</li> // Unique key
      ))}
    </ul>
  );
}

Common Interview Questions

Q: What is the key prop in React?

  • A special attribute that helps React identify which items have changed, been added, or been removed in lists.

Q: Why are keys important in React?

  • They help React efficiently track and update list items, preserve component state, and optimize performance.

Q: What happens if you don’t provide a key?

  • React will use array index as key, which can cause issues with state preservation and inefficient updates.

Q: Can you use array index as a key?

  • It’s not recommended because it can cause issues when items are reordered, added, or removed from the list.

Q: What makes a good key?

  • Unique, stable, and predictable identifiers that don’t change between renders.

Q: How do keys help with performance?

  • They allow React to efficiently update only the items that have changed instead of re-rendering the entire list.

Q: What happens if you use duplicate keys?

  • React will warn about duplicate keys and may not work correctly with state preservation.

Summary

  • Keys help React identify and track list items efficiently
  • Unique and stable keys are essential for proper reconciliation
  • Avoid array index as keys when items can be reordered
  • Use stable identifiers like database IDs or unique properties
  • Keys preserve component state when items are reordered
  • Missing keys cause React warnings and inefficient updates
  • Duplicate keys can cause unexpected behavior
  • Keys are crucial for performance optimization in dynamic lists

Interview angle 4

  • “What does key do?” - gives an element a stable identity across renders so reconciliation can match, move and preserve state instead of destroying and rebuilding. It is a hint to React, never readable as a prop.
  • “Why are index keys dangerous?” - they are positional. Insert at the front, delete, or reorder, and React matches item 0 to a different item: DOM state such as input text, focus and scroll position sticks to the wrong row. Index keys are only safe for a list that is static and never reordered or filtered.
  • “How do you deliberately reset state?” - change the key. Giving a component key={userId} remounts it when the user changes, which is the cleanest way to clear internal state without an effect.
  • “Must keys be globally unique?” - only among siblings.