← Усі задачіReact · Senior
Пошук без гонки відповідей
Напишіть хук useSearch(query, search). search(query) повертає проміс із масивом результатів. Хук повертає { results, loading }: поки запит іде, loading дорівнює true.
Відповіді можуть приходити не в тому порядку, в якому йшли запити. Показувати треба лише результат для поточного query: застаріла відповідь, що прийшла пізніше, не повинна його перезаписати. Для порожнього query - results = [] без виклику search.
Ctrl+Enter - запустити тести. Tab - відступ; щоб вийти з редактора клавіатурою, натисніть Esc, а потім Tab. Код зберігається в цьому браузері.
Тести (4)
const search = (q) => Promise.resolve([q + '1']); const { result } = renderHook(({ q }) => useSearch(q, search), { initialProps: { q: 'a' } }); await waitFor(() => expect(result.current.results).toEqual(['a1'])); expect(result.current.loading).toBe(false);
const search = () => new Promise(() => {}); const { result } = renderHook(({ q }) => useSearch(q, search), { initialProps: { q: 'a' } }); await waitFor(() => expect(result.current.loading).toBe(true));
const pending = {}; const search = (q) => new Promise((resolve) => { pending[q] = resolve; }); const { result, rerender } = renderHook(({ q }) => useSearch(q, search), { initialProps: { q: 'a' } }); await waitFor(() => expect(typeof pending.a).toBe('function')); rerender({ q: 'ab' }); await waitFor(() => expect(typeof pending.ab).toBe('function')); pending.ab(['AB']); await waitFor(() => expect(result.current.results).toEqual(['AB'])); pending.a(['A']); await wait(30); expect(result.current.results).toEqual(['AB']);
const search = fn(() => Promise.resolve(['x'])); const { result } = renderHook(({ q }) => useSearch(q, search), { initialProps: { q: '' } }); await wait(30); expect(search).toHaveBeenCalledTimes(0); expect(result.current.results).toEqual([]); expect(result.current.loading).toBe(false);