Coding exercise: build an autocomplete dropdown in React.

React practical coding · Freshers and experienced

Model answer

Combine a debounced input with a list of matches, keyboard control (arrows and Enter) and the right ARIA roles. Keep an "active index" in state.

function Autocomplete({ options, onSelect }) {
  const [q, setQ] = useState('');
  const [active, setActive] = useState(0);
  const matches = q ? options.filter((o) => o.toLowerCase().includes(q.toLowerCase())).slice(0, 6) : [];
  const choose = (v) => { onSelect(v); setQ(v); setActive(0); };
  const onKey = (e) => {
    if (e.key === 'ArrowDown') { e.preventDefault(); setActive((a) => Math.min(a + 1, matches.length - 1)); }
    if (e.key === 'ArrowUp') { e.preventDefault(); setActive((a) => Math.max(a - 1, 0)); }
    if (e.key === 'Enter' && matches[active]) choose(matches[active]);
  };
  return (
    <div>
      <input role="combobox" aria-expanded={matches.length > 0} aria-controls="opts" value={q}
             onChange={(e) => { setQ(e.target.value); setActive(0); }} onKeyDown={onKey} />
      {matches.length > 0 && (
        <ul id="opts" role="listbox">{matches.map((m, i) => (
          <li key={m} role="option" aria-selected={i === active} onMouseDown={() => choose(m)}>{m}</li>))}</ul>)}
    </div>
  );
}

onMouseDown is used so the choice happens before the input loses focus. For remote data, debounce the query and cancel old requests.

Tips

Practise it yourself in the React and Angular code playground.

Learn this topic

React.js Full Course: Beginner to Advanced .

Sign in to add your own answer.

More questions