cf.completefrontend

Predict the outputMedium

Two lists, one keyed by name and one by index, are reversed. Which rows keep their state, and which <li> elements does React move?

Both lists render the same teas with the same Row, which keeps a liked flag in its own state. The first list uses each tea's name as the key, the second its index. A MutationObserver, set up after the first render, logs every <li> that React inserts into either list, including one it moves.

What does it log, and what does the page show?
import { useEffect, useRef, useState } from "react";
 
function Row({ name }) {
  const [liked, setLiked] = useState(false);
  return (
    <li>
      {name}
      {liked ? " (liked)" : ""}{" "}
      <button onClick={() => setLiked(true)}>Like {name}</button>
    </li>
  );
}
 
export default function App() {
  const [teas, setTeas] = useState(["Green", "Black", "Mint"]);
  const byName = useRef(null);
  const byIndex = useRef(null);
 
  useEffect(() => {
    const observer = new MutationObserver((records) => {
      for (const record of records) {
        for (const li of record.addedNodes) {
          console.log(record.target.getAttribute("aria-label") + ": inserted " + li.firstChild.data);
        }
      }
    });
    observer.observe(byName.current, { childList: true });
    observer.observe(byIndex.current, { childList: true });
    return () => observer.disconnect();
  }, []);
 
  return (
    <>
      <ul ref={byName} aria-label="By name">
        {teas.map((tea) => (
          <Row key={tea} name={tea} />
        ))}
      </ul>
      <ul ref={byIndex} aria-label="By index">
        {teas.map((tea, index) => (
          <Row key={index} name={tea} />
        ))}
      </ul>
      <button onClick={() => setTeas([...teas].reverse())}>Reverse</button>
    </>
  );
}

It runs in development, rendered as <App />, and then:

  1. You click Like Green in the list keyed by name.
  2. You click Like Green in the list keyed by index.
  3. You click Reverse.

The answer

Work out every line it logs, in order, and what the page shows at the end. Then check.

Checking your sign-in…