0Pricing
React Academy · Lesson

Key & Ref Best Practices

Use stable keys, avoid index-as-key pitfalls, and work with callback refs.

Key & Ref Best Practices is a free React Academy lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the React Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

Welcome

In this lesson you will learn how to use list keys correctly, why using array index as a key causes bugs, and how to work with callback refs and forwarded refs.

Why Keys Matter

React uses `key` props to track which items in a list changed, were added, or were removed between renders. A correct key lets React reuse existing DOM nodes; a wrong key causes unnecessary unmounts and remounts.

Stable Unique Keys

The best key is a stable, unique ID from your data — like a database row ID or a UUID. This key must be unique among siblings only, not globally across the whole page.
users.map(user => (
  <UserCard key={user.id} user={user} />
))

Why Index as Key Is Problematic

Using the array index as a key works fine for static lists, but causes bugs in sorted or filtered lists. When items reorder, React matches components by index and reuses the wrong DOM nodes, corrupting input values and animation state.
// Risky when list can reorder or filter
items.map((item, i) => <Row key={i} {...item} />)

When Index Key Is Acceptable

Index-as-key is acceptable only when: (1) the list never reorders or filters, (2) items have no stable ID, and (3) items have no local state (e.g. input values). Static display lists are fine.

Generating Stable IDs

If your data has no ID, generate one at the time you create the item (not during render). You can use `crypto.randomUUID()` or the `nanoid` library.
const newItem = { id: crypto.randomUUID(), text: 'Buy milk' };

useRef Basics

`useRef` returns a mutable object whose `.current` value persists across renders without causing re-renders. It is used to hold DOM references and mutable values like timer IDs.
const inputRef = useRef(null);
<input ref={inputRef} />
// Access DOM node: inputRef.current.focus();

Callback Refs

Instead of passing a ref object, you can pass a **callback ref** — a function that React calls with the DOM node when it mounts and with `null` when it unmounts. This lets you set up logic exactly when the node becomes available.
function Input() {
  return (
    <input
      ref={node => {
        if (node) node.focus();
      }}
    />
  );
}

forwardRef for Component Refs

Function components do not accept `ref` as a regular prop. Wrap the component in `React.forwardRef` to let parent components attach a ref to an internal DOM node.
const FancyInput = React.forwardRef((props, ref) => (
  <input ref={ref} className="fancy" {...props} />
));

// Parent
const inputRef = useRef(null);
<FancyInput ref={inputRef} />

useImperativeHandle

When a parent holds a ref to a child, you can control exactly what it exposes using `useImperativeHandle`. This keeps the child's internal DOM private while providing a clean imperative API.
const Child = forwardRef((_, ref) => {
  const innerRef = useRef();
  useImperativeHandle(ref, () => ({
    focus: () => innerRef.current.focus(),
  }));
  return <input ref={innerRef} />;
});

Quick Check

Why should you avoid using the array index as a key in a list that can be reordered?

Recap

Use stable data IDs as keys, avoid index keys in dynamic lists, use useRef for DOM access and mutable values, use callback refs for mount/unmount logic, and use forwardRef to expose refs from child components.

Up Next

Next lesson: **Folder Structure & Naming Conventions** — you will organise a React project with feature-based folders and consistent file naming.

Frequently asked questions

Is the “Key & Ref Best Practices” lesson free?

Yes — the full text of “Key & Ref Best Practices” is free to read here on the web, and the React Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the React Academy course, upgrade to CoddyKit PRO.

What will I learn in “Key & Ref Best Practices”?

Use stable keys, avoid index-as-key pitfalls, and work with callback refs. You practise React Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start React Academy?

No prior experience is required. React Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Key & Ref Best Practices” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this React Academy lesson?

Yes. Every React Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. What StrictMode Does
  2. Pure Components & Avoiding Side Effects in Render
  3. Key & Ref Best Practices
  4. Folder Structure & Naming Conventions
← Back to React Academy