Я хочу задавать query параметры из компонента в строке URL, так как логика получается большой мне хочется вынести её в отдельный хук.
Я сделал это:
import { isBrowser } from '../lib/is-browser';
export const useQueryParams = (desiredParams: string[]) => {
const params = isBrowser() ? window.location.search : null;
const queryParams = params ? parseQueryParams(params, desiredParams) : null;
const changeQueryParams = (queryParams: Record<string, string>): void => {
const params = new URLSearchParams(Object.entries(queryParams).filter(([, value]) => !!value));
updateURL(params.toString());
};
return [queryParams, changeQueryParams] as const;
};
const updateURL = (param: string): void => {
if (history.pushState) {
const baseUrl =
window.location.protocol + '//' + window.location.host + window.location.pathname;
const newUrl = baseUrl + (param ? `?${param}` : '');
history.pushState(null, '', newUrl);
} else {
console.warn('History API не поддерживается');
}
};
export const parseQueryParams = (params: string, desiredParams: string[],): Record<string, string> => {
const searchParams = new URLSearchParams(params);
return desiredParams.reduce((acc: Record<string, string>, key) => {
if (searchParams.has(key)) acc[key] = searchParams.get(key) as string;
return acc;
}, {});
};
Хуку useQueryParams при вызове передаётся массив строк, это ключи параметры которые нужны для компонента.
useQueryParams возвращает объект ключ - значение, и функцию которая будет изменять параметры.
Проблемы:
1. Как можно убрать все сайд эффекты в useEffect?
2. Как использовать хук не в одном компоненте? т.е. что-бы два компонента используя useQueryParams, не перезаписывали параметры друг друга.
3. Как вообще правильно задавать параметры в URL?