Рядок запиту

Через адресний рядок можна передавати динамічні значення змінних. Це дуже активно вживана технологія в інтернеті.

Наприклад, уявімо інтернет-магазин. І на сторінці продуктів нам виводиться весь перелік товарів. За допомогою рядку запиту можна налаштувати сортування і вибірку результатів за певним параметром, наприклад кольором, ціновим обмеженням, компанією виробником, наявністю в магазині тощо. На такому ж принципі базуються і сайти-пошуковики.

Щоб додати до адреси рядок запиту потрібно поставити знак питання ? і після нього один або більше параметрів у форматі "ключ=значення". Якщо параметрів більше одного, то їх розділяють знаком амперсанд &.

До прикладу візьмемо сайт з продажу телефонів і розглянемо яким може бути рядок запиту:

https://mysite.com/phones?firm=apple&color=black&maxPrice=700&inStock=true

Тут ми звертаємося до компонента, який буде показано за роутом /phones і в нього передаємо чотири параметри - фірму виробника, колір, максимальну ціну і наявність в продажу. В самому компоненті <Phones> можна прописати фільтр, який буде робити вибірку, які задовольняють умові. Таке посилання буде показувати однаковий контент у різних користувачів на різних пристроях.

Отримання параметрів із рядка запиту

Для читання та зміни рядка запиту у бібліотеці React Router є хук useSearchParams, який є обгорткою над вбудованим у браузер класом URLSearchParams.

const [searchParams, setSearchParams] = useSearchParams();

Цей хук повертає масив із двох значень: об'єкт параметрів рядка запиту для поточного URL (searchParams) та функцію оновлення рядка запиту(setSearchParams).

Щоб отримати значення параметра який ми чекаємо, потрібно використати метод get() і передати ключ параметра. Якщо такий параметр прийшов, то повернеться його значення, якщо ні, то повернеться null.

const color = searchParams.get("color");

Подивимося на прикладі, як отримати ці значення:

https://mysite.com/phones?firm=apple&color=black&maxPrice=700&inStock=true
src/pages/Phones.jsx
import { useSearchParams } from "react-router-dom";

const Phones = () => {
  const [searchParams] = useSearchParams();
  const firm = searchParams.get("firm"); 
  const color = searchParams.get("color"); 
  const maxPrice = searchParams.get("maxPrice"); 
  const inStock = searchParams.get("inStock"); 

  console.log(firm, typeof firm); // "apple", string
  console.log(color, typeof color); // "black", string
  console.log(maxPrice, typeof maxPrice); // "700", string
  console.log(inStock, typeof inStock); // "true", string

  return (
    <div>
      <p>Firm: {firm}</p>
      <p>Color: {color}</p>
      <p>Maximum price: {maxPrice}</p>
      <p>In stock: {inStock}</p>
    </div>
  );
};

Для подальшої обробки даних і приведення типів використовуйте вбудовані класи Number(value) та Boolean(value).

Параметри як об'єкт

Метод get() може бути незручно використовувати, якщо параметрів дуже багато. Відтак, можна отримати обʼєкт з властивостями.

const [searchParams] = useSearchParams();
const params = useMemo(
  () => Object.fromEntries([...searchParams]),
  [searchParams]
);
const { firm, maxPrice, color, inStock } = params;

Мемоізація операції перетворення об'єкта параметрів, щоб отримувати посилання на новий об'єкт лише якщо зміняться параметри рядка запиту, а не при кожному рендері компоненту.

Зміна рядка запиту

Щоб передати нове значення параметра потрібно використати другий елемент масиву setSearchParams, який отримуємо викликавши useSearchParams. Цій функції потрібно передати об'єкт нових параметрів, який повністю замінить поточний рядок запиту.

src/pages/Phones.jsx
import { useSearchParams } from "react-router-dom";

export const Phones = () => {
  const [searchParams, setSearchParams] = useSearchParams();
  const firm = searchParams.get("firm");

  return (
    <div>
      <h1>Phones</h1>
      <input
        type="text"
        value={firm}
        onChange={e => setSearchParams({ name: e.target.value })}
      />
    </div>
  );
};

Відстеження змін

Якщо змінюється рядок запиту, хук useSearchParams повертає нове значення параметрів і компонент оновлюється. На цю зміну можна за потреби прописати хук useEffect.

Приклад

Розглянемо на прикладі рядок запиту з одним параметром. За основу візьмемо раніше створену схему маршрутизації.

Напишемо в компоненті <Works>, який рендериться за роутом /works інпут-фільтр, який змінюватиме рядок запиту та у списку робіт лишатиме тільки ті, в заголовках яких є збіг пошукового запиту.

Роут буде такого формату: /works?name=query

Посилання на код тут.

Last updated