Войти Регистрация
Код-ревью

18. Хук поиска с бесконечной лентой

Средняя

TypeScript · 36 строк

Хук useAdSearch грузит объявления по 20 штук и подгружает следующую страницу, когда пользователь докрутил до низа. Запрос и город меняются из строки поиска и фильтра.

Отметьте строки с ошибками.

В работе: Выдача поиска в веб-версии: самая посещаемая страница сайта.

Как проверяем Нажмите на строку с ошибкой и коротко напишите, что не так. Баг засчитан, если отмечена хотя бы одна его строка. Зачёт — найдено не меньше 60 % багов с учётом серьёзности (критичный весит 3, обычный 2, мелкий 1), а лишних отметок не больше, чем багов в коде. Пустые строки, скобки и комментарии лишними не считаем. Ответ один на подход: после него показываем разбор.
Reactхукиустаревшее замыканиегонка запросов

Источник: на задачах Авито: поиск и выдача объявлений. Условие пересказано своими словами.

Давали на собеседовании? Ответов пока мало — ваш поможет.
  1. import { useEffect, useState } from "react";
  2. type Ad = { id: number; title: string; price: number; city: string };
  3. export function useAdSearch(query: string, city: string) {
  4. const [ads, setAds] = useState<Ad[]>([]);
  5. const [page, setPage] = useState(1);
  6. const [hasMore, setHasMore] = useState(true);
  7. useEffect(() => {
  8. setPage(1);
  9. setAds([]);
  10. }, [query]);
  11. useEffect(() => {
  12. if (query.length < 2) return;
  13. fetch(`/api/search?q=${query}&city=${city}&page=${page}`)
  14. .then((r) => r.json())
  15. .then((data: { items: Ad[]; total: number }) => {
  16. setAds([...ads, ...data.items]);
  17. setHasMore(page * 20 <= data.total);
  18. });
  19. }, [query, city, page]);
  20. useEffect(() => {
  21. const onScroll = () => {
  22. if (hasMore && window.innerHeight + window.scrollY >= document.body.offsetHeight - 300) {
  23. setPage(page + 1);
  24. }
  25. };
  26. window.addEventListener("scroll", onScroll);
  27. return () => window.removeEventListener("scroll", onScroll);
  28. }, []);
  29. return { ads, hasMore };
  30. }