Обновление query-параметров

React Router предоставляет гибкий и удобный механизм для работы с URL, включая query-параметры, которые часто используются для передачи состояния или фильтров между страницами. Для управления query-параметрами в React Router используют сочетание встроенных хуков и объектов, таких как useSearchParams, useLocation и useNavigate.


Хук useSearchParams

useSearchParams позволяет получить текущие query-параметры и функции для их обновления. Этот хук возвращает массив из двух элементов: объект параметров и функцию для их изменения.

Пример использования:

import { useSearchParams } from 'react-router-dom';

function Products() {
  const [searchParams, setSearchParams] = useSearchParams();
  
  const category = searchParams.get('category') || 'all';
  
  const handleCategoryChange = (newCategory) => {
    setSearchParams({ category: newCategory });
  };
  
  return (
    <div>
      <button onCl ick={() => handleCategoryChange('electronics')}>Электроника</button>
      <button onCl ick={() => handleCategoryChange('books')}>Книги</button>
      <p>Выбранная категория: {category}</p>
    </div>
  );
}

Особенности:

  • searchParams.get('ключ') возвращает строку или null, если параметр отсутствует.
  • setSearchParams заменяет все текущие query-параметры на новые. Чтобы сохранить существующие параметры, их нужно явно передавать:
setSearchParams(prev => ({ ...Object.fromEntries(prev), category: newCategory }));

Использование useLocation и useNavigate

Для более точного контроля над URL, включая query-параметры, можно использовать хук useLocation для чтения текущего состояния URL и useNavigate для изменения.

Пример:

import { useLocation, useNavigate } from 'react-router-dom';

function Filter() {
  const location = useLocation();
  const navigate = useNavigate();
  
  const params = new URLSearchParams(location.search);
  const sort = params.get('sort') || 'asc';
  
  const toggleSort = () => {
    params.set('sort', sort === 'asc' ? 'desc' : 'asc');
    navigate(`${location.pathname}?${params.toString()}`, { replace: true });
  };
  
  return (
    <div>
      <button onCl ick={toggleSort}>Сортировка: {sort}</button>
    </div>
  );
}

Особенности:

  • useLocation предоставляет объект с pathname, search и другими свойствами текущего URL.
  • useNavigate позволяет программно изменять URL, добавляя query-параметры или меняя путь.
  • Использование опции { replace: true } предотвращает создание новой записи в истории браузера.

Множественные query-параметры

Для работы с несколькими параметрами удобно использовать URLSearchParams. Он позволяет добавлять, изменять и удалять параметры динамически.

Пример:

const params = new URLSearchParams(location.search);
params.set('page', 2);
params.set('filter', 'active');
params.delete('sort');

navigate(`${location.pathname}?${params.toString()}`);
  • params.set('ключ', 'значение') — добавляет или обновляет параметр.
  • params.delete('ключ') — удаляет параметр.
  • params.toString() формирует строку query-параметров для URL.

Синхронизация состояния компонента с query-параметрами

Часто требуется, чтобы состояние React-компонента отражало значения query-параметров и обновлялось при их изменении.

import { useState, useEffect } from 'react';
import { useSearchParams } from 'react-router-dom';

function Pagination() {
  const [searchParams, setSearchParams] = useSearchParams();
  const [page, setPage] = useState(Number(searchParams.get('page')) || 1);

  useEffect(() => {
    setSearchParams({ page });
  }, [page, setSearchParams]);

  return (
    <div>
      <button disabled={page <= 1} onCl ick={() => setPage(page - 1)}>Назад</button>
      <span>Страница {page}</span>
      <button onCl ick={() => setPage(page + 1)}>Вперед</button>
    </div>
  );
}

Особенности:

  • Хук useEffect позволяет синхронизировать состояние компонента с URL при каждом изменении.
  • Использование Number(searchParams.get('page')) гарантирует числовое представление параметра.

Советы по обновлению query-параметров

  1. Сохранять существующие параметры: При обновлении одного параметра другие не должны теряться.

  2. Использовать URLSearchParams для сложных операций: добавление, удаление, сортировка.

  3. Выбирать между replace и push:

    • replace: true — обновление без добавления новой записи в историю.
    • по умолчанию создается новая запись, что полезно для навигации вперед/назад.
  4. Синхронизация с состоянием React: Обеспечивает реактивность интерфейса при изменении параметров URL.


Если необходимо управлять query-параметрами в приложениях с большим количеством фильтров и пагинацией, рекомендуется создавать обертку над useSearchParams с функциями для чтения, записи и удаления параметров. Это упрощает повторное использование и поддержание кода.