BRUCE_FEBRUCE_FE

EN/CH Mode

BRUCE_FE React Interview Notes - Understanding React Key Usage

Deep dive into React key property: its purpose, proper usage, common mistakes, and performance impact. Learn why not to use index as key, how keys help React identify element changes, and the relationship between React reconciliation algorithm and keys.

影片縮圖

Lazy to read articles? Then watch videos!

What is the Purpose of React Key?

In React, key is a special prop primarily used to help React identify elements in a list. It acts like an "ID card" for each element, allowing React to quickly determine which elements have changed.

Main purposes of Key:

  • 1. Improve DOM update efficiency
  • 2. Maintain component state persistence
  • 3. Avoid unnecessary re-renders
  • 4. Ensure list element uniqueness

Relationship Between Key and React List Rendering

When React renders lists, it needs to know which elements need to be updated, added, or removed.

Without key: React can only compare by position

Original list:

Position 0: Apple

Position 1: Banana

Position 2: Orange

Add 'Mango' to the beginning:

Position 0: Apple→Mango (update)

Position 1: Banana→Apple (update)

Position 2: Orange→Banana (update)

Position 3: Add Orange

With key: React can compare by identity

Original list:

key="a": Apple

key="b": Banana

key="c": Orange

Add 'Mango' to the beginning:

key="m": Add Mango

key="a": Apple (unchanged)

key="b": Banana (unchanged)

key="c": Orange (unchanged)

Problems with Using Index as Key

⚠️ When list order changes, using index as key leads to unnecessary DOM updates:

// Bad practice if list will update
{items.map((item, index) => (
  <Item key={index} data={item} />
))}

// Good practice
{items.map(item => (
  <Item key={item.id} data={item} />
))}

Key Can Also Be Used to Force Component Recreation

Component instances, state, and DOM are closely tied to their keys. When the key changes, even if the component type remains the same, React will:

  • 1. Completely unmount the old component instance (triggering useEffect cleanup functions)
  • 2. Create a new component instance (re-triggering useEffect)
  • 3. Reset all internal component state
  • 4. Rebuild DOM nodes

This behavior can be intentionally used to force component state reset:

// Using key to reset form component
function ResetableForm({ formData, resetKey }) {
  return (
    <Form 
      key={resetKey}  // When resetKey changes, the entire Form component will reset
      initialValues={formData}
    >
      {/* Form content */}
    </Form>
  );
}

// Usage example
function ProfileEditor() {
  const [user, setUser] = useState(null);
  const [resetCounter, setResetCounter] = useState(0);
  
  // When user changes, we can reset the form by changing the key
  return (
    <div>
      <UserSelector onSelect={setUser} />
      <ResetableForm 
        formData={user} 
        resetKey={user?.id || resetCounter} 
      />
      <button onClick={() => setResetCounter(c => c + 1)}>
        Reset Form
      </button>
    </div>
  );
}

Key Best Practices

Choosing the Right Key

  • Prioritize stable, unique IDs: Data usually has inherent IDs, like database primary keys, UUIDs, etc.
  • Consider content hash next: If no ID is available, generate a hash based on content
  • Avoid random values: Random keys generated on each render will cause all components to re-render
  • Use index as last resort: Only use index when items are stable and won't be reordered

Common Mistakes

// ❌ Wrong: Using index as key for mutable lists
{items.map((item, index) => (
  <TodoItem key={index} item={item} />
))}

// ❌ Wrong: Using random values or timestamps as key
{items.map(item => (
  <TodoItem key={Math.random()} item={item} />
))}

// ✅ Correct: Using inherent ID
{items.map(item => (
  <TodoItem key={item.id} item={item} />
))}

// ✅ Alternative: Combining index with stable identifying property
{items.map((item, index) => (
  <TodoItem key={`${item.name}-${index}`} item={item} />
))}

🔥 Common Interview Questions

(1) Why do we need keys in React? What are the consequences of not providing keys?

Answer: React uses keys to identify elements in a list, like an ID number for each person. With keys, React can:

  • 1. Know which elements have changed, been added, or removed
  • 2. Decide whether to reuse elements instead of rebuilding them
  • 3. Correctly preserve element state

Consequences of not having keys:

Original List

Item A (typing)
Item B

After Deleting A

Item B (input lost)

When no key is provided, React defaults to using index, which leads to these issues when the list changes:

  • 1. Performance degradation (excessive DOM rebuilding)
  • 2. UI confusion (e.g., incorrect selection states)
  • 3. State confusion (e.g., input content appearing in wrong places)

(2) Why is using index as key not recommended? When is it acceptable to use?

Answer: Index is just a position number, not representing the item itself. When the list changes, the same index might correspond to different items:

// Original list: index to item mapping
[0: Apple, 1: Banana, 2: Orange]

// After deleting Apple: same indices now map to different items!
[0: Banana, 1: Orange]

This leads to:

  • 1. Components being unnecessarily rebuilt
  • 2. Form input values appearing in wrong places
  • 3. State confusion

Index can only be used when all these conditions are met:

  • 1. The list will never be reordered
  • 2. Items won't be added/removed
  • 3. Items don't have IDs
  • 4. Components don't have state

(3) How to correctly generate key values? What are common strategies?

Answer: Good keys should be stable and unique, in order of priority:

  1. Data ID: The ideal choice
    <Item key={user.id} />
  2. Content Hash: When no ID is available
    <Item key={hash(item.content)} />
  3. Generated ID: Created during initialization
    // Add ID during initialization
    const data = items.map(i => ({...i, id: uuid()}))