Храните query и состояние запроса, кодируйте параметр URL и отменяйте предыдущий fetch при изменении ввода.
Вторая задача: реализуйте компонент поиска с использованием стандартного сервера через query-параметр — сделайте input для ввода запроса, состояния для результатов и запроса, получение данных через fetch в useEffect с обработкой ошибок и состояния загрузки, отрисовку списка результатов (поле name).
Храните query и состояние запроса, кодируйте параметр URL и отменяйте предыдущий fetch при изменении ввода.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Храните query и состояние запроса, кодируйте параметр URL и отменяйте предыдущий fetch при изменении ввода.
Пример предполагает /api/search?q=... и массив объектов с уникальным id и строкой name:
import { useEffect, useState } from 'react';
export default function Search() {
const [query, setQuery] = useState('');
const [state, setState] = useState({ status: 'loading', data: [] });
useEffect(() => {
let active = true;
const controller = new AbortController();
setState({ status: 'loading', data: [] });
async function load() {
try {
const res = await fetch('/api/search?' + new URLSearchParams({ q: query }),
{ signal: controller.signal });
if (!res.ok) throw new Error('Request failed');
const data = await res.json();
if (!Array.isArray(data) || !data.every(x => x &&
['string', 'number'].includes(typeof x.id) && typeof x.name === 'string')) {
throw new Error('Invalid response');
}
if (active) setState({ status: 'success', data });
} catch {
if (active && !controller.signal.aborted) setState({ status: 'error', data: [] });
}
}
load();
return () => { active = false; controller.abort(); };
}, [query]);
return <section>
<label>Поиск <input value={query} onChange={e => setQuery(e.target.value)} /></label>
{state.status === 'loading' && <p role="status">Загрузка...</p>}
{state.status === 'error' && <p role="alert">Ошибка загрузки</p>}
{state.status === 'success' && (state.data.length
? <ul>{state.data.map(x => <li key={x.id}>{x.name}</li>)}</ul>
: <p>Ничего не найдено</p>)}
</section>;
}
Debounce можно добавить отдельно; защита от устаревшего ответа нужна независимо от него.