Гид по технологиям

Как создать поисковую строку в React с фильтрацией в реальном времени

4 min read Frontend Обновлено 05 Dec 2025
Поисковая строка в React: фильтр в реальном времени
Поисковая строка в React: фильтр в реальном времени

Лупа на открытой книге

Поисковые строки помогают пользователям быстро находить нужный контент на сайте. Они также полезны для аналитики — по запросам видно, что ищут посетители.

React отлично подходит для реализации отзывчивой поисковой строки. С помощью хуков и методов массива filter/map вы получите поиск в реальном времени, который быстро реагирует на ввод.

Что понадобится

  • Базовый проект React (create-react-app или другой).
  • Понимание хуков useState и обработчиков событий onChange.
  • Исходные данные — локальный массив или API.

Если у вас ещё нет проекта, создайте его командой:

npx create-react-app search-bar

Базовая форма ввода

Добавьте в файл App.js простую форму с input:

export default function App() {
  return (
    
) }

Далее контролируйте значение input через состояние. Импортируйте useState и добавьте обработчик onChange:

import { useState } from 'react'

export default function App() {
  const [query, setQuery] = useState('')

  const handleChange = (e) => {
    setQuery(e.target.value)
  }

  return (
    
) }

Каждый ввод обновляет состояние query через handleChange.

Фильтрация данных при вводе

По сути, поисковая строка должна фильтровать набор данных по введённому запросу. Удобно хранить и сам запрос, и отфильтрованный список в одном объекте состояния, чтобы уменьшить число рендеров:

const [state, setState] = useState({
  query: '',
  list: []
})

Пример данных — список постов:

const posts = [
  {
    url: '',
    tags: ['react', 'blog'],
    title: 'How to create a react search bar',
  },
  {
    url: '',
    tags: ['node', 'express'],
    title: 'How to mock api data in Node',
  },
  // more data here
]

В обработчике onChange выполните фильтрацию и сохраните результаты в состоянии:

const handleChange = (e) => {
  const value = e.target.value
  const results = posts.filter(post => {
    if (value === '') return true
    return post.title.toLowerCase().includes(value.toLowerCase())
  })

  setState({
    query: value,
    list: results
  })
}

Заметьте: когда query пустой, мы возвращаем все элементы (или можно вернуть пустой список — зависит от UX). Приведение строк к нижнему регистру делает поиск нечувствительным к регистру.

Отображение результатов

Для вывода списка используйте map по state.list. Часто полезно скрывать результаты, пока query пустой:

export default function App() {
  // state и handleChange
  return (
    
    {(state.query === '' ? '' : state.list.map(post => { return
  • {post.title}
  • }))}
) }

Можно улучшить UX, показывая сообщение, если результатов нет:

    {state.query === '' ? 'Введите запрос для поиска' : (!state.list.length ? 'По вашему запросу ничего не найдено' : state.list.map(post =>
  • {post.title}
  • ))}

Это помогает пользователю понять, что поиск выполнен и просто не дал совпадений.

Поиск по нескольким полям

В простейшем варианте мы ищем только по title. Чтобы расширить поиск на другие поля (например tags или url), используйте логический OR:

const results = posts.filter(post => {
  const q = value.toLowerCase()
  return (
    post.title.toLowerCase().includes(q) ||
    post.tags.join(' ').toLowerCase().includes(q) ||
    (post.url && post.url.toLowerCase().includes(q))
  )
})

Так поиск станет более гибким и полезным для пользователей.

Альтернативные подходы

  • Debounce вводов: используйте debounce (lodash или собственную реализацию), если фильтрация тяжёлая или идёт запрос на сервер. Это уменьшит число запросов и рендеров.
  • Поиск на сервере: при больших наборах данных отправляйте запросы на сервер с query, чтобы сервер возвращал уже отфильтрованный список.
  • Индексация и полнотекстовый поиск: для сложных сценариев используйте поисковые движки (Elasticsearch, Algolia, Typesense) или БД с полнотекстовым поиском.
  • Использование библиотек UI: готовые компоненты (Downshift, react-select) облегчают клавиатурную навигацию и доступность.

