cf.completefrontend

Write the codeMedium

Build an AutoGrowList that scrolls each new item into view

AutoGrowList shows a list of items, starting with its initialItems prop (an array of strings), and a form with a field labelled New item and an Add button. The starter already adds items: submitting the form appends the trimmed text, ignores blank text, and empties the field.

Finish it: every time an item is added, call scrollIntoView({ block: "nearest" }) on the new item's <li>, so it's visible even when the list is taller than its box. Don't scroll when the list first shows, or when nothing was added.

Write this (AutoGrowList.jsx)
import { useRef, useState } from "react";
 
export default function AutoGrowList({ initialItems = [] }) {
  const [items, setItems] = useState(() => initialItems.map((text, index) => ({ id: index, text })));
  const [draft, setDraft] = useState("");
  const nextId = useRef(initialItems.length);
 
  function handleSubmit(event) {
    event.preventDefault();
    const text = draft.trim();
    if (!text) return;
    setItems([...items, { id: nextId.current++, text }]);
    setDraft("");
    // Scroll the new item into view.
  }
 
  return (
    <div>
      <ul className="list">
        {items.map((item) => (
          <li key={item.id}>{item.text}</li>
        ))}
      </ul>
      <form onSubmit={handleSubmit}>
        <label>
          New item <input value={draft} onChange={(event) => setDraft(event.target.value)} />
        </label>
        <button>Add</button>
      </form>
    </div>
  );
}
The checks your code must pass
  • shows the starting items
  • adds the typed item at the end and empties the field
  • scrolls the new item into view
  • scrolls to each new item, not the one before it
  • scrolls with block: nearest
  • doesn't scroll on the first render or for blank text

The answer

Write it yourself first. Then compare it with a reference solution and the checks it passes.

Checking your sign-in…