Хук useSearchParams позволяет нам передавать параметр defaultInit
:
declare function useSearchParams(
defaultInit?: URLSearchParamsInit
): [URLSearchParams, SetURLSearchParams];
type URLSearchParamsInit =
| string
| ParamKeyValuePair[]
| Record<string, string | string[]>
| URLSearchParams;
Может ли кто-нибудь помочь мне понять, как следует использовать этот параметр? Когда я использую этот параметр, мои значения не добавляются к URL-адресу в браузере. Мне все еще нужно вызвать установщик после вызова перехватчика, чтобы обновить параметры поиска.
Например:
const myDefaults = {
one: 'A',
two: 'B'
};
// Passing in myDefaults here does not affect the URL in the browser
const [searchParams, setSearchParams] = useSearchParams(myDefaults);
// I have to additionally call useSearchParams to update the URL in the browser
useEffect(() => {
setSearchParams(myDefaults);
}, []);
Ожидается ли это? Если да, то какова цель параметра defaultInit
?
defaultInit
используется таким образом, что вы можете читать определенные параметры поиска по умолчанию, если они не существуют в URL-адресе; он не будет обновлять URL-адрес, если он не существует.
Например, если значение по умолчанию для category
— 1
, но пользователь открыл страницу без этого параметра запроса: https://example.com
.
В этом случае вы можете установить значение по умолчанию для этих параметров запроса, чтобы у вас было значение для чтения:
const [searchParams] = useSearchParams({ category: '1' });
const { category } = searchParams;
Это более или менее похоже на следующее:
const [searchParams] = useSearchParams();
const { category = '1' } = searchParams;
Однако учтите, что после того, как вы назовете setSearchParams
, defaultInit
перестанет действовать.
Изменить. Если вы хотите автоматически обновлять параметры поиска, если они не существуют, вы можете написать такую служебную функцию (не проверено):
import { useEffect, useRef } from 'react';
import { createSearchParams, useSearchParams } from 'react-router-dom';
function useSearchParamsWithUpdate(defaultInit) {
const [searchParams, setSearchParams] = useSearchParams(defaultInit);
const defaultSearchParams = useRef(createSearchParams(defaultInit));
useEffect(() => {
const update = {};
let needUpdate = false;
defaultSearchParams.current.forEach((v, k) => {
if (!searchParams.has(k)) {
update[k] = v;
needUpdate = true;
}
});
if (needUpdate) setSearchParams(update, { replace: true });
}, [searchParams, setSearchParams]);
return [searchParams, setSearchParams];
}
@devklick Да, я изменил свой ответ выше, включив в него пример кода, который должен делать то, что вы хотите.
Спасибо. Итак, ожидается, что
defaultInit
не обновит URL-адрес браузера? Думаю, я ожидал, что реагирующий маршрутизатор обработает применение значений по умолчанию и объединит их со всем, что уже есть в URL-адресе, но, возможно, это должен сделать разработчик, а затем вызвать установщик.