Почему не удаляются параметры из адресной строки при использовании navigate в react по клику

У меня есть на сайте сортировка по цене, при клике на кнопку 'дешевле'

onClick={() => {
    if (location.search.includes('asc')) {
        fetchByParams('_sort', '');
        fetchByParams('_order', '');
    } else {
        fetchByParams('_sort', 'asc');
    }
}}

идут товары по возрастающей цене, через это

const fetchByParams = async (query, value) => {
  const search = new URLSearchParams(location.search);
  if (value === 'All') {
    search.delete(query);
  } else if (value == false) {
    search.delete(query, value);
  } else if (query == '_sort') {
    search.set(query, 'price');
    search.set('_order', value);
  } else {
    search.set(query, value);
  }
  const url = `${location.pathname}?${search.toString()}`;
  navigate(url);
};

в адресной ссылке появляется '?_sort=price&_order=asc' и нужно чтобы при повторном нажатии на кнопку с адресной ссылки это убиралось, но при повторном нажатии остается '_sort=price' а '_order=asc' удаляется


Ответы (1 шт):

Автор решения: SwaD

Вы из одного блока вызываете fetchByParams 2 раза. В каждый вызов передаете разные данные.
Однако вы не учитываете асинхронность.

Если вы позовете ребенка дважды, он к вам 2 раза не придет!

Вы вызываете в одной группе {}

fetchByParams('_sort', '');
fetchByParams('_order', '');

Однако в функции вы смотрите на текущий location.search, который не успевает измениться.

Что происходит:

Ваш location.search равен _sort=price&_order=asc
Первый вызов функции удаляет _sort и передает в navigate остаток, т.е. _order=asc
Вызывается второй раз функция, однако ваш location.search по прежнему имеет значение _sort=price&_order=asc
Функция отрабатывает и передает в navigate _sort=price

Результат: вы видите в адресной строке ?_sort=price

Один из вариантов - закостыльте вашу функцию fetchByParams где будете сразу убирать 2 параметра из адресной строки, как то вот так к примеру:

if (value == 'clear') {
  search.delete('_order');
  search.delete('_sort');
}

или, если надо полностью очистить от всего, попробовать вот так

if (value == 'clear') {
  search.forEach((val, key) => {
    search.delete(key)
  })
}

Решение остается за вами, как более правильно поправить данное поведение для вашего проекта

→ Ссылка