Fuse.js — библиотека для «нечёткого» поиска по массивам прямо в браузере: находит результаты с опечатками и частичными совпадениями, поддерживает веса полей и работает без сервера.
Быстрый старт:
— получите отсортированный по релевантности список.
#javascript #гайды #frontend #сайтыподключ
Быстрый старт:
const fuse = new Fuse(items, { keys: ['title', 'tags'], threshold: 0.3 });
const results = fuse.search('react hooks');
— получите отсортированный по релевантности список.
#javascript #гайды #frontend #сайтыподключ
useMemo в React — кэшируем «дорогие» вычисления и фиксируем ссылочные значения, чтобы не дёргать лишние рендеры.
Пример:
— пересчёт только при изменении зависимостей.
Стабилизация пропсов:
передайте columns в дочерний компонент с React.memo — он не перерендерится из‑за новой ссылки.
Совет:
Применяйте useMemo для тяжёлых вычислений и стабилизации массивов/объектов в зависимостях; не используйте для побочных эффектов и не оборачивайте «на всякий случай».
#react #hooks #гайды #javascript #frontend
Пример:
const visible = useMemo(() => items.filter(it => it.title.includes(query)).sort(sorter[sortKey]), [items, query, sortKey]);
— пересчёт только при изменении зависимостей.
Стабилизация пропсов:
const columns = useMemo(() => [{id: 'name'}, {id: 'age'}], []);
передайте columns в дочерний компонент с React.memo — он не перерендерится из‑за новой ссылки.
Совет:
Применяйте useMemo для тяжёлых вычислений и стабилизации массивов/объектов в зависимостях; не используйте для побочных эффектов и не оборачивайте «на всякий случай».
#react #hooks #гайды #javascript #frontend
Отменяйте «устаревшие» запросы при живом поиске: AbortController защищает от гонок (когда медленный ответ перезаписывает свежие данные) и экономит трафик.
let controller;
async function search(query) {
controller?.abort(); // отменяем предыдущий
controller = new AbortController();
try {
const res = await fetch('/api/search?q=' + encodeURIComponent(query), { signal: controller.signal });
if (!res.ok) throw new Error('HTTP ' + res.status);
const data = await res.json();
renderResults(data);
} catch (e) {
if (e.name !== 'AbortError') showError(e); // игнорируем отмену
}
}
Советы: добавьте debounce ввода (≈150–300 мс), при необходимости ставьте таймаут (setTimeout(() => controller.abort(), 8000)) и очищайте его в finally. В React храните контроллер в useRef и отменяйте в cleanup эффекта.
#фишки #javascript #frontend #performance #гайды
let controller;
async function search(query) {
controller?.abort(); // отменяем предыдущий
controller = new AbortController();
try {
const res = await fetch('/api/search?q=' + encodeURIComponent(query), { signal: controller.signal });
if (!res.ok) throw new Error('HTTP ' + res.status);
const data = await res.json();
renderResults(data);
} catch (e) {
if (e.name !== 'AbortError') showError(e); // игнорируем отмену
}
}
Советы: добавьте debounce ввода (≈150–300 мс), при необходимости ставьте таймаут (setTimeout(() => controller.abort(), 8000)) и очищайте его в finally. В React храните контроллер в useRef и отменяйте в cleanup эффекта.
#фишки #javascript #frontend #performance #гайды