Когда такой подход не подойдёт

  • Очень большие объёмы данных в клиенте — фильтрация на клиенте будет медленной.
  • Нужна релевантность, ранжирование или синонимы — лучше использовать поисковый движок.
  • Конфиденциальные данные, которые нельзя выгружать на клиент — поиск только на сервере.

Мини‑методология разработки

  1. Определите источник данных: локальный массив или API.
  2. Решите, где будет фильтрация: клиент или сервер.
  3. Добавьте контролируемый input с useState.
  4. Реализуйте фильтрацию и кеширование результатов при необходимости.
  5. Добавьте debounce, если нужен.
  6. Протестируйте UX: пустой запрос, нет результатов, быстрое печатание.

Чек‑лист перед выпуском

  • Ввод доступен с клавиатуры.
  • Фокус и aria-атрибуты для экранных читалок (aria-label, role).
  • Debounce для сетевых запросов.
  • Показ состояния загрузки при запросе к API.
  • Сообщения при пустом результате.
  • Тесты: unit для фильтрации, e2e для UX.

Критерии приёмки

  • Поиск возвращает ожидаемые элементы при вводе релевантных запросов.
  • Интерфейс не блокируется при быстром вводе.
  • Для пустого запроса поведение согласовано с требованиями (показывать все/пустое).
  • Есть тесты на фильтрацию и на крайние случаи.

Пример решения с debounce (шаблон)

import { useState, useEffect } from 'react'
import debounce from 'lodash/debounce'

export default function Search() {
  const [query, setQuery] = useState('')
  const [list, setList] = useState([])

  const doSearch = (q) => {
    // фильтрация или вызов API
    const results = posts.filter(p => p.title.toLowerCase().includes(q.toLowerCase()))
    setList(results)
  }

  // debounce на 300 мс
  const debouncedSearch = debounce(doSearch, 300)

  useEffect(() => {
    if (query === '') {
      setList([])
      return
    }
    debouncedSearch(query)
    return () => debouncedSearch.cancel()
  }, [query])

  return (
    
setQuery(e.target.value)} />
    {list.map(item =>
  • {item.title}
  • )}
) }

Решение для больших данных

Если данных много, выполняйте поиск на сервере. Клиент отправляет query и получает уже отфильтрованный и, при необходимости, постранично разбитый набор.

// отправлять запрос на сервер с параметром ?q=...
// сервер возвращает только нужную страницу результатов

Ментальные модели и эвристики

  • «Делай мало на клиенте, если можно сделать много на сервере» — для производительности.
  • «Debounce — друг пользователя» — уменьшает количество запросов при быстром вводе.
  • «Покажи состояние» — индикаторы загрузки и сообщения при пустом результате улучшают UX.

Диагностическое дерево для выбора подхода

flowchart TD
  A[Небольшой набор данных < 1000] -->|Да| B[Фильтрация на клиенте]
  A -->|Нет| C[Нужна серверная фильтрация]
  C --> D{Требуется ранжирование и полнотекст}
  D -->|Да| E[Использовать поисковый движок 'Algolia/Elastic']
  D -->|Нет| F[Серверная фильтрация + пагинация]

Безопасность и конфиденциальность

  • Не отправляйте в аналитике или логах чувствительные запросы пользователей.
  • При хранении логов запросов обезличивайте данные.

Краткое резюме

Поисковая строка в React — это управляемый input, фильтрация массива методом filter и отображение через map. Для масштабных задач используйте debounce, серверную фильтрацию или специализированные поисковые сервисы. Тестируйте крайние случаи и обеспечьте доступность интерфейса.

Важно: выбирайте стратегию, исходя из объёма данных и требований к релевантности.

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Как узнать IP-адрес в Windows 10
Сеть

Как узнать IP-адрес в Windows 10

Видеозадний фон в Microsoft Edge — включение и отключение
Руководства

Видеозадний фон в Microsoft Edge — включение и отключение

Исправление ошибки 0x800070002c-0x3000d в Windows 10
Windows

Исправление ошибки 0x800070002c-0x3000d в Windows 10

Cider — клиент Apple Music для Linux
Linux

Cider — клиент Apple Music для Linux

Как использовать FC в командной строке Windows
Командная строка

Как использовать FC в командной строке Windows

Как защитить Wi‑Fi от соседей
Сеть

Как защитить Wi‑Fi от соседей